docs: 多agent架构plan计划
This commit is contained in:
354
docs/plans/multi-agent-refactor-plan.md
Normal file
354
docs/plans/multi-agent-refactor-plan.md
Normal file
@@ -0,0 +1,354 @@
|
|||||||
|
# 三模块多 Agent 改造方案
|
||||||
|
|
||||||
|
> 本文档描述将「AI 回复用户」「生成回忆录」「生成图片提示词」三个模块改造为多 Agent 模式的修改方案,仅作设计参考,不执行代码修改。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、概述
|
||||||
|
|
||||||
|
### 1.1 目标
|
||||||
|
|
||||||
|
将当前单体式 Agent 逻辑拆分为职责清晰、可独立演进的多 Agent 协同架构,实现:
|
||||||
|
|
||||||
|
- **职责分离**:每个 Agent 专注单一任务,便于维护和测试
|
||||||
|
- **可编排性**:通过 Orchestrator 统一调度,支持灵活编排与扩展
|
||||||
|
- **可观测性**:Agent 边界清晰,便于链路追踪和问题定位
|
||||||
|
- **渐进迁移**:在不破坏现有行为的前提下分阶段落地
|
||||||
|
|
||||||
|
### 1.2 适用范围
|
||||||
|
|
||||||
|
| 模块 | 当前实现位置 | 改造后预期 |
|
||||||
|
|------|--------------|------------|
|
||||||
|
| AI 回复用户 | `ConversationAgent` + pipeline | `ChatOrchestrator` + `ProfileAgent` + `InterviewAgent` |
|
||||||
|
| 生成回忆录 | `memoir_tasks` + `ContentAnalyzer`/`MemoirGenerator` | `MemoirOrchestrator` + 多个 Specialist Agent |
|
||||||
|
| 生成图片提示词 | `MemoirImagePromptService` | `ImagePromptOrchestrator` + `PromptGenerationAgent` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、现状分析
|
||||||
|
|
||||||
|
### 2.1 当前架构简图
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ WebSocket pipeline / Celery tasks │
|
||||||
|
├─────────────────────────────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ [process_user_message] [process_memoir_segments] │
|
||||||
|
│ │ │ │
|
||||||
|
│ ▼ ▼ │
|
||||||
|
│ ┌──────────────────┐ ┌─────────────────────────┐ │
|
||||||
|
│ │ ConversationAgent │ │ memoir_tasks (inline) │ │
|
||||||
|
│ │ - extract_profile│ │ - state extraction │ │
|
||||||
|
│ │ - generate_* │ │ - chapter classification│ │
|
||||||
|
│ │ - generate_ │ │ - narrative generation │ │
|
||||||
|
│ │ response_ │ │ - inject placeholder │ │
|
||||||
|
│ │ with_state │ └───────────┬─────────────┘ │
|
||||||
|
│ └──────────────────┘ │ │
|
||||||
|
│ ▼ │
|
||||||
|
│ ┌─────────────────────────┐ │
|
||||||
|
│ │ generate_chapter_images │ │
|
||||||
|
│ │ └─ MemoirImagePrompt │ │
|
||||||
|
│ │ Service.build_* │ │
|
||||||
|
│ └─────────────────────────┘ │
|
||||||
|
└─────────────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 主要问题
|
||||||
|
|
||||||
|
1. **职责混杂**:`ConversationAgent` 同时做资料提取、资料追问、正式访谈,逻辑耦合
|
||||||
|
2. **流程内聚**:回忆录处理全部写在 `process_memoir_segments` 单任务内,难以单测和替换子步骤
|
||||||
|
3. **Service 非 Agent**:`MemoirImagePromptService` 仅为工具类,无编排与决策能力
|
||||||
|
4. **缺乏统一抽象**:三个模块调用方式各异,无统一的 Agent 协议
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、多 Agent 架构设计
|
||||||
|
|
||||||
|
### 3.1 总体模式
|
||||||
|
|
||||||
|
采用 **Orchestrator + Specialist Agents** 模式:
|
||||||
|
|
||||||
|
- **Orchestrator**:负责路由、决策、编排,不直接调用 LLM 完成具体生成
|
||||||
|
- **Specialist Agent**:接收 Orchestrator 下发的任务,完成单一 LLM 任务并返回结构化结果
|
||||||
|
|
||||||
|
### 3.2 统一 Agent 协议(建议)
|
||||||
|
|
||||||
|
为便于 DI、测试和可观测性,建议定义统一的 Agent 协议:
|
||||||
|
|
||||||
|
```python
|
||||||
|
# 概念性协议,非实际代码
|
||||||
|
class AgentProtocol(Protocol):
|
||||||
|
"""Agent 基础协议"""
|
||||||
|
async def run(self, context: AgentContext) -> AgentResult: ...
|
||||||
|
```
|
||||||
|
|
||||||
|
- `AgentContext`:输入上下文(用户消息、状态、历史等)
|
||||||
|
- `AgentResult`:结构化输出(含 success/failure、data、trace_id)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、模块一:AI 回复用户(Chat)
|
||||||
|
|
||||||
|
### 4.1 目标架构
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────┐
|
||||||
|
│ ChatOrchestrator │
|
||||||
|
│ - 判断 profile vs interview │
|
||||||
|
│ - 路由到对应 Specialist │
|
||||||
|
│ - 聚合结果并写入 Redis │
|
||||||
|
└──────────────┬──────────────┘
|
||||||
|
│
|
||||||
|
┌────────────────────┼────────────────────┐
|
||||||
|
▼ ▼ ▼
|
||||||
|
┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐
|
||||||
|
│ ProfileAgent │ │ InterviewAgent │ │ StageDetectorAgent │
|
||||||
|
│ - 提取资料 │ │ - 状态感知回复 │ │ - 检测用户阶段 │
|
||||||
|
│ - 资料追问 │ │ - 引导与追问 │ │ - 供 Orchestrator │
|
||||||
|
│ - 开场白/问候 │ │ - 时代背景融入 │ │ 决策使用 │
|
||||||
|
└─────────────────────┘ └─────────────────────┘ └─────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 Agent 职责
|
||||||
|
|
||||||
|
| Agent | 职责 | 对应现有逻辑 |
|
||||||
|
|-------|------|--------------|
|
||||||
|
| **ChatOrchestrator** | 根据 `missing_fields`、`memoir_state` 决定调用 ProfileAgent 或 InterviewAgent;统一管理 Redis 写入、错误处理 | `process_user_message` 中的 if/else 分支 |
|
||||||
|
| **ProfileAgent** | `extract_profile_from_message`、`generate_profile_followup`、`generate_profile_greeting` | `ConversationAgent` 中 profile 相关方法 |
|
||||||
|
| **InterviewAgent** | `generate_response_with_state`、`generate_opening_message` | `ConversationAgent` 中 interview 相关方法 |
|
||||||
|
| **StageDetectorAgent**(可选) | `_detect_user_stage`,可升级为 LLM/embedding 检测 | `ConversationAgent._detect_user_stage` |
|
||||||
|
|
||||||
|
### 4.3 协作流程
|
||||||
|
|
||||||
|
1. Pipeline 调用 `ChatOrchestrator.run(conversation_id, user_message, user, segment, ...)`
|
||||||
|
2. Orchestrator 查询 `get_missing_profile_fields(user)`,若有缺失则调用 `ProfileAgent`
|
||||||
|
3. 否则获取 `MemoirState`,调用 `InterviewAgent`(可选:先调 `StageDetectorAgent` 获取 `detected_stage`)
|
||||||
|
4. 将 Agent 返回的 `responses` 写 Redis,返回给 pipeline 用于 WebSocket 下发
|
||||||
|
|
||||||
|
### 4.4 修改方案
|
||||||
|
|
||||||
|
| 步骤 | 操作 | 文件 |
|
||||||
|
|------|------|------|
|
||||||
|
| 1 | 新增 `ChatOrchestrator` 类 | `app/agents/chat/orchestrator.py` |
|
||||||
|
| 2 | 抽取 `ProfileAgent` | `app/agents/chat/profile_agent.py` |
|
||||||
|
| 3 | 抽取 `InterviewAgent` | `app/agents/chat/interview_agent.py` |
|
||||||
|
| 4 | 可选:抽取 `StageDetectorAgent` | `app/agents/chat/stage_detector.py` |
|
||||||
|
| 5 | 定义 `app/agents/chat/__init__.py` 统一导出 | - |
|
||||||
|
| 6 | 修改 `pipeline.process_user_message` 调用 `ChatOrchestrator` 而非 `ConversationAgent` | `app/features/conversation/ws/pipeline.py` |
|
||||||
|
| 7 | 保留 `ConversationAgent` 为 facade,内部委托给 Orchestrator(兼容期) | `app/agents/conversation_agent.py` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、模块二:生成回忆录(Memoir)
|
||||||
|
|
||||||
|
### 5.1 目标架构
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────┐
|
||||||
|
│ MemoirOrchestrator │
|
||||||
|
│ - 按 segment 编排流水线 │
|
||||||
|
│ - 管理章节锁、状态更新 │
|
||||||
|
│ - 派发 generate_chapter_images │
|
||||||
|
└──────────────────┬────────────────────────┘
|
||||||
|
│
|
||||||
|
┌─────────────────────────────┼─────────────────────────────┐
|
||||||
|
▼ ▼ ▼
|
||||||
|
┌──────────────────┐ ┌──────────────────────┐ ┌──────────────────┐
|
||||||
|
│ ExtractionAgent │ │ ClassificationAgent │ │ NarrativeAgent │
|
||||||
|
│ - state/slot │ │ - 8-category 分类 │ │ - 标题生成 │
|
||||||
|
│ 提取 │ │ - 无价值跳过决策 │ │ - 叙事改写 │
|
||||||
|
└──────────────────┘ └──────────────────────┘ └──────────────────┘
|
||||||
|
│ │ │
|
||||||
|
└─────────────────────────────┼─────────────────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌──────────────────────────┐
|
||||||
|
│ PlaceholderInjectAgent │
|
||||||
|
│ - inject_image_ │
|
||||||
|
│ placeholder_template │
|
||||||
|
└──────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 Agent 职责
|
||||||
|
|
||||||
|
| Agent | 职责 | 对应现有逻辑 |
|
||||||
|
|-------|------|--------------|
|
||||||
|
| **MemoirOrchestrator** | 遍历 segments、按 category 聚合、调用各 Specialist、更新 state、写 DB、派发补图任务 | `process_memoir_segments` 主循环 |
|
||||||
|
| **ExtractionAgent** | 调用 `get_state_extraction_prompt`,解析 JSON 返回 `detected_stage`、`slots` | `get_state_extraction_prompt` + 解析 |
|
||||||
|
| **ClassificationAgent** | 调用 `get_chapter_classification_prompt` 或等价逻辑,返回 category 或 None(跳过) | `_classify_chapter_category` |
|
||||||
|
| **NarrativeAgent** | `get_creative_title_prompt`、`get_narrative_prompt`,生成标题和正文 | `get_creative_title_prompt`、`get_narrative_prompt` |
|
||||||
|
| **PlaceholderInjectAgent** | 纯函数式,对 narrative 做 `inject_image_placeholder_template` | `inject_image_placeholder_template` |
|
||||||
|
|
||||||
|
### 5.3 协作流程
|
||||||
|
|
||||||
|
1. Celery 任务 `process_memoir_segments` 入口仅负责:取 segments、获取 db、调用 `MemoirOrchestrator.run(user_id, segment_ids, db)`
|
||||||
|
2. Orchestrator 对每个 segment:调 `ExtractionAgent` → 调 `ClassificationAgent`,若 None 则跳过
|
||||||
|
3. 按 category 聚合后,对每个 category:调 `NarrativeAgent` 生成 title + narrative → 调 `PlaceholderInjectAgent` → 写入 sections
|
||||||
|
4. 若有待补图章节,派发 `generate_chapter_images`
|
||||||
|
|
||||||
|
### 5.4 修改方案
|
||||||
|
|
||||||
|
| 步骤 | 操作 | 文件 |
|
||||||
|
|------|------|------|
|
||||||
|
| 1 | 新增 `MemoirOrchestrator` | `app/agents/memoir/orchestrator.py` |
|
||||||
|
| 2 | 抽取 `ExtractionAgent` | `app/agents/memoir/extraction_agent.py` |
|
||||||
|
| 3 | 抽取 `ClassificationAgent` | `app/agents/memoir/classification_agent.py` |
|
||||||
|
| 4 | 抽取 `NarrativeAgent` | `app/agents/memoir/narrative_agent.py` |
|
||||||
|
| 5 | 抽取 `PlaceholderInjectAgent`(或保留为 util) | `app/agents/memoir/placeholder_agent.py` |
|
||||||
|
| 6 | 定义 `app/agents/memoir/__init__.py` | - |
|
||||||
|
| 7 | 修改 `process_memoir_segments`:将主循环逻辑委托给 `MemoirOrchestrator` | `app/tasks/memoir_tasks.py` |
|
||||||
|
| 8 | 保留 `ContentAnalyzer`、`MemoirGenerator` 为内部实现或弃用 | `app/agents/memoir_processor.py` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、模块三:生成图片提示词(Image Prompt)
|
||||||
|
|
||||||
|
### 6.1 目标架构
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────┐
|
||||||
|
│ ImagePromptOrchestrator │
|
||||||
|
│ - 区分封面 vs 正文配图 │
|
||||||
|
│ - 调用 PromptGenerationAgent │
|
||||||
|
│ - 回退逻辑与缓存(可选) │
|
||||||
|
└────────────────┬────────────────┘
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
┌─────────────────────────────────┐
|
||||||
|
│ PromptGenerationAgent │
|
||||||
|
│ - build_prompt (正文) │
|
||||||
|
│ - build_cover_prompt (封面) │
|
||||||
|
│ - 风格映射、fallback │
|
||||||
|
└─────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.2 Agent 职责
|
||||||
|
|
||||||
|
| Agent | 职责 | 对应现有逻辑 |
|
||||||
|
|-------|------|--------------|
|
||||||
|
| **ImagePromptOrchestrator** | 根据调用方(封面/正文)选择 `build_prompt` 或 `build_cover_prompt`;统一异常处理和回退;可选:缓存相同输入的 prompt | `generate_chapter_images` 中调用 `prompt_service` 的代码 |
|
||||||
|
| **PromptGenerationAgent** | 接收 `chapter_title`、`chapter_category`、`description`、`context_excerpt`,调用 LLM 或 fallback 生成 `{prompt, style, size}` | `MemoirImagePromptService` 全部逻辑 |
|
||||||
|
|
||||||
|
### 6.3 协作流程
|
||||||
|
|
||||||
|
1. `generate_chapter_images` 任务内,对封面和每个 section:
|
||||||
|
- 构造 `(chapter_title, category, description, context_excerpt)` 等输入
|
||||||
|
- 调用 `ImagePromptOrchestrator.build_prompt` 或 `build_cover_prompt`
|
||||||
|
2. Orchestrator 内部委托 `PromptGenerationAgent`,失败时执行 fallback
|
||||||
|
|
||||||
|
### 6.4 修改方案
|
||||||
|
|
||||||
|
| 步骤 | 操作 | 文件 |
|
||||||
|
|------|------|------|
|
||||||
|
| 1 | 新增 `ImagePromptOrchestrator` | `app/agents/image_prompt/orchestrator.py` |
|
||||||
|
| 2 | 将 `MemoirImagePromptService` 重命名/重构为 `PromptGenerationAgent` | `app/agents/image_prompt/prompt_agent.py` 或保留 `app/features/memoir/memoir_images/prompting.py` 作为底层 |
|
||||||
|
| 3 | 定义 `app/agents/image_prompt/__init__.py` | - |
|
||||||
|
| 4 | 修改 `generate_chapter_images`:通过 `ImagePromptOrchestrator` 获取 prompt | `app/tasks/memoir_tasks.py` |
|
||||||
|
| 5 | 保持 `MemoirImagePromptService` 对外接口兼容(Orchestrator 内部调用) | - |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、跨模块协作(可选扩展)
|
||||||
|
|
||||||
|
### 7.1 统一编排层(远期)
|
||||||
|
|
||||||
|
若需在「对话结束 → 回忆录生成 → 图片生成」整条链路上做统一编排,可引入高层 Orchestrator:
|
||||||
|
|
||||||
|
```
|
||||||
|
┌────────────────────────────────────────────────────────────────┐
|
||||||
|
│ LifeEchoOrchestrator(可选) │
|
||||||
|
│ - 对话结束事件 → 触发回忆录编排 │
|
||||||
|
│ - 回忆录完成 → 触发图片编排 │
|
||||||
|
│ - 统一 trace_id、重试、配额校验 │
|
||||||
|
└────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
当前三个模块已在 pipeline / Celery 中串联,无需立即引入;待多 Agent 稳定后可评估是否抽象。
|
||||||
|
|
||||||
|
### 7.2 共享基础设施
|
||||||
|
|
||||||
|
- **LLM 调用**:各 Agent 通过 `get_llm_provider()` 获取,可统一包装为 `TracingLLM` 做 span 记录
|
||||||
|
- **配置**:`MemoirImageSettings` 等可注入 Agent 构造函数,便于测试 mock
|
||||||
|
- **日志**:建议在每个 Agent 入口/出口打 `logger.info`,含 `agent_name`、`trace_id`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 八、目录结构建议
|
||||||
|
|
||||||
|
```
|
||||||
|
api/app/agents/
|
||||||
|
├── __init__.py # 导出 ChatOrchestrator, MemoirOrchestrator, ImagePromptOrchestrator 等
|
||||||
|
├── base.py # AgentProtocol, AgentContext, AgentResult(可选)
|
||||||
|
├── conversation_agent.py # 保留为 facade,内部委托 ChatOrchestrator
|
||||||
|
├── memory_agent.py # 保留或标记 deprecated,由 MemoirOrchestrator 替代
|
||||||
|
├── memoir_processor.py # BackgroundTaskRunner 保留,ContentAnalyzer/MemoirGenerator 可迁移到 memoir/
|
||||||
|
├── chat/
|
||||||
|
│ ├── __init__.py
|
||||||
|
│ ├── orchestrator.py # ChatOrchestrator
|
||||||
|
│ ├── profile_agent.py # ProfileAgent
|
||||||
|
│ ├── interview_agent.py # InterviewAgent
|
||||||
|
│ └── stage_detector.py # StageDetectorAgent(可选)
|
||||||
|
├── memoir/
|
||||||
|
│ ├── __init__.py
|
||||||
|
│ ├── orchestrator.py # MemoirOrchestrator
|
||||||
|
│ ├── extraction_agent.py
|
||||||
|
│ ├── classification_agent.py
|
||||||
|
│ ├── narrative_agent.py
|
||||||
|
│ └── placeholder_agent.py
|
||||||
|
└── image_prompt/
|
||||||
|
├── __init__.py
|
||||||
|
├── orchestrator.py # ImagePromptOrchestrator
|
||||||
|
└── prompt_agent.py # PromptGenerationAgent(或沿用 MemoirImagePromptService)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 九、迁移路径
|
||||||
|
|
||||||
|
### 9.1 阶段划分
|
||||||
|
|
||||||
|
| 阶段 | 内容 | 风险 |
|
||||||
|
|------|------|------|
|
||||||
|
| **Phase 1** | 模块一 Chat 多 Agent 改造 | 低,可保留 ConversationAgent facade |
|
||||||
|
| **Phase 2** | 模块二 Memoir 多 Agent 改造 | 中,Celery 任务改动需充分测试 |
|
||||||
|
| **Phase 3** | 模块三 Image Prompt 多 Agent 改造 | 低,调用点少 |
|
||||||
|
| **Phase 4** | 清理旧实现、统一协议、补充测试与文档 | 低 |
|
||||||
|
|
||||||
|
### 9.2 兼容策略
|
||||||
|
|
||||||
|
1. **Facade 保留**:`ConversationAgent` 在 Phase 1 后作为 thin wrapper,内部调用 `ChatOrchestrator`,pipeline 可不改或仅改 import
|
||||||
|
2. **Feature Flag**:可配置 `USE_MULTI_AGENT_CHAT=true` 等,便于灰度与回滚
|
||||||
|
3. **测试**:每个 Phase 完成后,跑现有 HTTP/WebSocket/Celery 测试,确保行为一致
|
||||||
|
|
||||||
|
### 9.3 验收标准
|
||||||
|
|
||||||
|
- [ ] 三个模块均通过 Orchestrator + Specialist 模式工作
|
||||||
|
- [ ] 现有功能行为与改造前一致(对话回复、回忆录生成、图片生成)
|
||||||
|
- [ ] 单元测试覆盖各 Specialist Agent
|
||||||
|
- [ ] 文档更新:AGENT.md 或新增 multi-agent.md 描述新架构
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十、风险与注意事项
|
||||||
|
|
||||||
|
| 风险 | 缓解措施 |
|
||||||
|
|------|----------|
|
||||||
|
| Celery 任务中同步/异步混用 | Memoir/Image 相关 Agent 在 Celery 中需用同步 LLM 调用(`invoke`),保持与现有一致 |
|
||||||
|
| 状态一致性 | Orchestrator 负责事务边界,Memoir 模块的章节锁、state 更新逻辑保持不变 |
|
||||||
|
| 性能回归 | 多一层调用理论上增加极少量开销,可通过 benchmark 验证;避免不必要的 Agent 间序列化 |
|
||||||
|
| 过度抽象 | 若某模块 Specialist 仅一个,可简化为例常函数,不必强求「每个能力一个 Agent」 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十一、附录:现有调用关系速查
|
||||||
|
|
||||||
|
| 调用链 | 入口 | 核心逻辑位置 |
|
||||||
|
|--------|------|--------------|
|
||||||
|
| 用户发消息 → AI 回复 | `pipeline.process_user_message` | `ConversationAgent.generate_response_with_state` / `generate_profile_followup` |
|
||||||
|
| 对话结束 → 回忆录 | `pipeline.process_conversation_segments` → `process_memoir_segments.delay` | `memoir_tasks.process_memoir_segments` |
|
||||||
|
| 回忆录完成 → 补图 | `process_memoir_segments` 末尾 → `generate_chapter_images.delay` | `memoir_tasks.generate_chapter_images` → `MemoirImagePromptService.build_prompt` / `build_cover_prompt` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*文档版本:1.0 | 创建日期:2025-03-19*
|
||||||
Reference in New Issue
Block a user