AI Service v2 目标架构设计
本文档描述 ai_service 的目标架构主干,不重复介绍当前实现细节,而是回答下面四个问题:
- 后端后续为什么要建立新主干
- 新主干的模块边界和依赖方向是什么
- 第一阶段到底迁移哪条链路
- 旧代码在迁移期间如何共存
如果你想看当前已经落地的全景结构,请先读 AI Service 全景架构设计;本文聚焦“目标态”和“迁移约束”。
1. 背景与目标
当前仓库已经从单一后端演化为平台型 monorepo,ai_service 同时承载:
- FastAPI API 装配与控制面入口
- 对话与运行时编排
- Fusion 执行
- RAG、MCP、Skills 等能力接入
- 数据持久化与运行审计
现状问题不在于模块数量多,而在于后端依赖方向已经不稳定。一次能力变更往往会横穿:
api -> orchestrator -> services -> storage -> fusion
这会带来三个持续性问题:
- 改动半径大,定位一个需求要在多个全局目录来回跳转
- 业务规则与框架细节混杂,导致核心逻辑难以独立测试
- 旧结构会不断吸收新逻辑,目录即使增加也难形成真正边界
因此,AI Service v2 的目标不是拆微服务,也不是一次性重写整个平台,而是在当前仓库内建立一条新的后端架构主干。
2. 设计原则
2.1 总体原则
- 保持 monorepo,不在本阶段拆成多个进程或多个服务
- 只在
ai_service范围内建立新主干 - 先迁移一条高价值纵向链路,不复刻全部历史功能
- 旧实现允许继续存在,但默认进入冻结维护状态
2.2 依赖方向原则
新主干统一采用模块内 clean architecture 分层:
domain: 领域对象、领域规则、稳定值对象application: use case、port、编排接口infrastructure: SQLAlchemy、LangGraph、对象存储、向量库、外部 SDK adapterinterfaces: HTTP、WebSocket、jobs 等协议适配层
依赖方向必须保持为:
interfaces -> application -> domain
infrastructure -> application -> domain
禁止反向依赖:
domain不得依赖 FastAPI、SQLAlchemy、LangGraph、Qdrant、MinIOapplication不得直接依赖 ORM model、HTTP request/response、外部 SDK clientinterfaces不得承载业务编排
2.3 迁移原则
- 新增后端业务逻辑默认进入新主干
- 旧目录只允许修 bug 或做兼容转发
- 文档要先于或至少同步于代码调整,避免目录先变、边界后补
3. 目标主干结构
ai_service/
backbone/
entrypoints/
http/
websocket/
jobs/
modules/
agent_control/
domain/
application/
infrastructure/
interfaces/
runtime/
domain/
application/
infrastructure/
interfaces/
knowledge/
domain/
application/
infrastructure/
interfaces/
integration/
domain/
application/
infrastructure/
interfaces/
shared/
contracts/
observability/
kernel/
backbone/ 是说明性命名。后续如果目录名调整,边界规则不能变。
3.1 backbone/ 的层级定位
backbone/ 是 ai_service/ 下的新主干目录,不是整个 ai_service/ 的别名。
因此,和 backbone/ 同层级的应该是以下两类目录:
- 迁移期继续保留的旧系统目录
- 仓库级基础设施目录
当前建议保留为 backbone/ 同层的目录包括:
ai_service/
backbone/
api/
orchestrator/
fusion/
services/
storage/
utils/
migrations/
agents/
这些目录的含义分别是:
backbone/: 新的后端架构主干api/: 旧 HTTP 入口和协议装配层,迁移期内逐步转发到新主干orchestrator/: 旧对话运行时与编排实现资产fusion/: 现有 Fusion 相关运行时与服务实现services/: 旧能力层实现,后续主要作为 adapter 复用来源storage/: 数据模型、仓储实现和持久化基础设施utils/: 配置、数据库连接、日志等仓库级基础能力migrations/: 数据库迁移资产agents/: 现有 agent 实现与运行时相关代码
3.2 不应该与 backbone/ 同层的目录
以下目录不建议直接与 backbone/ 并列出现在 ai_service/ 顶层:
domain/application/infrastructure/interfaces/core/kernel/platform/v2/
原因不是这些名字本身错误,而是它们会和 backbone/ 的“新主干”语义重叠,导致仓库同时出现“全局四层”和“模块化主干”两套组织方式,后续会再次退化为横向平铺。
3.3 backbone/ 下面应该放什么
backbone/ 内部只允许放三类受控内容:
entrypoints/: 新主干的 HTTP / WebSocket / jobs 入口modules/: 按业务边界组织的新模块shared/: 受严格限制的跨模块基础契约
也就是说,业务模块应该下沉到:
ai_service/backbone/modules/
而不是直接和 backbone/ 并排放在 ai_service/ 顶层。
4. 模块边界
4.1 agent_control
负责:
Agent、AgentVersion、发布状态、治理配置、挂载关系- 对运行时暴露
AgentDefinitionRepository等读取端口 - 保证“运行时拿到的是可执行、可审计的已发布定义”
不负责:
- HTTP DTO
- LangGraph / MCP / RAG 直接调用
- 一次运行的状态机
4.2 runtime
负责:
- 一次运行的输入输出边界
RunPublishedAgentUseCaseRuntimeKernel- 运行状态、错误语义、结果对象
RunRepository等写入端口
不负责:
- Agent 定义持久化细节
- 外部能力的底层实现
- API 层的协议细节
4.3 knowledge
负责:
- 检索、文档上下文构建等知识能力端口
- 对旧
services/rag/*的复用适配 - 向
runtime暴露稳定KnowledgePort
不负责:
- Agent 发布规则
- API 层展示逻辑
4.4 integration
负责:
- 模型调用
- MCP 接入
- Skills 接入
- 对旧
services/mcp/*、services/skills/*、模型加载逻辑做 adapter 包裹
不负责:
- 业务用例决策
- Agent 领域规则
4.5 shared
允许承载:
- 稳定跨模块契约
- 错误基类
- 基础观测接口
- 与具体业务无关的公共值对象
禁止承载:
- Agent/Fusion/RAG 业务规则
- 仓库级“万能 util”
- 借道
shared的跨模块业务耦合
5. 第一阶段标准用例
第一阶段固定只迁移一个纵向用例:RunPublishedAgent。
5.1 用例定义
- 入口:单次 HTTP 请求
- 输入:
agent_idpublished_version_id或可解析为发布版本的等价标识user_input- 可选
runtime_overrides - 执行:
- 读取已发布 Agent/Fusion 定义
- 装配治理配置、能力挂载和输入契约
- 执行一次同步运行
- 持久化运行状态、输入摘要、输出结果和错误信息
- 输出:
run_idstatusfinal_outputusage_summary- 可选
error_detail
5.2 第一阶段明确不做的事
- 不重做完整流式对话
- 不重做多轮会话恢复
- 不重做 Agent CRUD 与版本发布控制台
- 不重做评测闭环
- 不重做数据库 schema
5.3 为什么先迁这条链路
RunPublishedAgent 同时覆盖:
- 控制面定义读取
- 运行时编排
- 外部能力调用
- 运行结果持久化
但它又不会把范围扩展到实时会话、管理后台和全量历史功能,因此适合作为第一条验证新主干有效性的链路。
6. 运行路径
flowchart TD
Client["Client / Admin / Demo"] --> Entry["HTTP Entrypoint"]
Entry --> UseCase["RunPublishedAgentUseCase"]
UseCase --> DefinitionPort["AgentDefinitionRepository"]
UseCase --> Kernel["RuntimeKernel"]
Kernel --> KnowledgePort["KnowledgePort"]
Kernel --> ToolPort["ToolPort"]
Kernel --> ModelPort["ModelPort"]
UseCase --> RunPort["RunRepository"]
DefinitionPort --> SqlAdapter["SQLAlchemy Adapter"]
KnowledgePort --> RagAdapter["RAG Adapter"]
ToolPort --> McpSkillAdapter["MCP / Skills Adapter"]
ModelPort --> ModelAdapter["Model Adapter"]
RunPort --> PersistenceAdapter["Persistence Adapter"]
UseCase --> Presenter["Presenter"]
Presenter --> Response["API Response"]
这条图表达的重点不是组件数量,而是边界:
- HTTP 层只做协议转换
UseCase只依赖 port- 基础设施细节只出现在 adapter
- 运行结果通过受控仓储边界写回既有表结构
7. 旧结构共存策略
第一阶段必须显式冻结旧结构,否则新逻辑仍会继续长在旧目录里。
7.1 冻结目录
以下路径进入“只修 bug,不新增业务能力”的冻结状态:
ai_service/api/routers/ai_service/orchestrator/ai_service/services/ai_service/fusion/infrastructure/runtime/
7.2 允许复用的旧路径
以下路径允许继续维护,但优先作为 adapter 和配置来源使用:
ai_service/storage/model_domains/ai_service/utils/settings.pyai_service/utils/database.py
7.3 兼容改动的约束
如果为了接入新主干而修改旧入口,修改只能用于:
- 转发到新 use case
- 协议兼容
- DTO 映射
不得继续把新的业务编排写回旧 router、旧 orchestrator 或旧 services。
8. 交付阶段
Phase 0: Architecture Alignment
- 补齐 PRD
- 新增本页文档
- 更新
architecture/index与mkdocs导航
Phase 1: Backbone Skeleton
- 创建新主干目录
- 落最小 contracts、error types、ports
- 建立
RunPublishedAgentUseCase空壳 - 建立单元测试夹具
Phase 2: Vertical Slice Migration
- 接上
AgentDefinitionRepositorySQLAlchemy adapter - 接上
KnowledgePort、ToolPort、ModelPort - 接上
RunRepository - 跑通单次 HTTP 运行入口
Phase 3: Compatibility And Evidence
- 在必要处让旧入口转发到新实现
- 增加
tests/unit/v2与tests/integration/v2 - 补齐开发文档和迁移说明
9. 验收证据
第一阶段不是“目录更整齐”就算完成,而是要有可验证证据。
9.1 测试证据
RunPublishedAgentUseCase可以在 stub port 下独立单测- 至少覆盖成功、定义缺失、能力调用失败三类路径
- HTTP 集成测试可以触发一次完整运行并写入结果
9.2 文档证据
- 本文档明确模块边界、迁移阶段和冻结规则
- 文档导航中可以稳定找到本页
9.3 结构证据
- 新增核心代码主要落在新主干目录
- 旧目录没有继续增加横向业务编排
10. 与当前态文档的关系
- AI Service 全景架构设计:描述当前代码和现状拓扑
- 本文:描述目标主干、边界约束和迁移策略
- 系统架构:仓库级当前态总览
如果后续新主干逐步落地并稳定,本文中的部分章节可以下沉到 systems/ 或 core/,把“目标态”升级成“稳定实现说明”。