From b56fc859cc3b027b2dc846c310b4f433c0049d4a Mon Sep 17 00:00:00 2001 From: yangshilin <2157598560@qq.com> Date: Thu, 19 Mar 2026 10:28:40 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=A4=9Aagent=E6=9E=B6=E6=9E=84plan?= =?UTF-8?q?=E8=AE=A1=E5=88=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/plans/multi-agent-refactor-plan.md | 354 ++++++++++++++++++++++++ 1 file changed, 354 insertions(+) create mode 100644 docs/plans/multi-agent-refactor-plan.md diff --git a/docs/plans/multi-agent-refactor-plan.md b/docs/plans/multi-agent-refactor-plan.md new file mode 100644 index 0000000..fb231bc --- /dev/null +++ b/docs/plans/multi-agent-refactor-plan.md @@ -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*