20 KiB
20 KiB
三模块多 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 主要问题
- 职责混杂:
ConversationAgent同时做资料提取、资料追问、正式访谈,逻辑耦合 - 流程内聚:回忆录处理全部写在
process_memoir_segments单任务内,难以单测和替换子步骤 - Service 非 Agent:
MemoirImagePromptService仅为工具类,无编排与决策能力 - 缺乏统一抽象:三个模块调用方式各异,无统一的 Agent 协议
三、多 Agent 架构设计
3.1 总体模式
采用 Orchestrator + Specialist Agents 模式:
- Orchestrator:负责路由、决策、编排,不直接调用 LLM 完成具体生成
- Specialist Agent:接收 Orchestrator 下发的任务,完成单一 LLM 任务并返回结构化结果
3.2 统一 Agent 协议(建议)
为便于 DI、测试和可观测性,建议定义统一的 Agent 协议:
# 概念性协议,非实际代码
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 协作流程
- Pipeline 调用
ChatOrchestrator.run(conversation_id, user_message, user, segment, ...) - Orchestrator 查询
get_missing_profile_fields(user),若有缺失则调用ProfileAgent - 否则获取
MemoirState,调用InterviewAgent(可选:先调StageDetectorAgent获取detected_stage) - 将 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 协作流程
- Celery 任务
process_memoir_segments入口仅负责:取 segments、获取 db、调用MemoirOrchestrator.run(user_id, segment_ids, db) - Orchestrator 对每个 segment:调
ExtractionAgent→ 调ClassificationAgent,若 None 则跳过 - 按 category 聚合后,对每个 category:调
NarrativeAgent生成 title + narrative → 调PlaceholderInjectAgent→ 写入 sections - 若有待补图章节,派发
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 协作流程
generate_chapter_images任务内,对封面和每个 section:- 构造
(chapter_title, category, description, context_excerpt)等输入 - 调用
ImagePromptOrchestrator.build_prompt或build_cover_prompt
- 构造
- 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 兼容策略
- Facade 保留:
ConversationAgent在 Phase 1 后作为 thin wrapper,内部调用ChatOrchestrator,pipeline 可不改或仅改 import - Feature Flag:可配置
USE_MULTI_AGENT_CHAT=true等,便于灰度与回滚 - 测试:每个 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