主题
多 Agent 协作与 A2A
一句话:多个 Agent 放在一起不会自然形成团队;拆不拆看三条判据——上下文隔离、权限分离、并行提速,单 Agent 加好工具能解决的不要拆。拆了就要回答四个程序问题:成员怎么组织(四种拓扑)、事实放在哪(共享状态还是消息传递)、并行分支怎么隔离与合并、结果由谁签字。A2A 只解决跨主体任务委派的报文与生命周期,组织与责任仍要编排层自己设计。
适用:2026 年多 Agent 编排与 A2A 协作实践;协议字段与状态取值以官方规范为准,通信语义、契约六要素与报文细节见 分布式通信与协议栈,本篇不重复。
为什么需要
单 Agent 会遇到三类墙:上下文被检索和工具日志挤爆;工具与权限集太大收不紧;串行循环把本可并行的子任务压成一条长队。这时多 Agent 确实有用——每个成员只携带完成当前工作所需的上下文、工具和操作范围。
但更常见的故障是不该拆。因为“角色分工看起来专业”而把需求、设计、实现、测试拆成四个 persona,任务本身严格串行、上下文强关联,拆分只是让每一次交接都多一份损耗。多 Agent 的成本是硬的:状态一致性(每个成员各持一份副本,覆盖写与丢失更新只在合并时爆发);调试复杂度(进程内断点变成跨进程因果链,没有统一任务标识就查不出“卡在哪一环、谁欠谁一个结果”);token 翻倍(N 份系统提示、N 份历史加协调消息,端到端成本常见为单 Agent 的 2–5 倍(经验值))。
所以起点是反判据:单 Agent + 好工具能解决,就不要拆。要拆,先回答撞了哪面墙,而不是想扮演谁。
核心机制
一、拆不拆:三条正判据与一条反判据
- 上下文隔离:检索、日志分析、大仓库扫描这类子任务产生大量中间过程、只需要回结论。放主上下文里要靠反复压缩卸载(见 上下文工程与压缩卸载);放独立成员上下文,主线天然干净。
- 权限分离:一个成员既做只读探索又做对外发送,权限模式就收不紧。拆成不同工具集、不同身份的成员,入站/出站分离才落得下去——交接不扩大权限,有效权限是各层交集。
- 并行提速:互不依赖的子任务(多文件分析、多源调研)串行跑是浪费时延。扇出只对有依赖图的“无依赖”部分动手,隔离与合并规则见本篇第四节。
反判据:目标单一、上下文集中、严格串行的任务,单 Agent 更简单有效。两个伪需求要警惕:上下文爆了先查工具返回是否限量,拆成员不解决问题;权限太宽先拆工具接口(见 工具、MCP 与 Skill),拆对话同样不解决问题。
读这棵树先看顶部的判定:它问的是“单 Agent + 好工具够不够”,不是“需要几个 Agent”,答“能”就直接结束。中间三个理由节点是拆分依据而非成员角色,它们只决定为什么拆;真正选结构的是下面那个菱形,四档按协调方式而非人数区分。NOTE 只标默认档,不是第五种拓扑。
二、四种协作模式与各自失败模式
| 模式 | 结构 | 适合 | 典型失败模式 | 缓解 |
|---|---|---|---|---|
| Supervisor / 层级 | 中心协调者拆任务、派工、聚合 | 目标明确、责任集中、子任务异质 | 中心瓶颈:局部判断都等 Leader;误派工:任务派给不具备能力或权限的成员,几轮后才暴露 | Leader 只管目标、约束与验收,不介入执行细节;派工依据 = 能力声明 ∩ 权限 ∩ 当前负载;委派深度设上限(3 层,经验值) |
| Handoff / 移交 | 会话所有权整体转移给下一个 Agent | 分诊场景:识别问题类别后专业应答 | 移交震荡:两个 Agent 都认为对方更合适,会话来回弹跳,预算烧完问题还在原地 | 移交条件与目标枚举化,不允许自由发挥;“谁持有会话”是唯一互斥状态;同一对成员间最多移交一次(经验值),第二次出现转人工或终止 |
| Pipeline / 流水线 | 固定顺序逐级传递,每级产出交付物 | 流程稳定、阶段边界清晰的 produce 链 | 误差沿级放大:第一级的偏差被第二级写成事实、第三级当作标准,全程无人发现 | 每级输出结构化产物而非自由文本;关键阶段后插入验证步;产物带版本与来源,返工回到出错的那一级,不整链重跑 |
| Debate / 对辩 | 多成员各自论证、互相反驳,裁判裁决 | 高不确定性判断:安全评审、根因定位 | token 方差大:一轮分歧触发多轮追加;附和失效:成员看到彼此观点后向第一个发言者收敛,对辩退化为附和 | 先独立给出结论、再互看对方观点,避免锚定;参与者 2–3 个、回合数不超过 2(经验值);裁判不参与内容生产,只做程序性裁决 |
决策树见第一节图。补充两条:四种模式可组合(外层 Supervisor、子任务内部 Pipeline);组合层数越多,观测和停止条件越要在根任务一次定死,不能每个局部各定一套预算。
三、共享状态还是消息传递
两条路的失效模式完全不同,必须先选一条再谈实现。
共享状态(成员读写同一份 store)的陷阱是读-改-写交错:模型无状态,察觉不到另一个成员正在改同一份上下文,只能由编排层预先消除竞争,事后补救不了。三个最小约束:单写者——每个键只允许一个成员写,其余只读;版本化——写入带 epoch 或 CAS,冲突显式报错而不是后写覆盖;权威归属——每个状态对象有且只有一个 owner 负责推进。
消息传递(各持副本、靠消息同步)的回报是可回放性:消息即日志,调试、评测、故障重建可以复用同一份轨迹;共享状态一旦被覆盖,历史就没了。两个最小约束:每条消息携带 {root_task_id, member_id, msg_id} 并按幂等键去重;消息说明“发生了什么”,Task State 与 Artifact 记录“当前事实是什么”——成员通知完成,其他成员仍以任务状态为准、经产物引用取结果,不把某条消息摘要当事实。
实践取向:默认消息传递 + 独立状态对象,把共享写当作例外并按上面三约束管理;消息平面与协作状态分离的通信契约见 分布式通信与协议栈。事件溯源可以作为状态权威,但要有完整事件、顺序、保留与重建契约,不能把消息队列当任务账本。
四、并行扇出:隔离、合并与部分失败
- 无依赖才并行:依赖决定何时开始,创建顺序不等于执行顺序;调度按任务状态判断,可独立推进的分支不因兄弟分支阻塞。
- 分支隔离:每个分支独立上下文、独立工具白名单;共享工作区按目录、分支或键空间隔离,合并点之前的写互不可见。会话内串行的原则同样适用于合并点(见 运行时并发与拦截)。
- 合并冲突要仲裁:两个分支改同一目标,必须预先声明 reducer(进程内框架)或仲裁步骤(跨进程:按版本、时间戳、证据强度裁决)。默认“last-write-wins”几乎总是错的;设计上应让分支写目标互不相交,把冲突降为例外而非常态。
- 部分失败语义显式选定:三档——fail-fast(一支失败即取消其余并返回已完成部分)、best-effort(聚合可用结果,缺项列清单)、quorum(达到 N/M 门槛才继续)。在编排设计时选定并写进契约,不能让运行时的框架默认值替你表态。
- 预算随扇出传播:全局 deadline 向下传递,分支数上限 4–8(经验值);分支超时先收partial 结果再判剩余,不允许无限等待。
五、A2A 的位置:跨主体任务委派
同进程的 subagent 或框架内的图节点不需要协议;只有跨进程、跨团队、跨部署单元时才轮到 A2A。它的主干三段:Agent Card 发现(skills[].examples 是给编排方做语义匹配的,不是给人看的;capabilities.streaming 决定后续用流式还是轮询;能发现、能调用不等于可信身份)、Task 生命周期(submitted / working / input-required / completed / failed / canceled / rejected / auth-required;input-required 是正常的中途交互,rejected 是拒单,与执行失败的 failed 不是一回事)、Artifact 交付(大内容只传引用,不往 Task 里塞整份日志)。
与 MCP 的分界一句话:MCP 管工具与上下文,是垂直方向的能力调用;A2A 管跨主体任务委派,是水平方向的有状态长跑任务。编排 Agent 经 A2A 把子任务派给专业 Agent,专业 Agent 自己再经 MCP 调工具,两者组合而不是竞争。报文形态、超时分层与“把 A2A 当同步 RPC”的具体失败模式见 分布式通信与协议栈。
四个子图是并列关系,不是流程的先后:前三个各画一种拓扑的结构骨架,第四个只标协议位置。虚线分两类——子图内的是失败路径(移交震荡),跨子图的是协议面调用(A2A 派单、MCP 调工具),两类都不是下一步执行顺序。
六、责任边界:执行与验证分离
生产者的结论不能自己签字。执行成员输出的是候选成果:提交(submitted)只表示产出物存在;接受(accepted)由独立验证者——测试成员、裁判模型或人工——依据验收标准做出,才允许流向下游;根任务完成表示当前有效版本共同覆盖目标;用户取得产物、确认接受并归档,任务才真正完结。三层结果语义不可互相替代,“已完成”不是终态。
配套三条:验证基于可访问的产物引用,不基于执行者的自述摘要;失败用例连同产物版本和修订要求关联回子任务,旧结果保留为历史事实,后续只对当前有效版本判断;Task(持续工作约定)与 Task Run(一次执行记录)分开建模,重试和恢复产生新 Run(任务建模细节见 异步任务编排与状态机)。
实战场景
场景一:为“像团队”拆 persona,token 翻倍、时延三倍、无法归因
现象:需求、设计、实现、测试被拆成四个 persona,立项理由是“分工看起来专业”。上线两周三个数字同时恶化:端到端 token 达到单 Agent 基线的 3 倍以上(经验值,需校准,仍在本篇立项估算的 2–5 倍口径内);端到端时延约为基线 3 倍(经验值,需校准)——四个角色严格串行、上下文强关联,拆分只是把一次循环切成四次交接;一次 badcase 定位从分钟级涨到小时级,没人能回答“卡在哪一环、谁欠谁一个结果”。
排查过程:按层排除。
- 通信层:每条消息带
{root_task_id, member_id, msg_id}并按幂等键去重,无丢无重,排除。 - 状态层:四角色串行持有会话,同一时刻只有一个写者,不存在读-改-写交错,排除。
- 权限层:出站动作只发生在测试成员,工具集按成员收窄未扩大,排除。
- 编排层:命中——上下文隔离、权限分离、并行提速三条正判据一条未撞,落在反判据里;同时 Pipeline 的失败模式已经发生:需求阶段的一句歧义被设计阶段写成事实、实现阶段当作标准,误差沿级放大且全程无人发现。
对症做法:合并回单 Agent 加结构化工具,把“设计”“测试”降为任务内的两个步骤,各产出带版本与来源的结构化产物、返工回到出错的那一步;确需权限分离才保留测试成员独立身份,移交只带四类内容——目标、已知事实、待处理事项、可用引用。立项前先跑单 Agent 基线,记录第几步、因为什么失败,再决定拆不拆。
复盘要点:“更专业”不是拆分理由,撞了哪面墙才是;状态一致性、调试复杂度、token 翻倍三笔硬成本要在预算评审期入表。归因能力来自用根任务 id 把成员执行串成同一棵 trace,与成员数量无关。
场景二:并行扇出漏配 reducer,分支互相覆盖
现象:Supervisor 对 6 个互不依赖的仓库做并行分析(分支数未超 4–8 上限),分支结论统一写入共享 store 的同一个键。一周内出现 11 条(经验值,需校准)结论与证据对不上:两个分支对同一键读-改-写交错,后写静默覆盖前写,被覆盖的分支自认为写入成功,直到用户采信错误结论才暴露。
排查过程:
- 通信层:完成通知全部送达,消息即日志可回放,排除丢消息。
- 编排层:调度按任务依赖图放行,可独立推进的分支未被兄弟阻塞,“创建顺序不等于执行顺序”没有被违反,排除。
- 状态存储层:命中——共享键允许多写者、写入不带版本,两次写入的执行日志都显示“成功”:默认 last-write-wins 替团队表了态,而设计期没人做过这个决定。
对症做法:回到默认取向——消息传递加独立状态对象,完成消息只说明“发生了什么”,结论作为 Artifact 交付、由 Task State 记录“当前事实是什么”;确有共享写例外的,按键空间把分支写目标拆到互不相交,汇总键只允许单写者,写入带 epoch 做 CAS、冲突显式报错而不是后写覆盖;进程内在合并点配 reducer,跨进程设仲裁步骤按版本、时间戳、证据强度裁决。部分失败语义(fail-fast / best-effort / quorum)在设计期选定并写进契约,不让框架默认值替你表态。
复盘要点:模型无状态,察觉不到另一个成员正在改同一份上下文,竞争只能由编排层预先消除,事后补救不了。“共享状态让成员信息同步”的误区在这里兑现了代价——同步了副本,丢更新照样发生,因为不同步的是权限和权威归属。
场景三:Handoff 之后没人签字,责任断链
现象:分诊 Agent 判定问题类别后把会话移交给专业 Agent,专业 Agent 输出结论并标记“完成”,用户拿到的却是错误产物。追问“谁对这个结果负责”,两个成员各自出示移交记录与完成记录,全程只有执行方自己签字:没有独立验证者,也没人认领根任务的验收责任,事故时长里归责与扯皮超过修复本身(经验值,需校准)。
排查过程:
- 通信层:跨主体委派的报文与 Task 生命周期记录完整,
input-required没有被误读成失败、rejected没有被当成failed,排除。 - 编排层:同一对成员间移交只发生一次,未触发移交震荡,排除。
- 验证与状态建模层:命中——三层结果语义被压成一层,submitted 被当成 accepted;Task 与 Task Run 混在一起建模,一次重试覆盖了上一轮的产物记录,旧结果没有保留为历史事实。
对症做法:执行成员输出候选成果,提交只表示产出物存在;接受由独立验证者(测试成员、裁判模型或人工)依据验收标准做出,验证基于可访问的产物引用、不基于执行者的自述摘要;编排配置把 producer_cannot_approve: true 与 final_accept: human 固化为硬约束;失败用例连同产物版本与修订要求关联回子任务,重试和恢复产生新 Run。移交转移的是会话所有权,不转移签字责任——根任务发起人始终是验收归口,“谁发起 → 谁执行 → 访问了什么”的责任链不因移交而断开。
复盘要点:“已完成”不是终态,用户取得产物、确认接受并归档,任务才真正完结。A2A 只解决跨主体委派的报文与生命周期,拓扑选择、合并语义、验收责任仍要编排层自己设计并留痕。
最小上手
yaml
orchestration:
mode: supervisor # 拿不准时的默认档
max_delegation_depth: 3 # 经验值
fanout: {max_parallel: 6, partial_failure: best_effort} # 经验值
handoff: {max_hops_per_pair: 1, on_oscillation: escalate_human}
pipeline: {stage_output: structured, verify_after_stage: true}
state:
passing: message # 默认消息传递
source_of_truth: task_state + artifact
shared_keys: {writer: single, versioning: cas}
responsibility: {producer_cannot_approve: true, final_accept: human}
stop: {budget: 继承全局 deadline 并向下传播, on_stop: 暂停委派转人工}跑通判据:每个成员只拿到任务所需的上下文与工具;从根任务 id 能串起所有成员的执行记录;同一对成员间的移交震荡能在第二次触发前被拦截;扇出分支失败时按选定语义返回并列出缺项;任何“完成”结论都有独立验证者的签字。
生产动作
- 从单 Agent 基线起步:记录单 Agent 在第几步、因为什么失败,再决定拆的理由;“更专业”不是理由。
- 团队级停止条件先于拆分约定:时间/成本预算、委派深度、派生任务数、重试次数、返工轮次、连续无有效进展;触及后暂停新委派与自动返工,保留结果、阻塞点和剩余预算转人工。单个成员的重试上限不替代团队级约束。
- 移交只带四类内容:目标、已知事实、待处理事项、可用引用;搜索过程、工具调用记录、未验证推理不原样传递,完整历史转交只会放大污染。
- 观测用根任务串联:成员执行挂同一棵 trace,跨 Agent 用 span links 保留真实因果;责任链“谁发起 → 谁执行 → 访问了什么”任一环节校验失败即拒绝,不降级为共享账号。
- 成本按 2–5 倍估算(经验值):预算评审时把 N 份系统提示、N 份历史和协调消息都算进去,与单 Agent 方案对比后再立项。
- 评估看整体:交付质量与协调成本共同衡量,只看单成员准确率会系统性高估多 Agent 收益。
边界
- 适合:跨专业长流程、子任务可独立交付、权限需要按成员收窄、无依赖并行能显著降时延。
- 不适合:严格串行且上下文强关联的任务、单机短时任务——用进程内 subagent 或直接工具化,跨进程协议对它们是纯开销。
- Debate 慎用:token 方差大,只留给高不确定性判断;有确定验证手段的任务(能跑测试就别辩论)。
- A2A 接通不等于团队成立:协议只统一报文与任务生命周期,拓扑选择、停止条件、合并语义、验收责任仍要编排层自己设计并留痕。
- 常见误区:成员越多越强——协调成本随数量组合增长;常见误区:共享状态让成员“信息同步”——不同步的是权限和权威归属,同步了也照样丢更新。
讲清楚
多 Agent 的立项判据是三条:上下文隔离、权限分离、并行提速;反判据只有一条——单 Agent 加好工具能解决就不要拆,因为换来的是三份硬成本:状态一致性、调试复杂度、token 翻倍。
拆了之后,组织上四选一:Supervisor(中心瓶颈与误派工)、Handoff(移交震荡)、Pipeline(误差沿级放大)、Debate(token 方差与附和失效),每种模式都有专属失效,拿不准从 Supervisor 起步。状态上默认消息传递 + Task State/Artifact 记录事实,共享写必须单写者、版本化、有权威归属;并行扇出只对无依赖分支动手,合并要 reducer,部分失败语义(fail-fast / best-effort / quorum)在设计期选定。跨主体委派才用 A2A——它管任务生命周期,MCP 管工具与上下文;最后一条铁律是执行与验证分离:生产者只能提交候选成果,接受由独立验证者做出,根任务的最终验收归发起人。
适用:2026 年多 Agent 编排与 A2A 协作 | 初稿 2026-10