01 · 核心概念
核心概念:拓扑 × 协调 × 通信
上一章 index 给了三轴的心智地图——这章把每条轴逐个建起来。读完,看到任何一套多 agent 系统,能在三条轴上各点出它的取值,并在最后判断它本就该不该是多 agent。基于 2026-06 的框架现状(LangGraph 1.0、Microsoft Agent Framework v1.0、AG2、OpenAI Agents SDK、CrewAI、Claude Agent SDK);下文代码用来演示分界判断,均未在本机执行(标 2026-06)。
本章你要建立的心智模型
- 拓扑 × 协调 × 通信是三条正交的轴——任一多 agent 系统都是三条轴各取一值的组合,而非"挑一个框架"。
- 拓扑回答"连接长什么形状":supervisor(一个协调者派活)、hierarchical(多层)、network/swarm(agent 直接交接、无中心)。
- 协调回答"下一步决策权在谁手里":中心调度 vs 去中心 handoff。通信回答"信息怎么流":共享 state vs 消息传递,外加 per-subagent 上下文隔离。
- 最重要的一道闸:多数任务单 agent + 多工具就够,只有"子任务独立可并行且价值高"才上多 agent。
1.1三轴总览
拓扑、协调、通信是三条互不绑定的轴;一套多 agent 系统就是在三条轴上各取一值的组合。
框架文档按"产品"组织——LangGraph 一节、CrewAI 一节、AutoGen 一节,读完只会按框架名记忆,换个框架就重新学。三轴把"框架"拆成"维度":任何系统都落在拓扑/协调/通信这三条轴上。认出取值,再认框架是哪种组合的封装,迁移成本就从"重学一个产品"降到"换一组取值"。
底层机制:为什么这三条轴是"正交"的
正交在这里有一个可验证的含义——固定其中两条轴的取值,第三条仍可独立改变,而系统照常成立。逐对验证一遍:
- 固定拓扑 supervisor + 通信共享 state,协调可以是"中心调度派活",也可以换成"协调者只在 state 里放下一步标记、由 agent 自行轮询"——拓扑没变,连接形状没变,决策权位置变了。
- 固定拓扑 supervisor + 协调中心调度,通信可以走全员可见的 group chat,也可以走只读写共享 state——谁说了算没变,信息载体变了。
- 固定协调中心调度 + 通信共享 state,拓扑可以是单层 supervisor,也可以叠成 hierarchical 多层——决策权与信息载体没变,连接的层数变了。
三对都能"固定二者、独立改第三",这就是正交的操作性定义。它的实践后果:一套系统不是"是 LangGraph 还是 AutoGen",而是三个独立选择叠出来的一个点,组合数远多于框架数。下面这张图把三条轴画成一个坐标,每个框架是这个坐标里的一块区域,而不是一条轴。
有人说"swarm 框架就是去中心,supervisor 框架就是中心调度,所以拓扑和协调其实是一回事"。这句话哪里错了?
展开答案(先停 10 秒再点)
错在把"常见搭配"当成"绑定"。拓扑是连接形状,协调是决策权位置,两者高度相关但不等同。反例:supervisor 拓扑下,协调权可以不在中心——协调者只负责把任务写进共享 state,由各 worker 自行认领(pull 模式),决策权其实分散了;反过来,network 拓扑里也能塞一个事实上的"裁判 agent"集中拍板。形状和决策权是两条可独立调的轴,常一起动不代表是同一条。
1.2拓扑结构
拓扑 = agent 之间连成什么形状——三种基本形状:supervisor、hierarchical、network/swarm。
拓扑决定了控制流的形状,而控制流的形状直接决定了哪些失败会发生(04 章按拓扑组织失败清单)。先把形状认清楚,后面的失败模式才有挂靠的钉子。三个名字首次出现,先用大白话点一句:supervisor = 一个"工头"派活给工人;hierarchical = 工头之上还有工头,多层;network/swarm(蜂群式自由交接)= 没有工头,工人之间直接把活递给下一个人。
底层机制:形状的差别落在"边"上
把每个 agent 看成节点、"谁能把控制权交给谁"看成有向边,三种拓扑的差别就是边的连法不同,比文档常说的"集中 vs 分散"更具体:
- supervisor:边是星形——所有边从中心节点出、再收回中心。worker 之间没有边,彼此不可达。控制流每一跳都经过中心,于是中心的 trace 里能看见全过程。
- hierarchical:边是树形——星形的递归,每个 worker 自己又可以是下一层的中心。控制权沿树往下分发、结果沿树往上汇聚;层数 = 决策被转手的次数。
- network/swarm:边是任意有向图——任一 agent 都允许有指向其它 agent 的边,没有必经的中心节点。在 LangGraph 里,这条"边"被实现成 handoff 工具返回的
Command(goto=..., graph=Command.PARENT)——agent 调用该工具,运行时就跳到父图的另一个节点,等于自己画了一条边。
"边"这个视角能直接读出代价:星形的中心是单点瓶颈也是单点可观测;任意图省掉了中心那一跳所以更快,但没有一处能看见全局,调试要把多段 trace 拼起来。这条权衡 02 章和 04 章会反复回引。
类比 · 带边界
把三种拓扑类比成公司的汇报线:supervisor 像一个经理带一组互不沟通的下属,所有协调经过经理;hierarchical 像总监—经理—员工的多级汇报;network/swarm 像一群同级同事,谁手上有合适的活就直接转给旁边的人。类比在这里断裂:公司的汇报线是为了"权责",而 agent 拓扑是为了"控制流与上下文边界"——经理换人不影响下属的记忆,但 supervisor 这一跳决定了 worker 能不能看见彼此的上下文。把拓扑当组织架构图去想会漏掉"上下文在哪分隔"这个 agent 独有的维度,那正是 1.4 的主题。
场景走查
需求:"给定一个城市,产出一份含天气、交通、3 个景点的一日游建议"。天气查询、交通查询、景点检索三件事彼此独立、可同时进行,最后拼成一份建议——边从一个协调点发出去、结果收回来,supervisor 星形正好贴合。若再要求"景点检索内部再按'美食/历史/自然'三类分头查",那就是在 worker 之下再开一层,星形递归成hierarchical。若需求变成"客服对话,账单问题转账单专员、技术问题转技术专员、专员之间还能互转",没有必经中心、agent 之间直接交接,那是network/swarm。
1.3协调机制
协调 = 谁持有"下一步决策权"——中心调度(协调者决定)vs 去中心 handoff(agent 自行决定交给谁)。
拓扑画出了边,但"边什么时候被走、被谁触发"是另一件事。同一张 supervisor 星形图,决策权可以在中心(协调者每一步决定派给谁),也可以分散(worker 干完自己挑下一步)。把决策权的位置单独拎出来当一条轴,才能解释为什么"同样的图"会有完全不同的运行行为和失败方式。handoff(交接)首次出现,大白话:一个 agent 主动把"这件事现在归你管"交给另一个 agent。
底层机制:决策权 = "下一步是谁"这个决定由谁的 LLM 调用产生
把它落到代码层面,决策权的位置就是一个很具体的问题——"下一步该轮到哪个 agent"这个判断,是哪一次 LLM 调用的输出?
- 中心调度:有一个固定的协调者节点,每一跳都先回到它,由它的 LLM 调用(或一段路由逻辑)产出"下一步是谁"。决策权集中在这一个节点。代价:协调者是必经跳,多一次往返、多一份 token;好处:下一步永远有据可查。
- 去中心 handoff:没有固定协调者,"下一步是谁"由当前正在跑的那个 agent自己的 LLM 调用产出——它在自己的工具列表里挑一个 handoff 工具调用,把控制权连同上下文交出去。决策权随控制权一起移动。代价:没有一处能集中看见"为什么走到了这一步",misroute(交错对象)只能事后从各段 trace 拼。
这条机制有一个反直觉处:决策权位置和拓扑不是一一对应。supervisor 拓扑通常配中心调度,但也能配 handoff(协调者只做入口,之后 agent 互相交接);network 拓扑通常配 handoff,但塞一个裁判节点就成了事实上的中心调度。所以面试里"画个 supervisor"不等于答完了——还得说清决策权在不在中心。
| 维度 | 中心调度 | 去中心 handoff |
|---|---|---|
| "下一步是谁"由谁决定 | 固定协调者节点 | 当前正在跑的 agent 自己 |
| 典型框架 | LangGraph supervisor、CrewAI hierarchical | OpenAI Agents SDK handoff、LangGraph swarm |
| 可观测性 | 强——决策都在一处 | 弱——决策分散在各 agent |
| 延迟 / token | 每跳多一次协调往返 | 省掉中心那一跳,更快 |
| 最怕的失败 | 协调者成瓶颈、或自己越权代劳 worker | misroute、交接后上下文带不全 |
类比 · 带边界
中心调度像航空的塔台——每架飞机的下一步动作都由塔台统一指挥;去中心 handoff 像接力赛——棒在谁手里,谁决定何时交给下一棒。断裂点:塔台和接力都假设"下一个上场的人"基本确定,而 agent 的 handoff 是由 LLM 现场判断的,存在判断错对象的风险(接力赛不会把棒交错跑道,agent 会)。所以去中心 handoff 真正的工程难点不在"交接"这个动作,而在"判断交给谁"这个易错的 LLM 决策——这正是 04 章 misroute 类失败的根。
场景走查
需求:"一个研究助手,先检索资料再写报告"。若让一个固定的协调者每步决定"现在该检索还是该写",决策可追溯、便于在中间插入人审,这是中心调度。需求变成"客服系统,账单专员处理到一半发现是技术问题,直接转给技术专员"——由当前专员自己判断该不该转、转给谁,没有回中心绕一圈,这是去中心 handoff。注意同一个客服系统,如果改成"每条消息都先回到一个分诊节点再分发",它又变回中心调度了——决策权的位置是被设计出来的,不是被场景唯一决定的。
1.4通信方式
通信 = 信息怎么在 agent 间流——共享 state(都读写同一状态)vs 消息传递(显式传消息);外加 per-subagent 上下文隔离。
拓扑画了边、协调定了谁决策,但"agent 之间到底交换了什么、看得见多少"还没回答。通信这条轴决定了两件高影响的事:上下文成本(谁看见越多,token 越贵)和上下文污染(看见不该看见的,判断被带偏)。它直接连着多 agent 最常见的两类生产事故,所以单列一条轴。
底层机制:两种载体,差别在"默认可见范围"
- 共享 state:所有 agent 读写同一个状态对象(LangGraph 的
State就是这种——它同时充当各 agent 之间的"公告板")。一个 agent 写进 state 的东西,别的 agent 默认读得到。好处:不用显式搬运信息;代价:state 越大,每个 agent 的上下文越臃肿,且容易读到与自己无关的内容。 - 消息传递:信息以显式消息流动——group chat(全员可见,如 AG2 的 GroupChat)或 handoff 时携带的上下文(点对点,如 OpenAI Agents SDK 把对话上下文随交接一起带过去)。可见范围由"发给谁"显式决定,但要自己保证"传够了"。
per-subagent 上下文隔离:为什么要把 subagent 的上下文分开
这是多 agent 区别于"一个长对话"的关键一招,也是 Anthropic 的 multi-agent research 系统反复强调的设计:给每个 subagent 一份独立、干净的上下文,而不是把所有 agent 塞进同一个不断膨胀的对话历史。两个动机,正好一推一拉:
- 推:防 context clash(上下文打架)。若所有 subagent 共享一条历史,A 的中间推理、B 的失败尝试、C 的无关检索全混在一起,每个 agent 都被迫读一堆与自己任务无关的内容——既烧 token,又容易被别人的错误结论带偏。隔离让每个 subagent 只看自己那一摊。
- 拉:但必须"传够信息"。隔离的代价是 subagent 看不到全局,于是协调者派活时要把"这个子任务需要的背景"明确打包进去——任务目标、约束、已知事实。Anthropic 的经验是:subagent 表现差,常常不是模型不行,而是派活时上下文给得不够。隔离和"传够"是一对必须同时拿捏的力。
所以上下文隔离不是"少给信息",而是"精确地给"——切断无关的,打包必需的。这条拿捏失手的两个方向(给太多 = clash、给太少 = subagent 抓瞎),04 章都各有一个失败模式对应。
通信轴管的是"信息可见范围",协调轴管的是"决策权位置",两者独立。一个去中心 handoff(决策分散)的系统,完全可以配共享 state(信息全可见);一个中心调度(决策集中)的系统,也可以给每个 subagent 隔离上下文(信息分隔)。把"谁能看见"和"谁说了算"分开想,是读懂多 agent 设计的一个关键切分。
# A. 共享 state —— agent 读写同一个 State,彼此默认可见
class ResearchState(TypedDict):
topic: str
findings: list[str] # 多个 agent 往这里 append,互相读得到
def worker(state: ResearchState) -> dict:
note = search(state["topic"])
return {"findings": [note]} # 写回共享 state,其他节点能读到
# B. 消息传递 / handoff —— 控制权 + 上下文显式交给下一个 agent
# (OpenAI Agents SDK:handoffs= 声明可交接对象,上下文随交接带过去)
billing = Agent(name="Billing", instructions="处理账单")
tech = Agent(name="Tech", instructions="处理技术故障")
triage = Agent(name="Triage", instructions="按问题类型交接",
handoffs=[billing, tech]) # 交接时携带对话上下文
# C. per-subagent 上下文隔离 —— 协调者给每个 subagent 一份"打包好的"干净任务
def spawn_subagent(subtask: str, packed_context: str):
# 关键:不传整条全局历史,只传这个子任务需要的背景(精确地给)
return run_agent(system=packed_context, task=subtask)
findings 是共享 state 的"公告板"语义——append 即广播。handoffs= 是消息传递里点对点交接的声明。packed_context 体现隔离的正确姿势:不是不给,是只给这个子任务需要的。
类比 · 带边界
共享 state 像团队共用一块白板,谁都能写、谁都能看;消息传递像发邮件,收件人明确。上下文隔离像"给每个外包只发与他那块活相关的需求文档,不把整个项目历史甩给他"。断裂点:白板/邮件的内容是人写的、稳定的,而 agent 写进共享 state 的常常是没核实的中间结论——别的 agent 读到后会当真,错误就这样传染(白板上的错字不会主动误导同事,state 里的错误结论会)。所以共享 state 的便利伴随"错误广播"的风险,这也是为什么高价值并行任务反而偏向隔离上下文。
场景走查
需求:"3 个 subagent 并行查同一主题的不同侧面,最后汇总"。若它们写进同一个 findings 列表、协调者读全部来汇总——共享 state,简单。但若其中一个 subagent 查岔了、把错误结论写进 state,另外两个读到后会顺着错下去——这时改成每个 subagent 隔离上下文、只把最终 finding 交回协调者,错误就被关在单个 subagent 里不外溢。需求若是"客服账单专员转技术专员",转过去时要带上"用户已经说过 API key 失效、已确认账户正常"这些上文——这是消息传递里"传够信息"的具体体现,少带一句用户就得重复说一遍。
同样是并行跑多个 subagent,什么时候该用共享 state、什么时候该用 per-subagent 隔离上下文?给一条判断依据。
展开答案(先答再展开)
判断依据:subagent 之间需不需要看见彼此的中间产物,以及中间产物错了会不会互相带偏。
需要互相看、且彼此基本可信(比如协作搭建一份共同文档的不同章节,要对齐术语)→ 倾向共享 state,省去搬运。彼此独立、互相看见只会增加噪声和被错误带偏的风险(比如各查一个独立侧面)→ 倾向隔离上下文,只把最终 finding 交回协调者。一句话:共享换协同,隔离换抗污染与省 token。Anthropic 的 research 系统选了隔离——因为并行检索的 subagent 互不需要看彼此的中间过程。
1.5单 agent + 工具 vs 多 agent 的分界
默认单 agent + 多工具;只有"子任务独立可并行且价值高"才上多 agent——这是全教程最重要的判断闸。
前四节教的是"多 agent 怎么搭"。这一节回答一个更上游的问题:这件事该不该是多 agent。多数任务一个 agent 配一组工具(外加必要时的固定 workflow)就够了;多 agent 引入并行价值的同时,也引入 token 成倍增长、协调复杂度、调试困难。把这道闸放在 1.5、放在全章最后,是因为它能否决前四节的一切——形状/决策权/通信选得再漂亮,若本就不该上多 agent,整套都是负债。
底层机制:多 agent 买的是什么、付的是什么
多 agent 不是免费的抽象,它是一笔有明确收支的交易:
- 买到:① 并行——独立子任务同时跑,省墙钟时间;② 上下文隔离——每个 subagent 专注一摊,防 clash;③ 专业化——不同角色不同 prompt/工具,提质。
- 付出:① token 成本——Anthropic 公布其 research 系统的多 agent 架构消耗约为单 agent 聊天的 15×;② 协调复杂度——多一层"派活—汇总"要写、要调;③ 可观测性下降——跨多个 agent 拼 trace 才看得清一次运行。
这笔账只有在子任务真的独立可并行、且任务价值足够高到撑得起 15× 量级的 token时才划算。Anthropic 给的边界很直白:multi-agent 适合"价值高到能吃下 token 开销、且广度优先(breadth-first)可并行探索"的任务,典型是开放式深度检索;反过来,大多数任务、尤其是写代码这种串行依赖强的任务,单 agent 更合适——这也是 Cognition 在《Don't Build Multi-Agents》里的核心主张。这条 read-heavy 可并行 vs write-heavy 强依赖的分界,02 章第一节(§2.1)会展开成一条主原理。
| 维度 | 单 agent + 多工具(默认) | 多 agent |
|---|---|---|
| 适合的任务 | 串行依赖、需前后一致(写代码、写长文) | 独立可并行、广度优先(开放式深度检索) |
| 上下文 | 一条累积上下文,保一致 | 多份隔离上下文,防 clash |
| token 量级 | 基准 | 约 15×(Anthropic research 系统) |
| 调试 | 一条 trace 看到底 | 跨多 agent 拼 trace |
| 代表主张 | Cognition《Don't Build Multi-Agents》 | Anthropic multi-agent research system |
把"多 agent"当成显得高级的默认架构,给一个本质串行的任务(如"按需求写一个功能并自测")硬拆成多个 agent 并行——结果各 agent 写出互相冲突的代码、风格不一、还得花一层去合并冲突,比单 agent 又慢又贵又差。先问该不该多 agent,再问怎么搭多 agent。这道闸答错,前四节的功夫全部变成负债。
类比 · 带边界
类比成"一个人干 vs 组个团队":能一个人按时干完的活,组团队只会增加沟通成本(开会、对齐、合并);只有活大到一个人来不及、且能切成互不依赖的几块时,团队才真正提速。断裂点:人组团队还能靠默契和临场沟通补救切分不当,agent 之间没有默契——切分不当(本该串行却并行)不会被运行时自动修复,只会原样放大成发散和冲突。所以"能不能切成独立的几块"对 agent 是硬约束,比对人更不容妥协。
场景走查
需求 A:"调研 5 家竞品的定价并出一张对比表"——5 家彼此独立、可同时查、调研结论有商业价值,三道闸全过,多 agent(每家一个 subagent 并行检索)合理。需求 B:"把这份调研写成一篇连贯的分析报告"——写作前后强依赖、要风格统一,第一道闸就"否",回到单 agent。需求 C:"回答一个用户的简单产品问题"——单 agent 配一个检索工具就够,价值也撑不起多 agent 开销,根本不必进后面两道闸。三个需求摆在一起,正好是 1.5 这道闸的日常用法:先判该不该,再谈怎么搭。
§本章 self-check
合上教程,把答案先写在纸上或编辑器里。卡住的题,就是心智模型还没建好的地方——回对应小节再来。
- 用一句话说清拓扑、协调、通信三条轴各自回答什么问题。再举一个例子:固定其中两条、独立改第三条而系统仍成立。
- supervisor、hierarchical、network/swarm 三种拓扑,从"边"的角度各是什么形状?哪种没有"必经中心",它带来的好处和代价分别是什么?
- "per-subagent 上下文隔离"为什么不是简单地"少给信息"?给太多和给太少分别会出什么问题?
- 设计题:给定需求"一个能回答内部文档问题、并在涉及敏感操作时转人工的企业问答助手"。先判断它该不该上多 agent;若上,在三条轴上各点出你的取值并各给一句理由。
答案(先做完再展开)
- 拓扑=连接成什么形状;协调=下一步决策权在谁手里;通信=信息怎么流、谁看得见。例:固定"supervisor 拓扑 + 共享 state 通信",协调可在中心(协调者每步派活)也可分散(worker 自行认领 state 里的任务)——拓扑和通信没变,决策权位置变了,系统照样跑。这就是三轴正交。
- supervisor=星形(边全连中心,worker 互不可达);hierarchical=树形(星形递归,每层一个小中心);network/swarm=任意有向图。network/swarm 没有必经中心:好处是省掉中心那一跳、更快、更灵活;代价是没有一处能看见全局,misroute 与调试只能事后拼多段 trace。
- 因为隔离的正确姿势是"精确地给"——切断无关的、打包必需的,不是单纯减量。给太多=context clash,subagent 被无关内容和别人的错误结论带偏、还烧 token;给太少=subagent 缺背景抓瞎,表现差常被误判成"模型不行"。两个方向都失分,要同时拿捏。
- 参考答案(非唯一):多半不该上多 agent——问答+转人工是串行流程、子任务不独立、价值也撑不起 15× token,单 agent + 检索工具 + 一个 HITL 转人工动作即可。若坚持要点取值(练习用):拓扑 supervisor(一个入口 agent 统筹,便于在敏感点集中插入人审);协调中心调度("下一步是检索/回答/转人工"由入口 agent 决定,可追溯,敏感操作前能拦);通信共享 state(流程线性、信息量小,无需隔离),转人工处用消息传递把已确认上文带给人工。关键在第一步就敢答"不该上"——这正是 1.5 那道闸的用法。
把一个你没正式学过的系统放进三轴坐标
设想一个"自动写单元测试"的 agent 系统:读一个函数 → 生成测试 → 运行测试 → 失败就改测试再跑,直到通过。不查它的实现,只凭你对这件事行为的直觉回答:
- 它在 1.2 拓扑上更像哪种形状?为什么不适合 network/swarm 并行?
- 它的协调(1.3)决策权更倾向落在中心还是去中心?
- 用 1.5 那三道闸过一遍:它该不该是多 agent?哪一道闸最先把它挡回单 agent?
- 这三个答案里,哪一个判断同时锁定了另外两个?
提示(卡住再展开)
"生成→运行→改→再跑"是一条带反馈的串行回路,后一步强依赖前一步的结果——这一个判断就几乎锁定了全部:① 拓扑像单 agent 的自循环(或最多一个 generator-critic 的固定两节点),不适合 network/swarm,因为并行写测试会各写各的、无法对同一份代码收敛;② 决策权倾向中心/固定流程(下一步是"改"还是"完成"由一个固定逻辑判断,而非自由交接);③ 三道闸里第一道(独立可并行?)就答"否",因为它本质串行,于是回到单 agent + 工具(运行测试是个工具调用,不必是另一个 agent)。"串行依赖强"这一个判断是上游,它同时决定了拓扑和该不该多 agent——和 02.1 的 read-vs-write 主原理是同一条线。