2026 多智能体框架横向测评:LangGraph / AutoGen / CrewAI / MetaGPT / OpenAI Agents SDK / Google ADK,到底选谁?
写在前面:上一篇《从0到1手搓生产级 AI Agent:LangGraph 1.2 + LangChain 1.3 保姆级实战》最后留了一节"多 Agent 协作",评论区问得最多的一句是——“到底该选哪个框架?”
这篇就把这个问题一次性说透。
本文基于 2026 年 8 月各框架的最新稳定版,六个主流选手中的五个全部装到本地实跑(MetaGPT 依赖过重,改为源码级核对),同一个业务场景(舆情简报:研究员 → 分析师 → 审校)用六种框架各写一遍,每段代码的 API 都在对应版本上实际跑过验证(MetaGPT 一节为源码级核对,见文中说明),包括那些官方文档还没来得及更新的破坏性变更(比如 Google ADK 2.7 已经把 SequentialAgent 标记为废弃了,你现在网上搜到的教程 100% 是过时的)。
全文约 1.8 万字(含代码),建议先收藏再看。看完你会拿到:一张选型决策树、一份六维评分表、六份可直接改造的骨架代码,以及 14 条只有踩过才知道的坑。
目录
- 一、先泼盆冷水:80% 的场景不该上多 Agent
- 二、六种协作拓扑:框架之上的底层模式
- 三、参赛选手与版本锁定(2026.08 实测)
- 四、逐个拆解 + 最小可跑骨架
- 五、六维横向评分表
- 六、多 Agent 的成本账怎么算
- 七、可观测性与调试
- 八、选型决策树
- 九、生产踩坑清单(14 条)
- 结语
一、先泼盆冷水:80% 的场景不该上多 Agent
先说结论:多角色不是能力放大器,是复杂度放大器。 它能解决的问题只有三个,带来的新问题至少有四个。
1.1 多角色真正解决的三个问题
| 真问题 | 为什么单 Agent 解决不了 |
|---|---|
| 上下文污染 | 一个 Agent 塞了 40 个工具 + 检索结果 + 历史对话,模型开始"选错工具"。拆成 3 个角色,每个角色只看自己那 10 个工具 |
| 能力/权限专精 | 写代码的 Agent 需要沙箱执行权限,客服 Agent 绝对不能有。角色即权限边界 |
| 可并行的子任务 | 同时查 5 个数据源,串行 25 秒,并行 6 秒 |
1.2 多角色带来的四个新问题
| 新问题 | 具体表现 |
|---|---|
| Token 成本非线性上涨 | Supervisor 模式下,主管每次转交都要重读一遍上下文。3 个角色轮一圈,token 消耗通常是单 Agent 的 2.5~4 倍 |
| 延迟叠加 | 每次角色切换 = 一次额外的模型往返。5 次切换 = 多等 8~15 秒 |
| 错误放大 | 研究员编了一条假数据,分析师会当真、审校会替它润色。单点幻觉会被下游合法化 |
| 调试难度指数上升 | 单 Agent 出错看一条 trace;多 Agent 出错要看"谁在第几轮把话说歪了" |
1.3 一张表判断你到底该不该上
| 你的场景 | 建议 |
|---|---|
| 工具 < 15 个,流程单一 | 别上多 Agent,用单 Agent + 好的工具描述 |
| 流程固定、步骤明确(先 A 后 B 再 C) | 别上多 Agent,用工作流编排(LangGraph StateGraph / ADK Workflow),把 LLM 当节点 |
| 步骤之间有明确的"能力鸿沟"(检索 vs 写代码 vs 审核) | 上 Supervisor |
| 需要真并行(多数据源、多语种、多方案) | 上 Parallel / Fan-out |
| 需要专家之间自由讨论、互相纠错 | 上 GroupChat / Debate(但先做好烧钱准备) |
| 任务规模不可预知、需要动态拆解 | 上 Hierarchical / Planner(最难驯服,慎用) |
一个经验法则:能用有向图写死的,就别交给 LLM 去决定谁下一个说话。 每多一次"让模型自己决定",就多一份不可控。
二、六种协作拓扑:框架之上的底层模式
框架会过时,拓扑不会。先把这六种模式搞清楚,再看框架就是"这个框架把哪几种模式做成了一等公民"。
2.1 Supervisor(主管制)
+------------+
| supervisor |
**+------------+...
***** . .....
*** . ...
*** . ...
+---------+ +------------+ +---------+
| analyst | | researcher | | __end__ |
+---------+ +------------+ +---------+
(上图是 langgraph-supervisor 编译后 get_graph().draw_ascii() 的真实输出)
- 控制流:所有子 Agent 只跟主管说话,彼此不通信。主管决定下一个交给谁、什么时候结束
- 优点:控制点唯一,好审计、好加限流、好做人工审批
- 缺点:主管是单点瓶颈,且每轮都要重读全量上下文 → 贵
- 适用:客服路由、多领域问答、任务分派
2.2 Sequential Pipeline(流水线)
START → researcher → analyst → reviewer → END
- 控制流:写死的有向链,谁都不能"决定"下一个是谁
- 优点:最便宜、最可预测、最好调试。90% 声称需要多 Agent 的场景其实只需要这个
- 缺点:不能回退、不能动态跳步
- 适用:内容生产、数据清洗、报告生成、代码 review 流水线
2.3 Swarm / Handoff(对等转交)
researcher ⇄ analyst
↕ ↕
writer ⇄ reviewer
- 控制流:没有主管,每个 Agent 手里有若干
handoff工具,谁接手谁就是"当前活跃 Agent",并且记住上次是谁在说话 - 优点:省掉主管那一层的 token;交互式场景(多轮客服)体验最自然
- 缺点:容易出现 A→B→A→B 的乒乓死循环,必须配轮次上限
- 适用:多轮对话式客服、分诊(triage)
2.4 GroupChat / Selector(群聊制)
[researcher, analyst, critic, reviewer] ← selector(LLM) 每轮挑一个发言
- 控制流:一个 selector(可以是 LLM,也可以是规则函数)在每轮从参与者里挑下一个发言人,所有人共享同一份会话历史
- 优点:涌现式协作,适合开放式问题
- 缺点:全员共享上下文 = 上下文爆炸;轮数不收敛就是烧钱机器
- 适用:方案头脑风暴、复杂问题拆解
2.5 Debate / Critic(辩论与批判)
proposer → critic → proposer(修订) → critic → ... → judge
- 控制流:生成者与批判者交替,最后由裁判定稿
- 优点:对抗性验证是目前最有效的降幻觉手段之一,尤其适合有客观对错的任务
- 缺点:成本至少 ×2,且 critic 提示词写不好就会变成"彩虹屁机器"
- 适用:代码 review、事实核查、合规审查
写 critic 的提示词有个诀窍:默认它必须找出问题。“请审阅"会得到"写得很好”;"请找出至少 3 处事实性风险,找不到就说明你没认真看"才会得到有用的输出。
2.6 Hierarchical(分层 / 团队的团队)
planner
/ | \
team_A team_B team_C ← 每个 team 内部又是一个 supervisor
- 控制流:上层规划器拆任务,下层每个团队自己是一个完整的多 Agent 系统
- 优点:能扛住真正复杂的长任务(MetaGPT 的软件公司就是这个形态)
- 缺点:最难调试、最容易失控,成本不可预估
- 适用:自动化软件开发、长文档生成、深度研究
三、参赛选手与版本锁定(2026.08 实测)
以下版本号全部由 pip index versions <pkg> 在 2026-08-18 实测得到,不是抄的文档:
| 框架 | 实测最新稳定版 | 出身 | 核心心智模型 |
|---|---|---|---|
| LangGraph | langgraph==1.2.11langgraph-supervisor==0.0.31langgraph-swarm==0.1.0 | LangChain | 状态机 / 有向图 |
| AutoGen (AgentChat) | autogen-agentchat==0.7.5autogen-core==0.7.5 | Microsoft | 异步消息 + 群聊 Team |
| CrewAI | crewai==1.15.16 | CrewAI Inc. | 角色 + 任务 + Crew(拟人化) |
| MetaGPT | metagpt==0.8.2 | FoundationAgents | SOP 驱动的"软件公司" |
| OpenAI Agents SDK | openai-agents==0.21.1 | OpenAI | Agent + Handoff + Guardrail |
| Google ADK | google-adk==2.7.1 | Agent 树 + Workflow 图 |
顺带记下几个相关生态版本,写 requirements 时用得上:
langchain==1.3.15
langchain-core==1.5.6
langgraph-checkpoint-postgres==3.1.2
ag2==1.0.2 # AutoGen 的社区分支,API 与 0.2.x 更接近
agno==2.9.0
camel-ai==0.2.90
semantic-kernel==1.44.1
claude-agent-sdk==0.2.139
注意
metagpt==0.8.2:这是当前 PyPI 上的最新稳定版,版本号已经停在 0.8.x 相当长一段时间了。选型时请把"社区活跃度"和"你能不能自己维护 fork"一并算进去。
四、逐个拆解 + 最小可跑骨架
统一业务场景:给定一个话题,研究员取材 → 分析师成稿 → 审校把关,输出 300 字简报。
统一模型:DeepSeek(OpenAI 兼容接口),换成通义/Kimi/智谱只改 base_url 和 model 即可。
4.1 LangGraph 1.2 —— 工程师的框架
装:
pip install "langgraph==1.2.11" "langchain==1.3.15" "langchain-openai" \
"langgraph-supervisor==0.0.31" "langgraph-swarm==0.1.0"
Supervisor 骨架:
import os
from langchain.agents import create_agent
from langchain.chat_models import init_chat_model
from langgraph_supervisor import create_supervisor
from langgraph.checkpoint.memory import InMemorySaver
llm = init_chat_model(
"deepseek-chat", model_provider="openai", temperature=0,
base_url="https://api.deepseek.com",
api_key=os.environ["DEEPSEEK_API_KEY"],
)
def web_search(query: str) -> str:
"""按关键词检索最近 7 天的公开资讯,返回标题+摘要列表。"""
return f"[mock] {query} 的检索结果"
researcher = create_agent(
model=llm, tools=[web_search],
system_prompt="你是资料研究员,只负责检索与罗列事实,不做结论。",
name="researcher", # ← 必填!见下方踩坑
)
analyst = create_agent(
model=llm, tools=[],
system_prompt="你是分析师,基于研究员给出的事实做归因与结论,不允许自行编造数据。",
name="analyst",
)
supervisor = create_supervisor(
agents=[researcher, analyst],
model=llm,
prompt="你是主管。先让 researcher 取材,再让 analyst 出结论,最后你汇总成 300 字简报。",
output_mode="last_message", # 只把子 Agent 的最后一条消息回传给主管
add_handoff_back_messages=True,
).compile(checkpointer=InMemorySaver())
for chunk in supervisor.stream(
{"messages": [{"role": "user", "content": "分析一下 2026 年多智能体框架的竞争格局"}]},
config={"configurable": {"thread_id": "t-1"}},
):
print(chunk)
踩坑 ①(我实测踩到的第一个):子 Agent 不给 name 会直接抛异常:
ValueError: Please specify a name when you create your agent, either via
`create_react_agent(..., name=agent_name)` or via `graph.compile(name=name)`.
踩坑 ②:output_mode 有两个值,直接决定你的账单:
| 取值 | 行为 | 后果 |
|---|---|---|
"last_message"(默认) | 只把子 Agent 的最后一条消息回传主管 | 便宜,但主管看不到子 Agent 的中间推理 |
"full_history" | 子 Agent 的完整消息历史全部并入主图 | 主管信息全,但 token 消耗成倍上涨 |
Swarm 骨架(无主管,对等转交):
from langgraph_swarm import create_swarm, create_handoff_tool
to_analyst = create_handoff_tool(agent_name="analyst",
description="事实已收集完毕,转交分析师做结论")
to_researcher = create_handoff_tool(agent_name="researcher",
description="资料不足,转回研究员补充检索")
researcher = create_agent(llm, [web_search, to_analyst],
system_prompt="你是研究员。", name="researcher")
analyst = create_agent(llm, [to_researcher],
system_prompt="你是分析师。", name="analyst")
app = create_swarm(
[researcher, analyst],
default_active_agent="researcher",
).compile(checkpointer=InMemorySaver())
Swarm 编译出来的图长这样(真实 draw_ascii() 输出,注意它是双向的,这正是乒乓死循环的来源):
+-----------+
| __start__ |
+-----------+
... ..
. ..
.. ..
+---------+ .
| analyst | ..
+---------+ ..
... ..
. ..
.. .
+------------+
| researcher |
+------------+
评价:LangGraph 的心智模型是"状态机",不是"团队"。它不会替你决定任何事,你要的一切控制力(中断、回滚、时间旅行、持久化)它都给,代价是你得自己写图。langgraph-supervisor 和 langgraph-swarm 只是两个薄封装,看一眼源码就能自己实现——这其实是优点。
4.2 AutoGen AgentChat 0.7.5 —— 群聊拓扑最全
装:
pip install "autogen-agentchat==0.7.5" "autogen-ext[openai]==0.7.5"
import asyncio, os
from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.teams import (
SelectorGroupChat, RoundRobinGroupChat, Swarm,
GraphFlow, DiGraphBuilder, MagenticOneGroupChat,
)
from autogen_agentchat.conditions import TextMentionTermination, MaxMessageTermination
from autogen_agentchat.ui import Console
from autogen_ext.models.openai import OpenAIChatCompletionClient
client = OpenAIChatCompletionClient(
model="deepseek-chat",
base_url="https://api.deepseek.com/v1",
api_key=os.environ["DEEPSEEK_API_KEY"],
# ↓ 非 OpenAI 官方模型必须手动声明能力,否则启动即报错
model_info={"vision": False, "function_calling": True, "json_output": True,
"family": "unknown", "structured_output": True},
)
def web_search(query: str) -> str:
"""检索公开资讯。"""
return f"[mock] {query}"
researcher = AssistantAgent("researcher", model_client=client, tools=[web_search],
description="负责检索事实", # ← selector 靠它选人
system_message="你是研究员,只罗列事实。")
analyst = AssistantAgent("analyst", model_client=client,
description="负责归因分析",
system_message="你是分析师。")
reviewer = AssistantAgent("reviewer", model_client=client,
description="负责审校,通过就回复 APPROVE",
system_message="你是审校。通过则只回复 APPROVE。")
# 终止条件可以用 | 组合,这是 AutoGen 设计得最舒服的地方之一
term = TextMentionTermination("APPROVE") | MaxMessageTermination(12)
team = SelectorGroupChat(
[researcher, analyst, reviewer],
model_client=client,
termination_condition=term,
allow_repeated_speaker=False, # 防止同一个人连说两轮
)
asyncio.run(Console(team.run_stream(task="分析 2026 年多智能体框架竞争格局")))
AutoGen 0.7.x 的五种 Team,一次看全:
| Team 类 | 拓扑 | 什么时候用 |
|---|---|---|
RoundRobinGroupChat | 轮流发言 | 最省钱、最可预测;固定流程首选 |
SelectorGroupChat | LLM 选下一个发言人 | 开放式协作;注意 selector_prompt 可自定义 |
Swarm | Handoff 转交 | 对话式分诊 |
GraphFlow | 有向图,支持条件边、并行、循环 | 想要 LangGraph 那种控制力但不想离开 AutoGen 时用 |
MagenticOneGroupChat | 带 Ledger 的规划型群聊 | 复杂、开放、需要动态重规划的任务 |
GraphFlow 是 0.5+ 之后 AutoGen 补齐的短板,用 DiGraphBuilder 声明:
b = DiGraphBuilder()
b.add_node(researcher).add_node(analyst).add_node(reviewer)
b.add_edge(researcher, analyst).add_edge(analyst, reviewer)
flow = GraphFlow(participants=b.get_participants(),
graph=b.build(),
termination_condition=term)
踩坑 ③:AutoGen 全异步。AssistantAgent 的工具可以是同步函数(框架会包装),但 team.run() / run_stream() 必须 await。在 Jupyter 里直接 await,在脚本里 asyncio.run()。
踩坑 ④:description 字段不是给人看的注释,SelectorGroupChat 的选人提示词里塞的就是它。写得含糊,选人就乱。
评价:拓扑最全,异步模型设计得干净,微软背书。缺点是 0.2 → 0.4 那次重写导致网上一半教程完全不能用(autogen.ConversableAgent、initialize_agent 那一套是老 API),搜资料时要格外注意版本。想留在老 API 的可以看 ag2==1.0.2 这个社区分支。
4.3 CrewAI 1.15.16 —— 上手最快,拟人化最强
装:
pip install "crewai==1.15.16"
import os
from crewai import Agent, Task, Crew, Process, LLM
from crewai.tools import tool
llm = LLM(model="deepseek/deepseek-chat",
api_key=os.environ["DEEPSEEK_API_KEY"],
base_url="https://api.deepseek.com", temperature=0)
@tool("web_search")
def web_search(query: str) -> str:
"""按关键词检索公开资讯。"""
return f"[mock] {query}"
researcher = Agent(role="资料研究员", goal="把与 {topic} 相关的事实找全",
backstory="十年情报分析经验,只信一手来源。",
tools=[web_search], llm=llm, allow_delegation=False, verbose=True)
analyst = Agent(role="行业分析师", goal="基于事实给出可执行结论",
backstory="常年写券商研报。", llm=llm, allow_delegation=False, verbose=True)
t1 = Task(description="检索 {topic} 最近 7 天的公开进展,列 5 条以上事实。",
expected_output="带来源链接的事实清单(markdown 列表)", agent=researcher)
t2 = Task(description="基于上一步事实撰写 300 字简报。",
expected_output="300 字中文简报", agent=analyst,
context=[t1], # ← 显式声明依赖,别指望它自己猜
output_file="brief.md")
crew = Crew(agents=[researcher, analyst], tasks=[t1, t2],
process=Process.sequential, verbose=True)
print(crew.kickoff(inputs={"topic": "多智能体框架"}))
两种 Process:
Process.sequential:按tasks顺序执行,便宜、可预测,生产上 90% 用这个Process.hierarchical:必须额外提供manager_llm或manager_agent,由它动态派活
manager = Agent(role="项目经理", goal="拆解任务并派给合适的人",
backstory="十年 PM 经验", llm=llm)
crew = Crew(agents=[researcher, analyst], tasks=[t],
process=Process.hierarchical, manager_agent=manager)
CrewAI Flow —— 别忽略它。Crew 适合"一群人干一件事",Flow 适合"把多个 Crew 和普通函数串成一条有状态的业务流",带 @start / @listen / @router 装饰器和 Pydantic 状态:
from pydantic import BaseModel
from crewai.flow.flow import Flow, start, listen, router
class BriefState(BaseModel):
topic: str = ""
brief: str = ""
score: int = 0
class BriefFlow(Flow[BriefState]):
@start()
def collect(self):
self.state.brief = research_crew.kickoff(inputs={"topic": self.state.topic}).raw
return self.state.brief
@router(collect)
def gate(self):
return "pass" if self.state.score >= 80 else "revise"
@listen("revise")
def do_revise(self): # ← 方法名不能叫 revise!见踩坑 ⑤
...
@listen("pass")
def publish(self):
...
BriefFlow().kickoff(inputs={"topic": "多智能体框架"})
踩坑 ⑤(实测踩到):@listen("revise") 装饰的方法如果自己也叫 revise,CrewAI 1.x 会在类定义阶段就用 Pydantic 校验拦下来:
pydantic_core._pydantic_core.ValidationError: 1 validation error for BriefFlow
Value error, Invalid flow definition for BriefFlow: methods.revise.listen listen
condition 'revise' references the handler name 'revise'. A listener triggered by
its own completion creates an infinite loop.
这个报错信息写得很好,但只有跑起来才知道,文档里没写。
踩坑 ⑥(合规重点):CrewAI 默认开启遥测上报,会往 telemetry.crewai.com:4319 发 span。内网/离线/金融合规环境会看到一堆连接超时日志,更重要的是——你可能不希望任务元数据出网。三个环境变量任选其一关掉:
export CREWAI_DISABLE_TELEMETRY=true
# 或
export OTEL_SDK_DISABLED=true
# 或
export CREWAI_DISABLE_TRACKING=true
评价:role / goal / backstory 这套拟人化 API 让非工程背景的人也能上手,从 0 到 Demo 是六个里最快的。代价是抽象层很厚,想插一个自定义的重试策略或者改一下上下文拼接逻辑,你得往框架里钻。做 PoC 和内部工具首选;做需要精细控制的核心链路,会有点憋屈。
4.4 MetaGPT 0.8.2 —— SOP 驱动的"软件公司"
MetaGPT 的定位和上面几个不太一样:它不是给你搭多 Agent 系统的通用框架,它本身就是一个已经搭好的多 Agent 系统——一个模拟软件公司。核心公式是 Code = SOP(Team)。
from metagpt.software_company import generate_repo
repo = generate_repo(
"写一个命令行版的 2048 小游戏",
investment=3.0, # 预算上限(美元),花超了自动停
n_round=5,
)
print(repo)
内部等价于:
import asyncio
from metagpt.team import Team
from metagpt.roles import ProductManager, Architect, ProjectManager, Engineer, QaEngineer
company = Team()
company.hire([ProductManager(), Architect(), ProjectManager(),
Engineer(n_borg=5, use_code_review=True)])
company.invest(investment=3.0)
company.run_project("写一个命令行版的 2048 小游戏")
asyncio.run(company.run(n_round=5)) # Team.run 是协程
说明:这一节的代码是我对照
metagpt==0.8.2的 wheel 源码逐行核对的(metagpt/software_company.py、metagpt/team.py、metagpt/roles/__init__.py),而不是像前面几节那样在本地实跑——MetaGPT 的完整依赖链较重,装一次代价不小。
三个设计值得单独学,就算你不用 MetaGPT 也可以抄:
invest()预算熔断:把美元预算作为一等公民写进 API,超支直接抛异常。这是我见过对"Agent 烧钱"最直接的解法,其他框架都需要你自己实现- SOP 固化:角色之间传递的不是自由文本,而是 PRD、设计文档、任务清单这些结构化产物——用文档格式约束协作,比用提示词约束有效得多
Role的_observe / _think / _act三段式:把"看到什么消息 → 决定做什么 → 执行"拆开,是很好的 Agent 内核抽象
评价:学思想 > 用代码。当前 PyPI 最新稳定版停在 0.8.2,把它放进生产链路前,请先确认团队有能力自己维护。但它的 SOP 思路和预算熔断设计,值得每个做多 Agent 的人读一遍源码。
4.5 OpenAI Agents SDK 0.21.1 —— 极简主义者的选择
装:
pip install "openai-agents==0.21.1"
import os
from agents import (Agent, Runner, handoff, function_tool,
OpenAIChatCompletionsModel, set_tracing_disabled)
from openai import AsyncOpenAI
client = AsyncOpenAI(base_url="https://api.deepseek.com/v1",
api_key=os.environ["DEEPSEEK_API_KEY"])
set_tracing_disabled(True) # 用非 OpenAI 模型时,先关掉 OpenAI 的 trace 上报
model = OpenAIChatCompletionsModel(model="deepseek-chat", openai_client=client)
@function_tool
def web_search(query: str) -> str:
"""检索公开资讯。"""
return f"[mock] {query}"
analyst = Agent(name="analyst", model=model,
handoff_description="负责基于事实做归因与结论", # ← 给别人看的"名片"
instructions="你是分析师,只基于给定事实作答。")
researcher = Agent(name="researcher", model=model, tools=[web_search],
handoff_description="负责检索事实",
instructions="你是研究员,取完材后交给 analyst。",
handoffs=[handoff(analyst)])
# 脚本里用 run_sync;异步环境(FastAPI / Jupyter)里用 await Runner.run(...)
result = Runner.run_sync(researcher, "分析 2026 年多智能体框架竞争格局", max_turns=10)
print(result.final_output)
这个 SDK 的核心洞察是:多 Agent 只有两种组合方式,它把两种都做成了一等公民。
| 方式 | 语义 | 用法 |
|---|---|---|
| Handoff | 转移控制权,之后由新 Agent 主导对话 | handoffs=[handoff(other)] |
| Agent-as-tool | 不转移控制权,把子 Agent 当成一个函数调用,拿到返回值继续 | other.as_tool(...) |
translator = Agent(name="translator", model=model, instructions="把输入翻译成英文。")
editor = Agent(name="editor", model=model, instructions="你是主编。",
tools=[translator.as_tool(
tool_name="translate_to_en",
tool_description="把中文文本翻译为英文")])
这个区分极其重要,是很多人多 Agent 设计混乱的根源:需要"派个活拿结果回来"就用 agent-as-tool,需要"这事以后归你管了"才用 handoff。大部分人误用了 handoff。
另外它内置了 input_guardrails / output_guardrails——把护栏做成框架原语而不是让你手写中间件,这一点很务实:
from agents import InputGuardrail, GuardrailFunctionOutput
async def no_pii(ctx, agent, input_text):
hit = "身份证" in str(input_text)
return GuardrailFunctionOutput(output_info={"hit": hit}, tripwire_triggered=hit)
agent = Agent(name="x", model=model, instructions="...",
input_guardrails=[InputGuardrail(guardrail_function=no_pii)])
评价:API 面最小,一天能读完全部源码,Runner.run 的 max_turns 默认 10 也很克制。缺点是没有内置持久化/检查点(会话状态要自己接 Session/外部存储),复杂图编排能力不如 LangGraph。中小型 Agent 应用、或者你本来就重度使用 OpenAI 生态,这是性价比最高的选择。
4.6 Google ADK 2.7.1 —— 变化最快,也是本文最大的"独家"
装:
pip install "google-adk==2.7.1"
ADK 原本的多角色原语是 SequentialAgent / ParallelAgent / LoopAgent 三件套,网上现在能搜到的中文教程 100% 是这一套。但在 2.7.1 上跑一下,你会看到:
DeprecationWarning: SequentialAgent is deprecated in favor of Workflow and will be
removed in a future version. Workflow cannot yet be used as an LlmAgent sub-agent.
也就是说,这三个类已经进入废弃通道,新的一等公民是 google.adk.workflow.Workflow——一个真正的图编排原语。新写法:
from google.adk.agents import LlmAgent
from google.adk.workflow import Workflow, START
researcher = LlmAgent(name="researcher", model="gemini-2.5-flash",
instruction="你是研究员,只罗列事实。",
output_key="facts") # 写进 session state
analyst = LlmAgent(name="analyst", model="gemini-2.5-flash",
instruction="基于 {facts} 写 300 字简报。", # 直接插值读 state
output_key="brief")
reviewer = LlmAgent(name="reviewer", model="gemini-2.5-flash",
instruction="审校 {brief},通过回复 APPROVE。")
wf = Workflow(
name="brief_workflow",
edges=[(START, researcher, analyst, reviewer)], # 链式糖:一条元组 = 一条链
max_concurrency=4,
)
并行 fan-out + join 也是一条边的事:
cn = LlmAgent(name="cn_src", model="gemini-2.5-flash", instruction="查中文源", output_key="cn")
en = LlmAgent(name="en_src", model="gemini-2.5-flash", instruction="查英文源", output_key="en")
merger = LlmAgent(name="merger", model="gemini-2.5-flash",
instruction="合并 {cn} 与 {en},去重后输出。", output_key="brief")
wf = Workflow(
name="fanout_wf",
edges=[(START, (cn, en)), # 元组 = 扇出,两个节点并行触发
(cn, merger), (en, merger)],
max_concurrency=2,
)
Workflow 还带了几个 LangGraph 用户会觉得眼熟的东西:Edge(route=...) 条件边、JoinNode 汇合节点、FunctionNode(普通 Python 函数也能当节点)、RetryConfig 节点级重试、timeout 节点级超时、rerun_on_resume 恢复语义。
踩坑 ⑦:Workflow 目前还不能作为 LlmAgent 的 sub_agent 使用(废弃警告里明写了)。所以如果你的架构是"一个主 LlmAgent 下挂若干工作流",现在还迁不动,得再等等。
踩坑 ⑧:ADK 的角色间传值靠 output_key 写入 session state + {key} 模板插值读取,不是靠消息历史。这和其他五个框架的心智模型完全不同,迁移时最容易翻车的就是这里。
评价:ADK 是六个里演进最激进的,好处是设计在快速收敛(从"三个特化 Agent 类"收敛到"一个通用图",方向明显对了),坏处是你今天写的代码半年后可能要改。绑定 Gemini 生态、且能接受跟版本的团队可以上;求稳的先观望。
五、六维横向评分表
评分标准(1~5 分,5 分最好),基于 2026.08 实测版本,带主观判断,欢迎评论区拍砖:
| 维度 | LangGraph | AutoGen | CrewAI | MetaGPT | OpenAI SDK | Google ADK |
|---|---|---|---|---|---|---|
| 上手速度 | 2 | 3 | 5 | 4 | 5 | 3 |
| 控制粒度 | 5 | 4 | 2 | 2 | 3 | 4 |
| 拓扑丰富度 | 4 | 5 | 3 | 2 | 3 | 4 |
| 持久化/断点续跑 | 5 | 3 | 3 | 3 | 2 | 4 |
| 可观测性 | 5(LangSmith) | 4 | 3 | 2 | 4(内置 trace) | 4(Cloud Trace) |
| 人工介入 HITL | 5 | 4 | 3 | 1 | 3 | 4 |
| 生产成熟度 | 5 | 4 | 4 | 2 | 4 | 3 |
| 文档与版本稳定性 | 4 | 3 | 4 | 2 | 5 | 2 |
| 模型中立性 | 5 | 5 | 5 | 4 | 3 | 3 |
一句话画像:
- LangGraph:要控制力就选它,代价是你得懂图
- AutoGen:拓扑最全,异步设计最干净,注意版本断层
- CrewAI:Demo 之王,业务人员也能改,深度定制会憋屈
- MetaGPT:学 SOP 思想和预算熔断,别急着上生产
- OpenAI Agents SDK:最小可用美学,handoff / agent-as-tool 的区分值得所有人抄
- Google ADK:设计在快速收敛,但请做好跟版本的准备
六、多 Agent 的成本账怎么算
这是最多人翻车的地方。给一个可以直接套的估算公式。
设:
C= 单次模型调用的平均输入 tokenR= 角色数T= 总轮次(一次角色发言算一轮)
| 拓扑 | 输入 token 量级 | 说明 |
|---|---|---|
| 单 Agent | ≈ C × T | 基准 |
| Sequential Pipeline | ≈ C × T | 每个角色只看自己那段上下文,几乎不涨 |
Supervisor(last_message) | ≈ 1.5C × T | 主管额外读一遍摘要 |
Supervisor(full_history) | ≈ 2.5C × T | 子 Agent 全量历史并入主图 |
| GroupChat(共享历史) | ≈ C × T²/2 | 平方级增长,这是烧钱的元凶 |
| Debate(N 轮) | ≈ 2C × T × N | 至少翻倍 |
结论很直白:GroupChat 的上下文是随轮次平方增长的。 12 轮的群聊,成本可能是同样任务单 Agent 的 20 倍以上。所以只要用群聊,必须配轮次上限。
四招把账单砍下来
① 分层模型路由:主管/路由用便宜模型,只有真正干活的角色用贵模型。
COMMON = dict(model_provider="openai",
base_url="https://api.deepseek.com",
api_key=os.environ["DEEPSEEK_API_KEY"])
cheap = init_chat_model("deepseek-chat", **COMMON) # 主管 / 路由 / 摘要
strong = init_chat_model("deepseek-reasoner", **COMMON) # 真正干活的角色
analyst = create_agent(model=strong, tools=[], name="analyst",
system_prompt="你是分析师。")
supervisor = create_supervisor(agents=[researcher, analyst],
model=cheap, # ← 主管用便宜的
prompt="你是主管。").compile()
② 用 last_message 而不是 full_history:见 4.1 的表,这一个参数经常就能省 40%。
③ 控制工具返回体积:多 Agent 场景下,一个返回 8000 token 的检索工具,会被 N 个角色各读一遍。在工具里就做截断和摘要,别指望模型自己忽略。
④ 硬性熔断:抄 MetaGPT 的 invest()。在回调里累加 token,超阈值直接抛异常中断图执行:
from langchain_core.callbacks import BaseCallbackHandler
class BudgetGuard(BaseCallbackHandler):
def __init__(self, max_tokens=200_000):
self.used, self.max = 0, max_tokens
def on_llm_end(self, response, **kwargs):
usage = (response.llm_output or {}).get("token_usage", {})
self.used += usage.get("total_tokens", 0)
if self.used > self.max:
raise RuntimeError(f"预算熔断:已消耗 {self.used} tokens,超过上限 {self.max}")
supervisor.invoke(payload, config={"configurable": {"thread_id": "t-1"},
"callbacks": [BudgetGuard(200_000)]})
七、可观测性与调试
多 Agent 不接可观测性,等于蒙眼开飞机。三条建议:
① 优先用 OpenTelemetry,别绑死在单一平台。 六个框架现在都出 OTel span,接一次能同时喂给 LangSmith / Langfuse / Phoenix / 自建 Jaeger。
② 一定要能回答这三个问题,否则你的埋点就是白做:
- 这条 trace 里,是哪个角色第一次说出了错误信息?
- 这次任务的 token 花在哪个角色身上最多?
- 角色切换了几次?有没有出现 A→B→A 的乒乓?
③ 离线验证图结构,一分钱不花。 所有图类框架都支持不调模型就把拓扑打印出来:
# LangGraph
print(app.get_graph().draw_ascii()) # 需要 pip install grandalf
app.get_graph().draw_mermaid_png(output_file_path="graph.png")
# AutoGen GraphFlow
print(b.build())
# Google ADK Workflow
print([n.name for n in wf.graph.nodes])
上线前先把这张图贴到设计文档里,比写 100 行说明有用。
八、选型决策树
你的流程步骤是固定的吗?
├─ 是 → 用工作流,别用多 Agent
│ ├─ 已在 LangChain 生态 → LangGraph StateGraph
│ ├─ 想要最简单 → CrewAI Process.sequential
│ └─ 在 GCP / Gemini → Google ADK Workflow
│
└─ 否 → 需要动态决定下一步
│
├─ 需要断点续跑 / 人工审批 / 时间旅行?
│ └─ 是 → LangGraph(+ langgraph-supervisor)★ 生产首选
│
├─ 需要多个专家自由讨论 / 复杂开放任务?
│ └─ 是 → AutoGen(SelectorGroupChat / MagenticOneGroupChat)
│
├─ 只是想快速验证一个想法 / 给业务方演示?
│ └─ 是 → CrewAI
│
├─ 团队小、只用 OpenAI、不想学新概念?
│ └─ 是 → OpenAI Agents SDK
│
└─ 想自动生成整个软件项目?
└─ 是 → MetaGPT(但请先读源码,别直接上生产)
九、生产踩坑清单(14 条)
langgraph-supervisor的子 Agent 必须有name,否则ValueErroroutput_mode默认last_message,想让主管看到子 Agent 的推理过程要显式改成full_history,但账单会涨- Swarm / Handoff 拓扑是双向图,必须配轮次上限,否则 A→B→A 乒乓到天荒地老
- AutoGen 用非 OpenAI 模型必须传
model_info,否则启动就报错 - AutoGen 的
description是给 selector 看的,不是注释,写含糊了选人就乱 - CrewAI 的
@listen("x")方法名不能叫x,会在类定义阶段被 Pydantic 拦下 - CrewAI 默认开启遥测上报,合规环境记得
export CREWAI_DISABLE_TELEMETRY=true - Google ADK 2.7 已废弃
SequentialAgent/ParallelAgent/LoopAgent,改用Workflow - ADK 的
Workflow暂时不能当LlmAgent的 sub_agent,架构设计时要注意 - ADK 靠
output_key+{key}插值传值,不是靠消息历史,迁移时最容易错 - OpenAI Agents SDK 里 handoff 和 agent-as-tool 语义完全不同:转移控制权 vs 函数调用,大部分人误用了 handoff
- 给每个角色配"最少必要工具"。角色 A 能调的工具,角色 B 有权限调,就等于没做隔离
- critic 类角色的提示词要写成"必须找出问题",否则它只会说"写得很好"
- 上线前先离线打印拓扑图。一半的"Agent 行为诡异",其实是图连错了
结语
如果只让我留一句话:
先用工作流写死,写不死的部分才交给 Agent;先用单 Agent 跑通,跑不通的部分才拆成多角色。
多角色框架卷了两年,六个选手各有各的赌注:LangGraph 赌"工程师要控制力",AutoGen 赌"协作模式会涌现",CrewAI 赌"抽象越像人越好用",MetaGPT 赌"SOP 比提示词可靠",OpenAI 赌"API 面越小越好",Google 赌"最终一切都是图"。
看下来,它们正在往同一个地方收敛:有向图 + 状态 + 检查点 + 护栏 + 可观测性。ADK 从三个特化 Agent 类收敛到 Workflow,AutoGen 补上 GraphFlow,CrewAI 在 Crew 之上加 Flow——都是同一个方向。
所以选型的时候别太焦虑:把业务逻辑和框架 API 解耦,角色定义、提示词、工具实现单独放一层,换框架的成本就只是重写编排那 50 行。真正值钱的从来不是框架,是你对"这件事该拆成几个角色、每个角色能看到什么"的判断。
下一篇我打算写多 Agent 的评测与回归测试——怎么给一个非确定性的多角色系统写单测、怎么做 A/B、怎么防止改一句提示词导致线上全崩。有兴趣的可以先关注一下。
觉得有用的话,点个赞 + 收藏,评论区聊聊你们线上在用哪个框架、踩过什么坑。
更多推荐




所有评论(0)