这是 AutoGen 系列的第三篇,也是最后一篇实战篇。在之前的文章中,我们分别拆解了 AutoGen 的内部架构与AG2分叉始末(第一篇),以及生产级部署方案(第二篇)。现在到了真正动手的时候——从零构建一个完整的多Agent系统。你将学到:如何用 AssistantAgent + SelectorGroupChat 构建内容创作团队、GroupChat 的选人机制深度剖析——从源码看 select_speaker() 的实现细节、Tool & Code Execution——Agent 工具注册和 Docker 沙箱代码执行、6 个来自 GitHub Issues 的高频踩坑、以及测试与生产模式。
本文假设你已经安装了 autogen-agentchat 和 autogen-ext[openai] 包。如果你还没有阅读第一篇架构文章,建议先花 10 分钟快速浏览,了解 AutoGen 的三层架构设计哲学——这对理解本文的实战内容有很大帮助。
| 系列篇 | 标题 | 核心内容 |
|---|---|---|
| #1 | 架构源码分析 | 三层架构、消息类型、AG2分叉 |
| #2 | 生产部署 | FastAPI+SSE、持久化、监控 |
| #3 (本文) | 实战指南 | 多Agent构建、踩坑修复、测试 |
我们将构建一个内容创作团队,包含 4 个专用 Agent,按流水线协作:Researcher(调研收集资料)→ Writer(撰写内容)→ Reviewer(审查修改)→ Publisher(格式化输出)。每个 Agent 使用 AssistantAgent,通过 system_message 设定角色。使用 SelectorGroupChat 让 LLM 动态决定下一个发言的 Agent,设置 MaxMessageTermination(max_messages=15) 防止无限对话。Termination 条件深度配置:组合 TextMentionTermination(收到 "TERMINATE" 文本)、MaxMessageTermination(超过 20 条消息)和 StopMessageTermination。
源码中终止系统的核心在 conditions/_terminations.py,每个 TerminationCondition 实现了 __call__ 方法,接收消息序列,返回 StopMessage | None。组合条件是典型的职责链模式——多个终止条件按顺序执行,任何一个返回 StopMessage 即终止。这种设计让开发者可以灵活组合简单的终止条件构建复杂的终止策略。
Agent 的 system_message 是决定 Agent 行为的关键。一个好的 system_message 应该包含:角色定义(你是谁?)、职责描述(你做什么?)、约束条件(你不能做什么?)、输出格式(你如何表达?)。例如 Researcher 的 system_message 可能包含"You are a thorough researcher. Your job is to find relevant information and present it in a structured format. Never fabricate data. Cite your sources."
AutoGen 提供了 3 种 GroupChat 实现:RoundRobinGroupChat(轮询,顺序轮流——维护 _next_speaker_index 索引,每次 +1 取模)、SelectorGroupChat(LLM 模型动态选择——选人逻辑分三个层级:Selector Function 覆盖 → Candidate Function 裁剪 → LLM 模型选择)、GraphGroupChat(有向图约束 + 可达性——只有有边相连的 Agent 才能连续发言)。三种 GroupChat 覆盖了从确定性到智能选择到图约束的完整光谱。
LLM 选人重试机制:_select_speaker() 方法执行实际的 LLM 调用,包含三次重试——如果 LLM 返回的提及不在参与者列表中(0 mentions)或提到了多个名字(>1 mentions),会自动重试最多 max_selector_attempts 次(默认 3 次)。全部失败后 fallback 到上一个发言者或第一个参与者。
理解选人机制的关键在于:SelectorGroupChat 的默认行为是让 LLM 基于对话历史选择下一个发言者。这意味着选人质量直接取决于你的 Agent 的 description 字段质量。如果两个 Agent 的描述都包含"handles user queries",LLM 无法区分它们。建议为每个 Agent 编写独特且准确的角色描述,并确保它们之间的职责边界清晰。
| GroupChat | 选人策略 | 重试机制 |
|---|---|---|
| RoundRobin | 顺序轮询 | 无 |
| Selector | 三级层级 | 3 次自动重试 |
| Graph | 有向图可达性 | 无 |
AutoGen 支持两种代码/工具执行模式:内置 Tool 注册(函数调用)和 CodeExecutorAgent(沙箱化代码执行)。Tool 注册模式:将任意 Python 函数注册为 Agent 工具,LLM 会在需要时调用。使用 FunctionTool 包装异步函数,通过 tools=[search_tool] 参数传入 AssistantAgent。reflect_on_tool_use 机制(v0.4+ 新增):Agent 在 Tool Call 后会用 LLM 再反思一次结果,形成 Thought → Action → Observation → Reflection 的完整循环。
CodeExecutorAgent — Docker 沙箱执行:使用 DockerCommandLineCodeExecutor 在 Docker 容器中安全执行代码。Approve/Deny 安全控制:通过 approval_func 审查代码内容,阻止文件系统操作和危险代码(open(、os.、subprocess、eval(、exec()。生产环境必须设置审批函数,并推荐使用 Docker 沙箱而非本地执行。
reflect_on_tool_use 是一个特别有价值的特性。当 Agent 调用工具获取结果后,如果 reflect_on_tool_use=True,Agent 会额外调用一次 LLM 来"反思"工具结果。这可以让 Agent 在返回最终答案之前确认工具输出是否合理、是否需要补充信息或是否需要调用另一个工具。对于复杂的数据分析任务,这个循环可以显著提升结果质量。
坑 1:包名混淆 — autogen vs autogen-agentchat。pip 会把两个包装在同一个环境里但彼此不兼容。修复:pip uninstall autogen autogen-agentchat 先清理,再只安装需要的。
坑 2:GroupChat 历史丢失 — 消息顺序混乱。Agent 是有状态的——每个 on_messages() 只接收新增消息。修复:检查 allow_repeated_speaker 设置,使用 Console(group_chat.run_stream(...)) 打印完整消息流。
坑 3:Token 超限 — 上下文窗口管理。AssistantAgent 默认使用 UnboundedChatCompletionContext,不会自动裁剪消息。修复:使用 BoundedChatCompletionContext(max_length=4000) 或设置 max_turns。
坑 4:Agent 无响应 — 超时/死锁。内部使用 SingleThreadedAgentRuntime,如果 Agent 抛出未捕获异常且 ignore_unhandled_exceptions=True,异常会被静默吞掉。修复:确保 ignore_unhandled_exceptions=False(v0.7+ 默认已修复),为模型客户端设置 timeout=30。
坑 5:状态不持久 — Checkpoint 恢复失败。没有内置自动持久化,需要手动在合适的时机调用 save/load_state。自定义消息类型必须在 Team 初始化时注册 custom_message_types=[MyMessage]。
坑 6:AG2 兼容性 — 迁移踩坑。API 完全不同:initiate_chat() → await team.run(),GroupChat(agents=...) → RoundRobinGroupChat(participants=...)。
多 Agent 系统的测试比单模型调用复杂得多。这里提供三层测试策略:单元测试(覆盖 80% 代码逻辑)——使用 unittest.mock 模拟模型客户端,验证 Agent 消息流程、Termination 条件、Tool 调用解析。集成测试——Mock Team 运行,测试完整的 Team 运行流程。CI 管道集成——pytest + GitHub Actions,Mock LLM 的单元测试覆盖 80%,真实 LLM 的集成测试覆盖关键路径(注意成本)。不要在 CI 中运行需要 Docker 的 CodeExecutorAgent 测试。
生产模式建议:模式 1 — 错误边界(try/except + MaxTimeTermination);模式 2 — 状态快照(每次交互后 save_state);模式 3 — 成本控制(监控 token 计数);模式 4 — 日志追踪(emit_team_events=True);模式 5 — 人机协同(UserProxyAgent 插入人类审批)。
Mock LLM 测试的关键技巧是使用 AsyncMock 模拟 ChatCompletionClient 接口。不需要真实的 LLM API 调用即可验证 Agent 的消息处理逻辑。对于 Tool 调用场景,模拟 create() 方法返回包含 tool_calls 的响应,然后验证 Agent 是否正确执行了工具。测试 Termination 条件时,模拟不同的消息序列验证终止条件是否在正确时机触发。
AutoGen + LangGraph 混合模式:对于复杂工作流,可以将 AutoGen 的 GroupChat 作为 LangGraph 图中的一个子节点运行——LangGraph 负责高层控制流,AutoGen 负责内部多 Agent 协作。框架对比最终总结:AutoGen(消息传递、有状态、内置状态持久化、Docker 沙箱内置、维护模式)、LangGraph(DAG 图编排、无状态节点、活跃开发)、CrewAI(顺序/层级、快速原型、活跃开发)、Microsoft Agent Framework(事件驱动、企业级多通道、活跃开发)。
一句话总结 AutoGen:AutoGen 的架构设计(三层分离、Pydantic 原生、纯异步、内置状态管理)在代码质量上远超 v0.2 和 AG2。但微软已转向 Microsoft Agent Framework。新项目用 Agent Framework,已有投入用 AG2,学习用 autogen-agentchat v0.7+。
最终建议:如果你在 2026 年启动一个新的多 Agent 项目,优先考虑 Microsoft Agent Framework。如果你的团队已经在 AutoGen/AG2 上有大量投资,继续使用现有栈。学习 AutoGen v0.7+ 的架构设计仍然很有价值——它的三层分离、消息传递模型和状态管理设计理念是 Agent 框架的通用知识。