🤝 构建 Agent 实践指南 — 多 Agent 协作

消息传递 · 状态共享 · 任务编排 — 从 AutoGen/LangGraph/CrewAI/MetaGPT/CAMEL 源码提炼的多 Agent 协作方法论

📑 目录

  1. 1 为什么需要多 Agent?单 Agent 的极限
  2. 2 协作模式全景图:6 种编排范式
  3. 3 消息传递:多 Agent 的血液循环
  4. 4 状态共享:从共享内存到事件溯源
  5. 5 任务编排:5 大框架的编排实现对比
  6. 6 Agent 切换:Handoff vs Router vs Watch
  7. 7 嵌套与层级:子 Agent 的组合艺术
  8. 8 并行执行:Map-Reduce 与异步扇出
  9. 9 终止与收敛:何时结束协作?
  10. 10 实战选型指南:场景 → 框架映射
  11. 11 反模式与常见坑
  12. 12 决策树:我该用多 Agent 吗?

1 为什么需要多 Agent?单 Agent 的极限

从 20 个 Agent 项目的源码分析中,我们发现单 Agent 系统面临三个根本性瓶颈:

🧠 上下文窗口耗尽

一个 Agent 承担太多职责,提示词膨胀、历史过长。GPT Researcher 的单 Agent 模式在深度研究时经常触及 token 上限,而多 Agent 的 ChiefEditorAgent 通过子话题拆分解决了这个问题。

🎭 角色混淆

同一个 Agent 既写代码又做 Code Review,认知冲突导致质量下降。MetaGPT 发现 SOP 流水线中让 Engineer 只写代码、QaEngineer 只做测试,Bug 检出率显著提升。

🔄 串行瓶颈

单 Agent 只能逐个处理子任务。AutoGen 的多 Agent 并行可以同时让不同 Agent 处理不同子查询,总耗时从 Σt_i 降到 max(t_i)

🛡️ 单点故障

一个 Agent 出错,整个流程崩溃。AutoGen 的 MagenticOne 用 Ledger 机制检测 stall 并重新规划;OpenClaw 的 subagent spawn/kill 实现了独立故障域。

核心洞察:多 Agent 不是"为了多而多"——它解决的是 认知负荷并行效率故障隔离 三个单 Agent 无法解决的问题。如果你的场景不涉及这三者,单 Agent 更简单。

2 协作模式全景图:6 种编排范式

从源码中提炼出 6 种多 Agent 编排模式,每种都有其最佳适用场景:

范式 1: 轮转 (Round-Robin) — AutoGen RoundRobinGroupChat Agent A ──→ Agent B ──→ Agent C ──→ Agent A ──→ ... 适用: 角色固定、顺序确定、每个角色必须发言的场景 范式 2: 监督者 (Supervisor) — LangGraph Supervisor ┌─────────────┐ │ Supervisor │ ← 决策中心 └──┬───┬───┬──┘ │ │ │ ▼ ▼ ▼ A B C ← 工作节点,被选中才执行 适用: 需要集中决策、任务动态分配 范式 3: 蜂群 (Swarm / Handoff) — AutoGen Swarm, LangGraph Command(goto) Agent A ──Handoff──→ Agent C Agent C ──Handoff──→ Agent B Agent B ──Handoff──→ Agent A 适用: Agent 自主决定下一步路由,动态任务链 范式 4: SOP 流水线 (Pipeline) — MetaGPT SOP, CrewAI Sequential PM → Architect → Engineer → QA → Reviewer 适用: 固定流程、每个阶段有明确输入输出 范式 5: 图执行 (DAG / State Machine) — LangGraph StateGraph, AutoGen DiGraph ┌───┐ ┌───┐ │ A ├────→│ C │ └─┬─┘ └───┘ │ ▲ ▼ │ ┌───┐ │ │ B ├───────┘ └───┘ 适用: 复杂依赖、条件分支、并行汇聚 范式 6: 层级嵌套 (Hierarchical) — AutoGen SocietyOfMind, LangGraph Subgraph ┌─── Team Lead ───┐ │ │ ┌── SubTeam A ──┐ ┌── SubTeam B ──┐ │ A1 A2 │ │ B1 B2 │ └───────────────┘ └───────────────┘ 适用: 复杂任务拆解、信息隐藏、故障隔离
范式路由决策并行性状态管理典型框架最佳场景
轮转固定顺序❌ 串行共享消息列表AutoGen圆桌讨论、轮流审稿
监督者中心 LLM✅ 可并行Supervisor 管理LangGraph客服路由、任务分发
蜂群Agent 自主❌ 串行Handoff contextAutoGen Swarm动态任务链、自由协作
SOP 流水线预定流程部分并行上下文传递MetaGPT, CrewAI软件开发、文档流水线
图执行条件边✅ DAG 并行检查点LangGraph复杂工作流、需要回滚
层级嵌套层级委托✅ 跨层并行分层隔离AutoGen SoM大团队、子任务独立

3 消息传递:多 Agent 的血液循环

多 Agent 系统的核心是 消息传递。不同框架的消息模型差异巨大,直接决定了系统的表达能力上限。

3.1 AutoGen:Actor Model 双模式通信

AutoGen Core 实现了两种消息传递模式,覆盖从简单到复杂的所有场景:

AutoGen Core — Actor Model 通信 模式 1: RPC (点对点) runtime.send_message(msg, AgentId("bob")) → asyncio.Future 等待 Bob 的返回值 → 请求-响应模式,适合需要结果的任务委派 模式 2: Event (发布/订阅) runtime.publish_message(msg, TopicId("research")) → SubscriptionManager 路由到所有订阅 "research" 的 Agent → 广播模式,适合事件通知、日志、监控 AgentChat 层的映射 ChatAgent.on_messages() → Core 层的 on_message() Team.run() → 内部创建 GroupChatManager 注册到 Runtime Manager 通过 Topic 管理参与者 → 路由发言者
# AutoGen Core: RPC 通信
result = await runtime.send_message(
    message=TextMessage(content="分析这段代码", source="reviewer"),
    recipient=AgentId("code_analyst")
)

# AutoGen Core: 发布/订阅
await runtime.publish_message(
    message=EventMessage(event="task_completed", result=summary),
    topic_id=TopicId("notifications")
)
AutoGen 的设计智慧:Core 层只关心消息路由,不关心语义。Chat 语义("谁该说话"、"说了什么")全部由上层 AgentChat 定义。这种分层让同一 Runtime 既可以跑聊天场景,也可以跑分布式 Agent 系统。

3.2 MetaGPT:Watch-Publish 精确路由

MetaGPT 的消息路由基于 cause_by 字段——每条消息携带"由哪个 Action 产生"的标记,Role 通过 watch 列表声明关心哪些 Action 的输出:

# MetaGPT: 消息路由核心
class Role(BaseRole):
    rc: RoleContext  # 包含 watch: set[str]

    async def _observe(self) -> int:
        news = self.rc.msg_buffer.pop_all()
        # 只保留 cause_by 在 watch 列表中的消息
        self.rc.news = [
            n for n in news
            if n.cause_by in self.rc.watch or self.name in n.send_to
        ]
        return len(self.rc.news)

# Environment 路由:根据 member_addrs 和 is_send_to() 推送到对应 Role 的 buffer
# Role 的 msg_buffer 是私有的,避免全局广播噪音
MetaGPT Watch-Publish 路由示例 ProductManager: watch: {WritePRD} ← 自己的输出 actions: [WritePRD] Architect: watch: {WritePRD} ← 关心 PRD 输出 actions: [WriteDesign] ProjectManager: watch: {WriteDesign} ← 关心设计输出 actions: [WriteTasks] Engineer: watch: {WriteTasks} ← 关心任务输出 actions: [WriteCode, WriteCodeReview] QA: watch: {WriteCode} ← 关心代码输出 actions: [WriteTest, RunCode] 路由流程: PM.publish_message(PRD) → Environment → Architect watch 命中 WritePRD → 推入 buffer → Architect._observe() → 过滤 → news = [PRD] → Architect._think() → 选择 WriteDesign → Architect._act() → 生成设计文档 → Architect.publish_message(Design) → Environment → ProjectManager watch 命中 → ...

✅ Watch-Publish 优势

  • 精确路由:只接收相关消息,避免信息过载
  • 松耦合:Role 不需要知道彼此的存在,只关心 Action 类型
  • SOP 天然适配:流水线 = watch 上一环节的输出

❌ Watch-Publish 劣势

  • 只能做流水线:无法表达循环、条件分支
  • 调试困难:消息路由依赖 cause_by 匹配,不容易追踪
  • 扩展性差:新增协作模式需要修改 Role 的 watch 列表

3.3 LangGraph:Channel + Reducer 状态通信

LangGraph 不使用"消息"概念——Agent 通过读写 Channel(共享状态键)通信:

# LangGraph: 通过共享 State 通信
class State(TypedDict):
    messages: Annotated[list, add_messages]  # Reducer: 追加而非覆盖
    next_agent: str
    research_results: Annotated[list, operator.add]  # 并行结果合并

# 并行 Worker 写入 research_results
# Reducer (operator.add) 自动合并两个 Worker 的输出
# 下游节点读到的就是合并后的完整结果
三种消息模型对比:AutoGen 的 Actor Model 最灵活(RPC + Pub/Sub),MetaGPT 的 Watch-Publish 最适合流水线,LangGraph 的 Channel+Reducer 最适合并行汇聚。选型时先想清楚你的协作模式。

4 状态共享:从共享内存到事件溯源

多 Agent 协作的另一个核心问题:状态存储在哪里?谁来读写?

策略实现读写模型并行安全回滚能力
共享消息列表AutoGen GroupChat所有 Agent 追加写⚠️ 需要锁❌ 无
共享 State + ReducerLangGraph节点通过 Reducer 写入✅ Reducer 保证✅ 检查点
私有 Buffer + 路由MetaGPTEnvironment 推入 Buffer✅ Buffer 私有❌ 无
Task 上下文传递CrewAITask 输出 → 下一 Task⚠️ 顺序依赖✅ 检查点
会话隔离OpenClaw subagent子代理独立会话✅ 完全隔离✅ 会话级

4.1 LangGraph 的检查点:状态时间旅行

LangGraph 拥有所有框架中最强的状态管理——检查点系统允许回溯任意历史状态:

# LangGraph: 检查点回溯
from langgraph.checkpoint.sqlite import SqliteSaver

checkpointer = SqliteSaver.from_conn_string("db.sqlite")
graph = builder.compile(checkpointer=checkpointer)

# 执行并自动保存检查点
result = graph.invoke({"messages": [...]}, config={"configurable": {"thread_id": "1"}})

# 查看所有历史状态
states = list(graph.get_state_history(config))
for state in states:
    print(f"Step {state.metadata['step']}: next={state.next}")

# 回滚到特定检查点
graph.invoke(None, config, checkpoint_id=states[3].config["configurable"]["checkpoint_id"])

# 修改状态后继续
graph.invoke(Command(update={"approved": True}), config)
检查点的价值:不只是"撤销"——更关键的是 调试(查看每步状态)和 人机协作(暂停→审查→继续)。LangGraph 是唯一做到这一点的框架。

4.2 AutoGen MagenticOne:Ledger 状态模型

MagenticOne 用结构化的 Ledger(账本) 管理协作状态,是最接近"项目管理"的编排:

# MagenticOne 双账本
class LedgerEntry(BaseModel):
    is_request_completed: bool
    is_in_progress: bool
    is_step_complete: bool
    next_speaker: str | None
    instruction_to_next_speaker: str | None

# 编排循环:
# 1. 初始化 Task Ledger (facts + plan)
# 2. 每轮:
#    a. 更新 Facts Ledger(基于新消息)
#    b. 更新 Plan Ledger(基于新事实)
#    c. 查询 Progress Ledger → 确定 next_speaker + instruction
#    d. 路由消息给 next_speaker
#    e. 检查 stall → 连续 stall >= max_stalls → 重新规划
#    f. 检查完成 → is_request_completed → 生成最终答案
Ledger 的启示:多 Agent 协作需要 显式状态追踪——不是隐式地让 LLM "记住"进度,而是用结构化数据记录"做完了什么、该做谁、做什么"。这是 MagenticOne 的核心贡献。

5 任务编排:5 大框架的编排实现对比

5.1 AutoGen:5 种群组编排模式

AutoGen 提供最丰富的编排选项——从最简单到最复杂,渐进式覆盖:

AutoGen 编排渐进式 Level 1: RoundRobinGroupChat — 固定轮转 select_speaker() → 按索引轮转 10 行代码搞定 Level 2: SelectorGroupChat — LLM 选择发言者 三层覆盖: selector_func → candidate_func → LLM 容错: 选择失败 → 回退上一个发言者 Level 3: Swarm — Agent 自主 Handoff Agent 通过 Handoff 工具声明"我该切换到谁" 不需要中央选择器 → 去中心化 Level 4: DiGraphGroupChat — DAG 图执行 (实验性) 有向图 + 条件边 + 循环 activation_group 前向依赖 Level 5: MagenticOneGroupChat — Ledger 编排 (论文级) 双账本 + stall 检测 + 重新规划 最接近真实项目管理的编排
# AutoGen: SelectorGroupChat 三层覆盖
team = SelectorGroupChat(
    participants=[writer, reviewer, editor],
    model_client=openai_client,
    selector_func=lambda messages: "reviewer" if "审查" in messages[-1].content else None,
    # selector_func 返回非 None → 覆盖 LLM 选择(确定性规则)
    # selector_func 返回 None → 走 LLM 选择
    candidate_func=lambda messages: ["writer", "editor"],  # 过滤候选
    allow_repeated_speaker=False,  # 不允许连续同一发言者
    max_selector_attempts=3,  # LLM 选择失败重试次数
)

5.2 LangGraph:StateGraph 图执行

LangGraph 的编排基于 Pregel 超步模型——所有节点在同一个超步并行执行,超步结束时通过 Reducer 合并结果:

# LangGraph: Supervisor 编排
from langgraph.graph import StateGraph, START, END

builder = StateGraph(State)

# 添加节点
builder.add_node("supervisor", supervisor_node)
builder.add_node("researcher", researcher_node)
builder.add_node("coder", coder_node)

# 添加边
builder.add_edge(START, "supervisor")
builder.add_conditional_edges(
    "supervisor",
    lambda state: state["next_agent"],  # 动态路由
    {"researcher": "researcher", "coder": "coder"}
)
builder.add_edge("researcher", "supervisor")
builder.add_edge("coder", "supervisor")
builder.add_conditional_edges("supervisor", should_end, {True: END, False: "supervisor"})

graph = builder.compile(checkpointer=SqliteSaver.from_conn_string("db.sqlite"))
Pregel 的独特价值:超步模型保证了并行写入的正确性——add_messages reducer 在超步结束时将两个并行节点的输出合并,而非覆盖。这是唯一有形式化正确性保证的执行模型。

5.3 CrewAI:Process-Driven + Flow

CrewAI 的编排分两层:Process 枚举控制基本模式,Flow 装饰器处理复杂流程:

# CrewAI: 基本模式
crew = Crew(
    agents=[researcher, writer, reviewer],
    tasks=[research_task, write_task, review_task],
    process=Process.sequential,  # 或 Process.hierarchical
)

# Hierarchical 模式:自动创建 Manager Agent
# Manager 获得 DelegateWorkTool + AskQuestionTool
# Manager 决定谁做什么

# Flow 系统:高级编排
class ResearchFlow(Flow):
    @start()
    async def plan(self, ctx):
        return {"plan": await planner.run(ctx)}

    @listen("plan")
    async def research(self, ctx):
        return {"research": await researcher.run(ctx)}

    @listen("research")
    async def write(self, ctx):
        return {"article": await writer.run(ctx)}

    @router("plan")
    async def route(self, ctx):
        if ctx.data["plan"]["needs_research"]:
            return "research"
        return "write"

5.4 MetaGPT:SOP 流水线

MetaGPT 的编排是 最不灵活但最可靠 的——SOP 一旦定义,角色就按流水线自动推进:

# MetaGPT: 软件公司 SOP
team = Team()
team.hire(
    ProductManager(),    # watch: {} → 触发 WritePRD
    Architect(),         # watch: {WritePRD} → 触发 WriteDesign
    ProjectManager(),    # watch: {WriteDesign} → 触发 WriteTasks
    Engineer(),          # watch: {WriteTasks} → 触发 WriteCode
    QaEngineer(),        # watch: {WriteCode} → 触发 WriteTest
)
team.run_project("构建一个博客系统")
# 自动按 SOP 推进: PRD → 设计 → 任务 → 代码 → 测试
MetaGPT SOP vs AutoGen Swarm 对比 MetaGPT SOP: 固定流水线,确定性高,但无法动态调整 PM ──PRD──→ Architect ──Design──→ PM ──Tasks──→ Eng ──Code──→ QA 适合: 标准化流程(软件开发、文档生成) AutoGen Swarm: 动态 Handoff,Agent 自主路由,灵活但不可预测 A ──?──→ ? ──?──→ ? (运行时才知道) 适合: 开放式任务(研究、探索、故障排查)

5.5 CAMEL:RolePlaying + Workforce

CAMEL 提供两种多 Agent 模式:

# CAMEL RolePlaying: 两个 Agent 对话
from camel.societies import RolePlaying

role_play = RolePlaying(
    assistant_role_name="Python 程序员",
    user_role_name="代码审查员",
    assistant_agent_kwargs={"model": "gpt-4"},
    user_agent_kwargs={"model": "gpt-4"},
)
# 自动生成角色提示词,两 Agent 交替对话

# CAMEL Workforce: 层级任务分解
from camel.societies import Workforce
workforce = Workforce("研究团队")
workforce.add_agent(researcher)
workforce.add_agent(writer)
result = await workforce.process_task(complex_task)
# 自动分解 → 分配 → 执行 → 汇总

6 Agent 切换:Handoff vs Router vs Watch

"下一个该谁说话?" 是多 Agent 编排的核心问题。三种主流方案:

机制决策者上下文传递可预测性代表框架
Handoff Agent 自身 精确 context 字段 低 (依赖 LLM) AutoGen Swarm
Router (选择器) 外部 LLM/函数 完整消息历史 高 (可确定性覆盖) AutoGen Selector
Watch (观察) 静态规则 (cause_by) 消息本身 最高 (完全确定性) MetaGPT
Command(goto) 节点函数返回 State update 中 (代码控制) LangGraph

6.1 AutoGen Handoff 深度解析

Handoff 将 Agent 切换建模为 工具调用——这是 AutoGen v0.5 最创新的设计:

Handoff 执行流程 1. 注册阶段 AssistantAgent(handoffs=["Bob"]) → Handoff(target="Bob") → FunctionTool(name="transfer_to_bob", description="Handoff to Bob") → 加入 Agent 的工具列表 2. 推理阶段 模型看到工具列表: [...正常工具, transfer_to_bob] 模型决定调用 transfer_to_bob → FunctionCall 3. 执行阶段 _check_and_handle_handoff(): 收集非 handoff 的工具调用+结果 → handoff_context 返回 HandoffMessage(target="Bob", context=[...]) 4. 路由阶段 Swarm Manager 收到 HandoffMessage → select_speaker() → 选中 "Bob" → Bob.on_messages() 接收 HandoffMessage → 展开 context 到 Bob 的 model_context
# AutoGen: Handoff 使用
analyst = AssistantAgent(
    "analyst",
    model_client=openai_client,
    tools=[search_tool],
    handoffs=["writer", "reviewer"],  # 声明可切换到谁
)

# 模型推理时自动看到 transfer_to_writer 和 transfer_to_reviewer 工具
# 模型决定切换时,HandoffMessage 携带当前上下文给下一个 Agent
Handoff vs Router 的取舍:Handoff 让 Agent 有自主权(灵活),但也意味着你放弃了中央控制(不可预测)。实践建议:生产系统用 Router + 确定性规则兜底,原型/探索用 Handoff

7 嵌套与层级:子 Agent 的组合艺术

7.1 AutoGen SocietyOfMind:Team-in-Agent

SocietyOfMindAgent 将一个 Team 包装为单个 Agent——实现两层信息压缩:

# AutoGen: SocietyOfMindAgent
inner_team = RoundRobinGroupChat([writer, reviewer])

writer_team = SocietyOfMindAgent(
    "writer_team",
    team=inner_team,
    model_client=openai_client,
    # 内层 Team 完成多轮写作-审稿
    # SocietyOfMind 用 LLM 总结为单条响应
)

# 外层 Team 只看到总结,不感知内部细节
outer_team = RoundRobinGroupChat([writer_team, translator])
SocietyOfMind 两层压缩 外层: RoundRobinGroupChat │ ├── SocietyOfMindAgent("writer_team") │ └── 内层: RoundRobinGroupChat │ ├── Writer Agent ──"初稿"──→ Reviewer │ └── Reviewer Agent ──"修改建议"──→ Writer │ ... (多轮直到收敛) │ → LLM 总结 → 单条 TextMessage │ └── Translator Agent → 接收总结,翻译 信息隐藏: 外层不感知内层的多轮对话细节 内层修改不影响外层逻辑 = 面向对象中的"封装"在 Agent 系统中的应用

7.2 LangGraph 子图组合

# LangGraph: 编译后的图作为节点
research_subgraph = research_builder.compile(checkpointer=...)
coding_subgraph = coding_builder.compile()

parent = StateGraph(ParentState)
parent.add_node("research", research_subgraph)  # 子图作为节点
parent.add_node("coding", coding_subgraph)
parent.add_edge("research", "coding")

# 子图内部状态通过 Command(graph=Command.PARENT) 上报
def research_done(state):
    return Command(
        update={"research_results": state["results"]},
        graph=Command.PARENT  # 上报给父图
    )

7.3 OpenClaw Sub-Agent:spawn/steer/kill/yield

OpenClaw 的子代理模型最接近操作系统进程管理:

# OpenClaw: 子代理生命周期
sessions_spawn(
    task="分析这份报告",
    runtime="subagent",
    context="isolated",  # 或 "fork" 继承父会话上下文
    mode="run",          # 后台执行
)

# 管理操作
subagents(action="list")    # 查看所有子代理
subagents(action="steer", target="sub-123", message="加上对比分析")  # 动态干预
subagents(action="kill", target="sub-123")  # 终止子代理
sessions_yield()            # 等待子代理结果
嵌套的三个层次:(1) Team-in-Agent(AutoGen SoM)——逻辑嵌套,共享 Runtime;(2) Subgraph-in-Graph(LangGraph)——编译嵌套,独立检查点;(3) Process-in-Process(OpenClaw)——进程嵌套,完全隔离。隔离越强,安全性越高但通信成本越大。

8 并行执行:Map-Reduce 与异步扇出

8.1 LangGraph Send API:动态并行扇出

LangGraph 的 Send 是所有框架中唯一的 运行时动态并行 机制:

# LangGraph: Send 动态并行
from langgraph.types import Send

def route_to_workers(state):
    """运行时才知道有多少任务——动态扇出"""
    return [
        Send("worker_node", {"task": task})
        for task in state["tasks"]  # tasks 数量在运行时确定
    ]

builder.add_conditional_edges("planner", route_to_workers)

# 所有 worker 完成后,结果通过 Reducer (operator.add) 合并
# 然后继续执行后续节点
Send API 执行流程 Planner Node │ ├── Send("worker", {task: "研究AI"}) ├── Send("worker", {task: "研究Web3"}) └── Send("worker", {task: "研究IoT"}) │ ▼ (并行执行 3 个 worker) ┌────────┬────────┬────────┐ │Worker 1│Worker 2│Worker 3│ └───┬────┴───┬────┴───┬────┘ │ │ │ ▼ ▼ ▼ Reducer (operator.add) 合并 3 个结果 │ ▼ Synthesizer Node

8.2 AutoGen 并行:异步 Task + Team

# AutoGen: 异步任务 (CrewAI 也有类似设计)
# 多个 Team 可以并发运行
import asyncio

results = await asyncio.gather(
    research_team.run(task="研究市场趋势"),
    coding_team.run(task="开发原型"),
    design_team.run(task="设计 UI"),
)
# 三个 Team 完全独立运行

8.3 GPT Researcher:并行子话题研究

GPT Researcher 的多 Agent 模式用 LangGraph 实现并行研究:

# GPT Researcher: ChiefEditorAgent 编排
# 1. Editor 将查询拆分为子话题
# 2. 每个子话题分配给独立的 Researcher Agent
# 3. Researcher 并行搜索、抓取、摘要
# 4. Reviewer 检查质量 → Reviser 修订
# 5. 最终汇总为完整报告
并行的关键Reducer——并行执行的难点不是"启动",而是"合并"。LangGraph 的 Reducer 模型(add_messagesoperator.add)是解决并行写入冲突最优雅的方案。没有 Reducer,你只能用全局锁或串行化,失去了并行的意义。

9 终止与收敛:何时结束协作?

多 Agent 协作最容易被忽视的问题:怎么知道做完了?

终止策略实现优势风险
最大轮次AutoGen max_turns简单可靠可能过早终止
消息内容检测AutoGen TextMentionTermination精确依赖 Agent 输出格式
外部判断函数AutoGen FunctionalTermination灵活需要手写逻辑
图到达 ENDLangGraph END 节点确定性需要正确建模
所有 Task 完成CrewAI Task 输出检查语义完整依赖 Task 定义
Stall 检测 + 重新规划AutoGen MagenticOne自适应可能无限循环
# AutoGen: 组合终止条件
from autogen_agentchat.conditions import (
    TextMentionTermination,
    MaxMessageTermination,
    TimeoutTermination,
    FunctionalTermination,
)

termination = TextMentionTermination("TERMINATE") | MaxMessageTermination(20)
# 任一条件满足即终止

# MagenticOne: stall 检测
# 连续 max_stalls 轮没有进展 → 重新规划
# 重新规划也 stall → 放弃
反模式:没有终止条件的多 Agent 循环。Agent 互相 Handoff 却没人说"我做完了",导致无限循环。永远设置最大轮次作为保底。

10 实战选型指南:场景 → 框架映射

场景推荐框架编排模式原因
软件开发流水线 MetaGPT SOP Pipeline 流程固定、角色明确、需要质量保证
客服/任务路由 LangGraph Supervisor 需要中心决策 + 条件路由 + 人机协作
自由协作/探索 AutoGen Swarm Agent 自主路由,适合开放式任务
研究分析 LangGraph Supervisor + Send 并行子话题 + 质量检查 + 可回滚
角色扮演/对话 CAMEL RolePlaying 学术出身,角色提示词自动生成
快速原型 CrewAI Sequential/Hierarchical 最简单的 API,3 行代码跑起来
复杂工作流 LangGraph StateGraph + Checkpoint 最灵活的图编排 + 状态持久化
运维/自动化 OpenClaw Sub-Agent + TaskFlow 进程隔离、安全策略、多平台

10.1 实战代码:用 LangGraph 构建研究团队

# 完整示例: LangGraph Supervisor + Send 并行研究
from langgraph.graph import StateGraph, START, END
from langgraph.types import Send, Command
from langgraph.checkpoint.sqlite import SqliteSaver
from typing import Annotated
import operator

class State(TypedDict):
    query: str
    subtopics: list[str]
    research_results: Annotated[list, operator.add]  # Reducer: 并行合并
    final_report: str

def supervisor(state):
    """分解查询为子话题"""
    subtopics = llm.invoke(f"将以下查询分解为3个子话题: {state['query']}")
    return {"subtopics": subtopics}

def route_to_researchers(state):
    """动态并行扇出"""
    return [Send("researcher", {"subtopic": t}) for t in state["subtopics"]]

def researcher(state):
    """单个子话题研究"""
    result = llm.invoke(f"研究: {state['subtopic']}")
    return {"research_results": [result]}

def synthesizer(state):
    """汇总所有研究结果"""
    report = llm.invoke(f"基于以下研究结果生成报告: {state['research_results']}")
    return {"final_report": report}

builder = StateGraph(State)
builder.add_node("supervisor", supervisor)
builder.add_node("researcher", researcher)
builder.add_node("synthesizer", synthesizer)

builder.add_edge(START, "supervisor")
builder.add_conditional_edges("supervisor", route_to_researchers)
builder.add_edge("researcher", "synthesizer")
builder.add_edge("synthesizer", END)

graph = builder.compile(checkpointer=SqliteSaver.from_conn_string("research.db"))
result = graph.invoke({"query": "2026年AI Agent技术趋势"})

10.2 实战代码:用 AutoGen Swarm 构建动态协作

# 完整示例: AutoGen Swarm 动态切换
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.teams import Swarm
from autogen_agentchat.conditions import MaxMessageTermination, TextMentionTermination
from autogen_ext.models.openai import OpenAIChatCompletionClient

model_client = OpenAIChatCompletionClient(model="gpt-4")

# 定义 Agent + Handoff
researcher = AssistantAgent(
    "researcher",
    model_client=model_client,
    tools=[search_tool, scrape_tool],
    handoffs=["writer", "reviewer"],  # 可切换到 writer 或 reviewer
)

writer = AssistantAgent(
    "writer",
    model_client=model_client,
    handoffs=["reviewer"],  # 写完给 reviewer 审
)

reviewer = AssistantAgent(
    "reviewer",
    model_client=model_client,
    handoffs=["writer", "researcher"],  # 可打回给 writer 或补充研究
)

# Swarm 编排
team = Swarm(
    [researcher, writer, reviewer],
    termination_condition=TextMentionTermination("APPROVED") | MaxMessageTermination(15),
)

result = await team.run(task="研究 AI Agent 框架对比,写一篇 2000 字的综述文章")

11 反模式与常见坑

反模式 1:Agent 过多 5 个以上 Agent 协调成本指数增长。MetaGPT 用 5 个角色(PM/Architect/PM/Eng/QA)是有原因的——这是人脑能同时跟踪的极限。超过 5 个 Agent,用嵌套 Team 拆分。
反模式 2:所有 Agent 共享所有消息 AutoGen GroupChat 默认所有 Agent 看到所有消息。Agent 数量多时,上下文膨胀、噪音增大、成本飙升。MetaGPT 的私有 Buffer + Watch 过滤是更好的模型。
反模式 3:没有终止条件的循环 Swarm 模式下 Agent 互相 Handoff,没人说"做完了"。必须设置 MaxMessageTerminationTextMentionTermination 作为保底。
反模式 4:同步等待异步结果 CrewAI 的 async_execution=True 允许 Task 并行,但同步 Task 会阻塞等待。如果 Task A 依赖 Task B 的输出但忘了声明 context=[task_b],A 会拿到空输入。
反模式 5:Handoff 上下文丢失 AutoGen Swarm 的 HandoffMessage.context 默认只包含工具调用+结果,不含完整对话历史。新 Agent 可能缺乏关键上下文。解决方案:在 Handoff 时显式传递摘要。
反模式 6:忽略 LLM 调用成本 5 个 Agent 的 Supervisor 编排,每轮 5 次 LLM 调用(1 个 Supervisor + 4 个 Worker)。10 轮就是 50 次调用。成本 = 50 × 单次成本。永远计算你的总调用次数。

12 决策树:我该用多 Agent 吗?

多 Agent 决策树 你的任务能否被一个 Agent 在合理 token 内完成? ├── → 用单 Agent,不要过度工程化 └── 不能 → 继续判断 ↓ 任务是否有明确的角色分工? ├── → 角色分工是否固定? │ ├── 固定 → MetaGPT SOPCrewAI Sequential │ └── 动态 → AutoGen SelectorGroupChatLangGraph Supervisor └── 没有 → 继续判断 ↓ 是否需要并行处理子任务? ├── 需要 → 子任务数量是否已知? │ ├── 已知 → LangGraph 并行节点AutoGen 多 Team │ └── 未知 → LangGraph Send API(唯一选择) └── 不需要 → 继续判断 ↓ 是否需要状态回滚/时间旅行? ├── 需要LangGraph + Checkpointer(唯一选择) └── 不需要 → 继续判断 ↓ 是否需要 Agent 自主路由? ├── 需要AutoGen Swarm (Handoff) └── 不需要 → 用最简单的方案:AutoGen RoundRobinCrewAI
终极原则能用单 Agent 就不要用多 Agent。多 Agent 的协调成本(通信开销、上下文丢失、调试复杂度、LLM 调用成本)是真实存在的。只在单 Agent 真的不够时才引入多 Agent。

🔗 相关链接

生成时间:2026-05-17 | 数据来源:AutoGen v0.5, LangGraph v0.3, CrewAI v0.8, MetaGPT v0.8, CAMEL v0.2, GPT Researcher, OpenClaw 源码分析