博客.
博客.
(联系方式)

保持联系

如果你想联系我,无论是讨论合作机会、分享想法,还是只是打个招呼,都可以通过以下方式找到我。

(最后更新)

版权所有 / 2026

(快捷键)C
返回学习路线
(02 · Agent 开发)2026年8月

多 Agent 系统

多 Agent 的价值不是「人多力量大」,而是给每个任务一间干净的办公室——上下文隔离。读懂 orchestrator-worker 与它的代价,你就读懂了 Subagent 为什么是现在这个样子。

多 Agent 系统

先破个题:为什么要「多」Agent

单 Agent 已经能干活了,为什么还要搞一堆?直觉回答是「人多力量大」——并行干活更快。这个答案只对了一小半,而且是没那么重要的一半。

真正的答案藏在前面章节讲的东西里:Agent 的一切决策都依赖上下文,而上下文是稀缺资源。 一个长任务跑到后面,上下文窗口里塞满了工具输出、中间尝试、失败记录,模型的注意力被稀释,表现开始下滑——俗称「上下文腐烂」(context rot)。哪怕窗口号称 100 万 token,有效注意力也撑不满。

多 Agent 的核心机制就是针对这个病的药方:把一个大任务拆成小任务,每个小任务交给一个拥有全新、干净上下文的 Subagent 去做,做完只把结论带回来。 所以请记住本章的主线:

多 Agent 系统的核心价值是上下文隔离,并行加速只是附赠的红利。

这个判断会贯穿全章:理解它,你就理解为什么 Subagent 要那样设计、为什么 Anthropic 和 Cognition 会给出看似矛盾的工程建议。


解剖一个工业级样本:Anthropic 的 Research 系统

2025 年 6 月,Anthropic 发表了一篇复盘文章,讲他们 Claude 里「Research」功能(深度调研)背后的多 Agent 系统是怎么搭的。这是目前公开资料里细节最多的工业级 orchestrator-worker 实践,值得逐条拆开看。

架构本身不复杂:用户提一个调研问题,Lead Agent(编排者)先规划出几个调研方向,然后并行派出一批 Subagent;每个 Subagent 在独立上下文里搜索、阅读、提炼,把发现写成摘要交回;Lead 综合所有发现,必要时再派新一轮 Subagent 补漏,最后由另一个 Agent 负责引用核查,产出带引用的报告。

Anthropic Research 系统的 orchestrator-worker 架构:Lead Agent 派活给并行 Subagent,摘要回流综合后再经引用核查产出报告

真正有价值的是他们公布的数据:

  • 性能:在内部调研评测集上,多 Agent 系统(Lead 用 Claude Opus 4、Subagent 用 Sonnet 4)比「单 Agent 版 Opus 4」的表现高出 90.2%。注意基线不是弱模型,而是同代旗舰的单体版本——提升完全来自架构
  • 成本:多 Agent 的 token 用量约为普通聊天的 15 倍(单 Agent 约为 4 倍)。换句话说,那 90% 的性能提升是用十几倍的算力账单换来的
  • 归因:他们统计了三个变量对性能差异的解释力——token 消耗量、工具调用次数、模型选择。结果是 token 消耗量单独解释了约 80% 的方差。这等于用数据证明了:让模型「想得更久、读得更多」(哪怕是分摊在多个 Agent 身上)就是性能的主要来源

评估方法也值得一提。 调研类任务没有标准答案,没法用单元测试式的断言。他们的做法是:尽早在小规模任务集上搭建评测,用 LLM-as-judge 按评分细则(rubric)打分——事实准确性、引用质量、完整性、来源质量等维度逐项评估,同时保留人工抽检兜底。经验是:评测不用一开始就大而全,20 个能稳定复现的小任务就足够驱动早期迭代。

还有几个工程细节很容易被略过,但实战里全是坑:

  • 长任务要可断点续传:调研可能跑几十分钟,Subagent 挂了不能从头再来,需要把进度持久化、支持恢复
  • 发布要彩虹部署(rainbow deployment):正在运行的 Agent 不能被新版本打断,新旧版本并存、逐步切流
  • 任务说明书要教编排者写:Lead Agent 天生倾向派模糊的活(「调研一下半导体」),必须在系统提示词里明确要求写清目标、输出格式、边界和工具建议

架构模式全景:不止主从一种

主从(orchestrator-worker)是最主流的形态,但不是唯一选项。把常见的多 Agent / 多步模式摆在一起看,适用场景会清晰很多:

1. 流水线(Pipeline / Prompt Chaining) A 的输出是 B 的输入,步骤预先写死。比如「起草 → 审校 → 翻译」。本质是带 LLM 的工作流,自主性最低、可控性最高、最容易测试。步骤能预先穷举的任务,首选它。

2. 路由器(Router) 一个分类器 Agent 判断输入属于哪类,路由给对应的专家处理。比如客服系统先判断「退款 / 技术支持 / 闲聊」,再转给不同提示词的 Agent。它解决的是入口分发问题,Agent 之间不协作。

3. 主从(Orchestrator-Worker) 本章的主角。编排者动态拆解、动态分派,子任务数量和内容在运行时才确定。适合步骤无法预先穷举、且可并行拆解的任务:广度优先调研、大代码库多角度审查、多方案对比。

4. 群体辩论(Multi-Agent Debate) 多个 Agent(或同一模型的多个实例)各自给出答案,互相看到对方的回答后辩论修正,多轮后收敛或投票。学术上证明能提升事实性和推理正确率(Du et al., 2023),但成本高、轮次多,工程上多见于高风险决策的二次校验,比如让三个 Agent 独立审查同一份安全审计再对答案。

判断该用哪一招,先问两个问题:步骤能不能预先写死?(能 → 流水线/路由)子任务之间需不需要运行时动态协调?(需要 → 主从)答案错了代价大不大?(大 → 加辩论/投票校验)


任务分解与协作:拆得好,协作才成立

主从架构跑不跑得动,八成取决于 Orchestrator 怎么拆任务。好的分解有三个特征:

  1. 边界清晰:每个子任务的输入输出明确,不依赖其他子任务的中间状态
  2. 自包含:子任务描述里包含了 Subagent 干活所需的一切信息——因为它看不到你的完整对话历史
  3. 结果可合并:多个子任务的结果能拼回一个完整答案

第 2 点尤其容易被忽略。Subagent 是被「空降」到任务里的,它不知道用户是谁、之前聊过什么、为什么有这个任务。所以 Orchestrator 派的活儿必须是一份完整的任务说明书,而不是一句「帮我查一下那个东西」。Anthropic 的经验是:任务描述里要写清楚目标、输出格式、可用的工具、以及明确的边界(比如「只调研 X,不要去碰 Y」),否则 Subagent 之间会重复劳动,或者干脆跑偏——他们的系统里 Lead Agent 甚至要给 Subagent 定「工作量档位」,简单任务少用工具和搜索次数,避免杀鸡用牛刀。

协作层面还有一个隐形问题:结果合并。三个 Subagent 分别调研完回来,答案之间有重叠、有矛盾、有口径差异,Orchestrator 综合时必须显式处理冲突,而不是无脑拼接。工程上常见的做法是让结果回传时带上置信度和出处,合并时按来源可信度裁决,裁决不了的保留分歧、标注给用户。


上下文的隔离与传递:本章的灵魂

现在把「隔离」这件事掰开揉碎。为什么 Subagent 必须隔离上下文?

第一,保护主 Agent 的上下文。 想象一个调研型 Subagent:它要搜 10 个网页、读 5 篇长文、做若干次失败的尝试——这些过程性内容可能有十几万 token。如果全部倒进主 Agent 的上下文,主 Agent 自己的「工作台」瞬间被垃圾淹没。隔离之后,主 Agent 只收到一份几百 token 的结论摘要,工作台始终干净。

第二,保护 Subagent 的上下文。 反方向同样成立:Subagent 不需要知道用户的完整历史、不需要看主 Agent 的规划草稿。给它一个聚焦的小上下文,它的注意力全在本任务上,表现反而更好。上下文越小越聚焦,模型的注意力越集中——这是隔离有效的注意力机制依据。

第三,控制错误传播。 某个 Subagent 跑偏了、产生了幻觉,污染只留在它自己的上下文里,随它销毁。主 Agent 拿到的结果如果可疑,可以再派一个 Subagent 去复核。

隔离不是免费的:代价的定量感觉

隔离的反面是信息丢失。整个协作链条上只有两个通道:

上下文隔离的两个通道:Orchestrator 用完整任务说明书派活,Subagent 只回传结论摘要,信息压缩比约 100:1

  • 向下传递(派活):宁可多写。任务背景、目标、输出格式、边界约束,全写进任务说明书。写少了,Subagent 只能靠猜
  • 向上传递(交活):宁可是摘要。结论 + 关键证据 + 不确定的地方,别把整个探索过程原样回传。但摘要必然有损——Subagent 读了 5 万字,交回来 500 字,信息压缩比 100:1,被压掉的细节里可能就有主 Agent 需要的那条线索

这就是隔离的核心权衡:你用信息保真度换取了注意力质量。 压缩比越高,主上下文越干净,但「细节在压缩中丢失」的风险越大。缓解办法有三个:摘要里强制带「不确定项」字段(让 Subagent 自己标注丢失风险);主 Agent 保留追问通道(对可疑结论再派一个 Subagent 定向深挖);关键原始数据走旁路存储(Subagent 把全文存文件/数据库,只回传引用指针,主 Agent 需要时按需读取)。

另一个代价是合并冲突,前面已经说过:并行 Subagent 各自做决策,互相看不见,隐含的假设可能互相矛盾——这个问题在反方观点一节还会展开。


两个最小可跑的代码示例

下面这个 TypeScript 例子把 orchestrator-worker 的机制浓缩成几十行——重点是看每个 worker 的 messages 数组是全新的,这就是上下文隔离在代码里的样子:

type Message = { role: "user" | "assistant"; content: string };

// 伪化的 LLM 调用,实际项目里换成你的模型 SDK
declare function chat(messages: Message[]): Promise<string>;

// Worker:全新上下文,只拿到任务说明书
async function runWorker(brief: string): Promise<string> {
  // 注意:这里没有历史消息,messages 从零开始 —— 这就是隔离
  const messages: Message[] = [{ role: "user", content: brief }];
  return chat(messages); // 返回结论摘要
}

// Orchestrator:拆任务、派活、汇总
async function runOrchestrator(task: string): Promise<string> {
  const plan = await chat([
    { role: "user", content: `把任务拆成 3 个可并行的子任务,每行一个:${task}` },
  ]);
  const briefs = plan.split("\n").filter(Boolean);

  // 并行派活,每个 worker 互不可见
  const findings = await Promise.all(briefs.map(runWorker));

  // 只把摘要汇总进自己的上下文
  return chat([
    { role: "user", content: `综合以下调研结果,回答:${task}\n\n${findings.join("\n\n")}` },
  ]);
}

第二个例子聚焦「传递」:一份好的任务说明书长什么样,以及结果回传时怎么把「不确定项」强制留下来,对抗摘要的信息丢失:

interface TaskBrief {
  goal: string;        // 这个子任务要回答什么
  context: string;     // Subagent 干活所需的全部背景(它看不到对话历史)
  outputFormat: string; // 期望的输出结构
  boundary: string;    // 明确不做什么,防止跑偏和重复劳动
  budget: string;      // 工作量档位:如「最多 5 次搜索」
}

interface Finding {
  conclusion: string;
  evidence: string[];     // 关键证据 + 出处
  uncertainties: string[]; // 强制字段:被压缩掉的风险、存疑的地方
}

const brief: TaskBrief = {
  goal: "调研 A2A 协议的 Task 生命周期有哪些状态",
  context: "主任务是为团队选型 Agent 间通信协议,候选是 A2A 和自建 HTTP 接口",
  outputFormat: "状态列表 + 每个状态一句话解释 + 官方文档出处",
  boundary: "只看 A2A 官方规范,不要展开 MCP 或其他协议",
  budget: "最多搜索 3 次,10 分钟内完成",
};

真实的 Harness(比如 Claude Code 的 Subagent 机制)比这个复杂得多——worker 也有自己的工具集和 Loop、有步数上限、结果要校验——但骨架就是这些:隔离的 messages + 精心构造的 brief + 带回不确定项的摘要式回传


A2A:跨组织的 Agent 普通话

主从架构解决的是「一个系统内部」的多 Agent 协作。但如果两个 Agent 分属不同公司、不同框架、不同供应商呢?比如你的客服 Agent 想调用物流公司的查询 Agent——这就是 A2A(Agent2Agent)协议要解决的问题。A2A 是 Google 在 2025 年 4 月发起的开放协议,同年 6 月捐给了 Linux 基金会。

Agent Card:Agent 的名片

每个 A2A 服务端 Agent 在一个众所周知的地址(通常是 /.well-known/agent.json)发布一张 JSON 名片,让别的 Agent 发现自己。简化后的结构:

{
  "name": "物流查询 Agent",
  "description": "查询包裹的实时物流状态",
  "url": "https://logistics.example.com/a2a",
  "version": "1.0.0",
  "capabilities": { "streaming": true, "pushNotifications": true },
  "defaultInputModes": ["text"],
  "defaultOutputModes": ["text", "data"],
  "skills": [
    {
      "id": "track-package",
      "name": "包裹追踪",
      "description": "按运单号查询物流轨迹",
      "examples": ["帮我查 SF123456789 到哪了"]
    }
  ]
}

关键是 skillscapabilities:前者声明「我会干什么」(供对方 Agent 的 LLM 理解语义),后者声明「我支持什么交互方式」(流式、推送等,供协议层对接)。

Task:一次协作的生命周期

A2A 里一次协作被建模为一个 Task,有明确的状态机:

A2A Task 状态机:submitted 到 working 到 completed,working 可转入 input-required 追问循环,或落入 failed 等失败终态

过程中的追问和进度通过 Message(角色为 user 或 agent,内容由 Text/File/Data 三种 Part 组成)承载;最终交付物是 Artifact——比如那份物流轨迹报告。这个设计的意义在于:协作是异步、长耗时、可追问的,不是一次请求-响应就完事,所以协议必须有任务状态的概念。

A2A vs MCP:一张对照表

很多人会问:A2A 和 MCP 什么关系?它们解决的是不同方向的问题:

维度MCP(Model Context Protocol)A2A(Agent2Agent)
发起者Anthropic,2024 年底Google,2025 年 4 月
连接方向Agent → 工具/数据(垂直)Agent → Agent(水平)
对端是什么无自主性的工具、资源、提示词有自主 Loop 的另一个 Agent
交互模型请求-响应,调用即返回Task 状态机,异步长任务、可追问
发现机制客户端连上 server 后列举 toolsAgent Card 名片,可公开发布
典型场景读数据库、调内部 API、操作文件跨公司/跨框架的 Agent 协作

一个完整系统里两者是互补的:你的 Orchestrator 通过 A2A 联系外部 Agent,通过 MCP 使用本地工具。现实是 A2A 还很年轻,生态远没有 MCP 成熟,了解概念即可,不必急着上生产


反方观点:Cognition 的「上下文共享悖论」

就在 Anthropic 发 Research 系统复盘的同一周,Cognition(Devin 的团队)发了一篇针锋相对的《Don't Build Multi-Agents》。他们的核心论点值得认真对待:

原则一:共享上下文,而且要共享完整的 Agent 轨迹,不只是消息。 一个 Agent 的每个行动都隐含着决策;只看结论消息,会丢掉「为什么这么做」的推理过程,后面的 Agent 可能做出与前文矛盾的假设。

原则二:行动承载隐式决策,冲突的决策导致坏结果。 并行 Subagent 各自独立决策——Subagent A 决定用 Flask,Subagent B 决定用 FastAPI,各自写完代码交回来,合并时才发现两个 Web 框架打起来了。主从架构里这种「隐含假设冲突」几乎不可避免。

所以 Cognition 的结论倾向于:长任务优先用单 Agent + 上下文压缩,把超长的历史压缩成结构化笔记续跑,而不是拆给多个上下文互不相通的 Agent。

怎么调和两家的矛盾?其实他们不矛盾,只是场景不同:

  • 广度优先、弱耦合的任务(调研 10 个独立话题):子任务之间几乎没有共享决策,隔离的代价小、收益大 → 多 Agent 赢(Anthropic 的场景)
  • 深度优先、强耦合的任务(连续改同一个代码库):每一步决策都依赖上一步的全部细节,拆开会丢掉关键上下文 → 单 Agent + 压缩更稳(Cognition 的场景)

判断标准还是回到本章主线:你的任务拆开后,子任务之间需要共享多少隐含上下文? 需要得越少,多 Agent 越划算。


工程实践要点

  • 从单 Agent 开始:先把单 Agent 的 Harness 打磨好,碰到上下文撑爆的具体痛点,再上多 Agent。为拆而拆只会得到一堆互相干扰的 Agent
  • Subagent 数量要克制:Anthropic 的经验是 3-5 个并行 Subagent 是甜区,再多收益递减、成本陡增
  • 给每个 Subagent 设资源上限:最大步数、最大 token、超时,缺一不可——一群失控的 Agent 烧钱速度也是并行的
  • 结果要有兜底:Subagent 可能失败或返回垃圾,Orchestrator 要能重派、降级或放弃
  • 可观测性先行:多 Agent 的调试难度是指数级上升的,每个 Subagent 的完整 trace 必须可回放
  • 记账:15 倍 token 不是修辞,上线前先把单次任务的成本上限算清楚

常见误区

  • 「人多力量大」思维:以为 Agent 越多系统越强。实际上每多一个 Agent,就多一份协调成本和 token 开销。多 Agent 是为了上下文隔离,不是为了热闹
  • 给 Subagent 传太少上下文:一句「帮我查一下」就派出去,Subagent 只能靠猜。任务说明书要写到「空降兵也能直接上手」的程度
  • 让 Subagent 直接对话:两个 Subagent 互相聊天,上下文各自独立,鸡同鸭讲。协调必须通过 Orchestrator 中转(或引入 A2A 这类有状态协议)
  • 强依赖的任务硬拆:步骤之间有严格先后依赖的任务(改同一文件的连续重构),拆给多个 Agent 只会制造合并冲突
  • 忽视摘要的信息丢失:以为 Subagent 回了摘要就万事大吉,忘了压缩比可能是 100:1。关键细节要走旁路存储或追问通道
  • 把辩论当万能校验:群体辩论能提升可靠性,但每个角色都是同一个模型时,系统性偏见会被投票放大而非消除

术语表

名词定义一句话直觉常见混淆
Orchestrator负责拆解、分派、汇总的主 Agent不干活的项目经理不等于「最强的模型」,它的核心能力是拆任务
Subagent在独立上下文中执行子任务的 Agent被空降的执行者不是工具调用:工具无自主性,Subagent 有自己的 Loop
Handoff把任务连同上下文整体移交给另一个 Agent换岗交接,连工作日志一起交与派 Subagent 相反:Handoff 移交上下文,Subagent 隔离上下文
上下文隔离每个 Subagent 拥有全新、互不可见的上下文窗口一人一间干净办公室不是「信息越多越好」,隔离是注意力管理手段
Context Rot(上下文腐烂)上下文变长变杂后模型表现下滑的现象书桌堆满废纸后找不到笔不是窗口溢出报错,是无声的质量衰减
任务说明书(Task Brief)Orchestrator 派活时给 Subagent 的完整任务描述空降兵的生存手册不是一句话指令,必须自包含背景和边界
Pipeline(流水线)步骤预先写死、输出依次传递的多步模式工厂传送带不是 Agent 协作,是工作流,自主性最低
Router(路由器)先分类、再分发给对应专家 Agent 的模式总机转接只解决入口分发,Agent 之间不协作
群体辩论(Debate)多 Agent 各自作答、互相修正、投票收敛的模式评审会同一模型的多实例辩论会放大而非消除共同偏见
SwarmOpenAI 的开源教学框架,主打轻量 Handoff多 Agent 的「Hello World」是教学项目不是生产框架,名字也泛指蜂群式架构
A2AGoogle 发起的 Agent 间开放协议,已捐给 Linux 基金会Agent 之间的普通话与 MCP 不竞争:A2A 连 Agent,MCP 连工具
Agent CardA2A 中声明 Agent 能力的 JSON 名片店门口的招牌菜单不是身份认证凭证,它解决的是「发现」不是「信任」
MCPAnthropic 发起的模型连接工具/数据的协议Agent 的 USB-C 接口对端是无自主性的工具,不是另一个 Agent
LLM-as-judge用 LLM 按评分细则给开放任务打分的评估法请 AI 当阅卷老师不能替代人工抽检,评分细则本身需要校准

参考材料


小结

多 Agent 系统不是「一群 AI 开会」,而是一套上下文管理策略:Orchestrator 拆任务、写说明书;Subagent 在隔离的干净上下文里专注干活;结论以摘要形式回流。隔离保护双方的注意力,代价是信息丢失与合并冲突;传递决定协作的质量。Anthropic 用 15 倍 token 换来 90% 的性能提升,Cognition 则提醒你强耦合任务别硬拆——分歧的表象下是同一条判断标准:子任务之间需要共享的隐含上下文越少,多 Agent 越划算。下一章我们会看 Agent 的另一个资源瓶颈:记忆。