跳转至

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 adapter
  • interfaces: HTTP、WebSocket、jobs 等协议适配层

依赖方向必须保持为:

interfaces -> application -> domain
infrastructure -> application -> domain

禁止反向依赖:

  • domain 不得依赖 FastAPI、SQLAlchemy、LangGraph、Qdrant、MinIO
  • application 不得直接依赖 ORM model、HTTP request/response、外部 SDK client
  • interfaces 不得承载业务编排

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

负责:

  • AgentAgentVersion、发布状态、治理配置、挂载关系
  • 对运行时暴露 AgentDefinitionRepository 等读取端口
  • 保证“运行时拿到的是可执行、可审计的已发布定义”

不负责:

  • HTTP DTO
  • LangGraph / MCP / RAG 直接调用
  • 一次运行的状态机

4.2 runtime

负责:

  • 一次运行的输入输出边界
  • RunPublishedAgentUseCase
  • RuntimeKernel
  • 运行状态、错误语义、结果对象
  • 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_id
  • published_version_id 或可解析为发布版本的等价标识
  • user_input
  • 可选 runtime_overrides
  • 执行:
  • 读取已发布 Agent/Fusion 定义
  • 装配治理配置、能力挂载和输入契约
  • 执行一次同步运行
  • 持久化运行状态、输入摘要、输出结果和错误信息
  • 输出:
  • run_id
  • status
  • final_output
  • usage_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.py
  • ai_service/utils/database.py

7.3 兼容改动的约束

如果为了接入新主干而修改旧入口,修改只能用于:

  • 转发到新 use case
  • 协议兼容
  • DTO 映射

不得继续把新的业务编排写回旧 router、旧 orchestrator 或旧 services。

8. 交付阶段

Phase 0: Architecture Alignment

  • 补齐 PRD
  • 新增本页文档
  • 更新 architecture/indexmkdocs 导航

Phase 1: Backbone Skeleton

  • 创建新主干目录
  • 落最小 contracts、error types、ports
  • 建立 RunPublishedAgentUseCase 空壳
  • 建立单元测试夹具

Phase 2: Vertical Slice Migration

  • 接上 AgentDefinitionRepository SQLAlchemy adapter
  • 接上 KnowledgePortToolPortModelPort
  • 接上 RunRepository
  • 跑通单次 HTTP 运行入口

Phase 3: Compatibility And Evidence

  • 在必要处让旧入口转发到新实现
  • 增加 tests/unit/v2tests/integration/v2
  • 补齐开发文档和迁移说明

9. 验收证据

第一阶段不是“目录更整齐”就算完成,而是要有可验证证据。

9.1 测试证据

  • RunPublishedAgentUseCase 可以在 stub port 下独立单测
  • 至少覆盖成功、定义缺失、能力调用失败三类路径
  • HTTP 集成测试可以触发一次完整运行并写入结果

9.2 文档证据

  • 本文档明确模块边界、迁移阶段和冻结规则
  • 文档导航中可以稳定找到本页

9.3 结构证据

  • 新增核心代码主要落在新主干目录
  • 旧目录没有继续增加横向业务编排

10. 与当前态文档的关系

如果后续新主干逐步落地并稳定,本文中的部分章节可以下沉到 systems/core/,把“目标态”升级成“稳定实现说明”。