Fix SSE route dependency and align architecture docs

This commit is contained in:
ash66
2026-05-18 16:32:42 +08:00
parent 86b9ac806a
commit 3f69cad404
149 changed files with 4786 additions and 5957 deletions

View File

@@ -24,7 +24,13 @@
### 2.1 `DocumentProcessor` 责任过载
`backend/app/services/document_processor.py` 当前同时承担
现状判断
- `backend/app/services/document_processor.py` 已经不再是当前主要编排点
- 上传、查询和问答的核心组织逻辑已经明显下沉到 `backend/app/application/*` 以及 `backend/app/shared/bootstrap.py`
- `DocumentProcessor` 当前更接近一个兼容旧调用路径的 legacy façade
其历史上曾集中承载过以下职责:
- 文档解析
- 摘要生成
@@ -33,22 +39,34 @@
- Milvus 入库
- 检索入口
这使上传处理链路、检索链路与基础设施初始化逻辑耦合在一个大类中。流程编排与具体实现没有边界,后续无论替换 parser、embedding、vector store 还是增加文档状态管理,都会直接影响同一个类
当前真正还需要收口的问题不是“继续拆这个大类”,而是把文档元数据、解析、分块、向量化和索引写入的稳定边界进一步收束到 application service 与端口接口中,避免后续重构继续围绕旧实现形态做判断
### 2.2 检索逻辑缺少稳定边界
`backend/app/services/rag/retriever.py` 当前同时管理
现状判断
- `backend/app/services/rag/retriever.py` 已经明显退化为兼容层
- 真正承担检索编排的是 `KnowledgeRetrievalService``shared/bootstrap` 中的 wiring
- `Retriever` 应被视为业务侧端口,而不是当前主编排单元
其历史上曾集中承载过以下职责:
- embedder 初始化
- Milvus 连接与 collection lifecycle
- 检索执行
- 结果映射
这意味着“检索能力”不是一个稳定的业务能力接口,而是一个直接依赖具体 embedding 和 Milvus 实现的复合服务。后续如果从 `BGE-M3 + hybrid search` 切到 `1536 dense-only` 或替换向量索引实现,会直接影响检索服务本身
所以这里的重点不是把旧 retriever 当成未来架构核心,而是确认检索能力的稳定边界已经迁移到 application 层,并继续清理仍然残留的 provider-specific 细节
### 2.3 `QAAgent` 责任过载
`backend/app/services/agent/qa_agent.py` 当前同时承担
现状判断
- `backend/app/services/agent/qa_agent.py` 已经不是当前主要问答编排点
- 当前实际的问答编排已经主要落到 `AgentConversationService`
- `QAAgent` 当前更接近向后兼容的 legacy façade
其历史上曾集中承载过以下职责:
- 检索调用
- 上下文构建
@@ -57,7 +75,7 @@
- SSE 流式问答流程
- 会话 workflow 编排
这导致 Agent workflow 与检索底座、LLM provider、上下文构造逻辑紧耦合。后续切换 LLM provider、替换 session store、复用 retrieval 能力时,影响面会扩散到整个 Agent 实现
剩余风险不在于“它还很大”,而在于仍有少量 API 入口和 session 读写没有完全收口到 application service导致目标边界和现状之间还存在断点
### 2.4 API 层直接编排具体服务
@@ -73,6 +91,10 @@
- 路由层知道过多内部实现细节
- 后续如果内部模块调整,路由层也要跟着改
现状里这条判断需要修正:大部分主流程已经通过 `backend/app/shared/bootstrap.py` 统一装配,并由 application service 承担编排;真正还没有完全收口的是 `backend/app/api/routes/agent.py` 中的 session/history/feedback 这类接口,它们仍直接访问 `ConversationStore`
因此,当前问题不是“路由层仍然是主编排中心”,而是“少数会话管理接口还没有通过 application service 统一封装”,这会持续打破 API 只做 transport concerns 的边界。
### 2.5 文档元数据与对象存储组织方式耦合
当前文档列表与下载逻辑高度依赖 MinIO 对象命名方式和对象遍历结果。对象存储目前承担了部分“业务真相”的角色,但对象存储只适合作为文件二进制载体,不适合作为完整文档元数据和状态管理的唯一来源。
@@ -84,7 +106,9 @@
- `knowledge` 通过 `DocumentProcessor.search()` 访问检索
- `agent` 通过 `Retriever` 访问检索
会导致同一检索能力未来演进成两条链路,难以统一检索策略、元数据模型和可替换边界
条问题描述需要更新。现在检索主链路已经被 `KnowledgeRetrievalService` 统一收束,`knowledge``agent` 的共享底座比过去清晰得多
当前仍未完全收口的是 Agent 的 session 相关能力:公开 API 里还存在 `/agent/session/{id}``/agent/session/{id}/history``/agent/sessions``/agent/feedback` 等接口直接读写 `ConversationStore`,这意味着“问答编排统一了,但会话管理还没有统一入口”。
## 3. Architecture Goals
@@ -132,7 +156,8 @@
系统必须形成稳定的单向依赖关系:
- `api -> application -> domain`
- `application -> infrastructure` 通过端口/实现绑定
- `application -> domain ports`
- `composition root -> application + infrastructure bindings`
- `infrastructure -> external systems`
不允许出现基础设施实现反向驱动业务编排,也不允许 domain 依赖 Web 或第三方 SDK。
@@ -238,12 +263,20 @@ backend/app/
- 通用异常
- 通用工具
- 公共基础设施无关组件
- composition root 与依赖装配
- 运行时共享的 wiring 辅助入口
非职责:
- 不承载业务编排
- 不变成新的 `services` 大杂烩目录
说明:
- `shared` 不是业务层,但它是本项目当前明确的装配层。
- `backend/app/shared/bootstrap.py` 是现阶段的 composition root负责把端口实现、基础设施适配器和 application service 连接起来。
- 后续如果新增 wiring 入口,应继续保持在同一类装配边界内,不要把依赖装配拆回各个路由或 service 构造函数中。
## 5. Module Responsibilities
### 5.1 `api`
@@ -269,6 +302,11 @@ backend/app/
- `KnowledgeRetrievalService`
- `AgentConversationService`
说明:
- 这 4 类是当前已经明确成型的核心用例服务,但不是 application 的全部上限。
- 现有 Agent session 管理接口所需的会话查询、历史读取、删除和反馈归档能力,后续应补入 application 层的明确用例服务或子服务,而不是继续让 API 直连 `ConversationStore`
### 5.3 `domain`
`domain` 层定义系统内部真正稳定的概念,例如:
@@ -467,6 +505,21 @@ backend/app/
- 当前 `QAAgent` 的 workflow 编排职责在目标态应迁移到这里,或被其吸收后只保留 façade 角色。
- SSE 与普通问答必须共用这一层,不允许复制业务编排逻辑。
### 7.5 `AgentSessionService`
职责:
- 读取会话详情
- 读取会话历史
- 列出会话
- 删除会话
- 记录会话反馈
说明:
- 这类能力目前仍散落在 `backend/app/api/routes/agent.py`,并直接依赖 `ConversationStore`
- 目标态应把它们收口到 application 层,保证 API 只处理 transport concerns而不是继续承担 session 级业务访问。
## 8. Core Workflows
### 8.1 文档上传入库链路
@@ -519,27 +572,63 @@ backend/app/
- 业务编排链必须完全复用
- 检索能力必须来自同一 `KnowledgeRetrievalService`
### 8.4 Agent Session 管理链路
目标流程如下:
1. `api/agent/session/*``api/agent/sessions` 接收会话管理请求
2. `AgentSessionService` 读取、列出、删除或归档反馈
3. `ConversationStore` 负责持久化与会话生命周期细节
4. API 输出 session 详情、历史、列表或反馈结果
约束:
- 会话详情、历史、列表和反馈接口不属于问答编排本身,应由独立的 session application service 处理。
- 这部分能力不应继续直接暴露 `ConversationStore` 给路由层。
## 9. Dependency Rules
系统内部依赖方向固定如下:
```text
api -> application -> domain
application -> infrastructure (through ports)
application -> domain ports
composition root -> application + infrastructure bindings
infrastructure -> external systems
```
具体规则如下:
- `api` 可以依赖 `application` 和 API 自己的 request/response models
- `application` 可以依赖 `domain` 和端口绑定后的 infrastructure 实现
- `application` 只能依赖 `domain`、端口接口,以及通过 composition root 注入进来的实现实例
- `domain` 不能依赖 `api``infrastructure`
- `infrastructure` 可以依赖 `domain` 定义的端口和数据模型,但不能反向驱动 application 逻辑
说明:
- 端口绑定发生在 `shared/bootstrap.py` 这类 composition root而不是 application 层内部。
- application 只能接收已装配好的依赖实例,不能反向“依赖某个 infrastructure 实现类”作为其设计前提。
## 10. Migration Mapping From Current Code
当前关键代码到目标模块的映射如下。
### 10.0 旧 facade 存续策略
当前仓库里仍保留若干旧 facade / 兼容入口,包括但不限于:
- `backend/app/services/document_processor.py`
- `backend/app/services/rag/retriever.py`
- `backend/app/services/agent/qa_agent.py`
这些类的定位是“兼容现有调用方的过渡入口”,不是目标态的主要编排层。它们在迁移完成前应继续保留,直到对应的调用方、测试和 API 入口都迁移到 application service 或新的适配层为止。
约束:
- 不允许因为目标架构已经定义,就在没有替换调用方的情况下直接删除这些 facade。
- 任何清理旧 `services` 的动作,都必须先确认是否还存在非 HTTP 的内部调用、测试依赖或临时适配依赖。
- 这些 facade 可以逐步瘦身,但在迁移窗口内应优先保持行为兼容,而不是追求“文件级清零”。
### 10.1 文档处理
当前:
@@ -551,6 +640,7 @@ infrastructure -> external systems
- 其流程编排职责迁移到 `application/documents/DocumentCommandService`
- 解析、分块、向量、入库分别通过端口接入
- 检索入口从该类中剥离,不再由 ingest orchestration 承担 search 职责
- 迁移期间该类作为兼容 facade 保留,直到所有直接调用点收口完成
### 10.2 检索
@@ -563,6 +653,7 @@ infrastructure -> external systems
- `domain/retrieval` 中定义 `Retriever` 端口和统一检索结果模型
- `infrastructure/vectorstore` 中承载具体检索实现
- `application/knowledge/KnowledgeRetrievalService` 作为统一检索用例入口
- 迁移期间该类作为兼容 facade 保留,避免影响现有检索调用方
### 10.3 Agent Workflow
@@ -576,6 +667,7 @@ infrastructure -> external systems
- 具体 LLM 调用走 `AnswerGenerator`
- 具体 session 读写走 `ConversationStore`
- 检索统一走 `KnowledgeRetrievalService`
- 迁移期间该类作为兼容 facade 保留,避免影响现有问答和测试调用点
### 10.4 存储