目录

Anthropic:先别急着拆子 agent

https://leafw-blog-pic.oss-cn-hangzhou.aliyuncs.com/fold-subagents-single-loop-cover.png

前几天写过一篇并行子 agent 的论文解读,结论是短任务上开并发普遍掉分,长任务有涨有跌。10 月 22 日,Anthropic 在 Claude 官网发布了一篇文章《Building agents: When to fold subagents into your main agent loop》,作者是 Anthropic 的 Diane Sarkis,讲什么时候该把子 agent 折回主循环,也就是把子 agent 的提示词和能力并进主 agent,变成它的 skill 和工具。

文章开头先肯定了子 agent:它们在验证、并行工作和按模块划分权限上很好用,Anthropic 内部不少 agent 也在用,比如多 agent 研究系统。但 Anthropic 的 Applied AI 团队在企业的 agent 部署里反复看到,把路由、规划器和各领域子 agent 折回主循环之后,效果更好。按文章的说法,在他们比较过的几家企业部署里,带 skill 的单 agent 在质量上常常同时胜过「一个提示词包办一切」和「拆成子 agent」两种设计,每个任务的成本和延迟也往往更低。

全文绕着一个问题:拆出去的每个子 agent,都要拿得出证据说明它为什么需要单独的上下文。

接下来大致按照背景、主张、迁移方法、工具包、启发和局限的顺序拆一遍。

背景:拆分从哪来

架构照着组织长

文章描述的起点很常见:公司想用一个统一的客户入口串起多个产品,每块能力归一个团队,于是各团队先各做一个 agent,再由中央平台团队在上面搭编排层。形式可以是编排 agent 调度子 agent,也可以是主 agent 把各团队的 agent 当成 MCP 工具来调。MCP 是 Model Context Protocol,一种把外部工具和数据接到模型上的开放协议。

文章认为这样看着简单,复杂度马上就来了,它列了五种问题:

  • 上下文管理:每次都要决定 agent 之间传什么,来回传递里细节会丢;
  • 子 agent 泛滥:每个团队都交付自己的子 agent,最后可能有几百个功能重叠的子 agent,没有统一标准,也没有明确的负责人;
  • 拼凑的系统提示:每个团队往系统提示里加一句,规则互相冲突,语气也不一致,原文管它叫 Frankenprompt;
  • 评测各自为政:每个团队只给自己的子任务加评测,整套评测没人维护,管理层看到的是被稀释、过于局部的分数;
  • 延迟:多 agent 结构本身会拖慢响应。有一位客户把多 agent 方案和单 agent 循环做了对比,后者运行时间快了大约 2 倍。

文章开头还举了个例子:一家公司面向客户的 agent 里有十来个专家子 agent,品牌语气很难保持一致,多出来的延迟也伤了用户体验。文章把这类拆分归到康威定律上:太多企业给每个团队、每类问题各配一个子 agent,agent 架构就成了组织架构图的翻版。

五层结构和一个循环

文章还描述了一种常见的方案演进,下图是原文配的对照图。

https://leafw-blog-pic.oss-cn-hangzhou.aliyuncs.com/fold-subagents-five-layer-architecture.png

左边是常见做法:请求先进多 agent 编排器,经过意图分类器和编号 1 到 5 的固定推理流水线,分进三个用户群桶,各走推荐分支,最后汇成答案,标题是「模型外面套了 5 层结构」。右边是他们常推荐的做法:一个清晰的系统提示、一个模型、四五个只负责取数据的轻量工具,外加一道严格的输出护栏,标题是「1 个循环」。文章说,这类方案得到的反馈往往是:大部分结构在替模型做它已不需要代劳的事,右边这套就够覆盖多数场景。

文章的主张

一个循环加渐进式披露

文章推荐的做法是渐进式披露:通过 skill 渐进地披露上下文,通过工具搜索渐进地披露工具。agent 平时只看到每个 skill 和工具的简短描述,用到时才加载完整内容。skill 是 Anthropic 的一种能力打包方式,一个文件夹里放说明文档和可选脚本,模型先看名字和一两句描述,需要时再读全文;工具搜索是同样的思路用在工具定义上。

文章给了三条理由。

第一,共享上下文的答案更好。对运行较久的 agent,多个任务的上下文最好都留在主上下文窗口里。见过前面每一步结果的 agent 能把它们串起来,比几个子 agent 各交回一份摘要得出的结果更丰富,有损的交接也更少。

第二,渐进式披露能防止上下文膨胀。不用把所有内容一次性塞进很长的系统提示,单个 agent 也能处理各种任务,这就去掉了团队过去拆子 agent 的主要理由。文章给的数字是:Anthropic 把 Claude Code 面向更强模型的系统提示削减了 80% 以上,其中包括渐进式披露 skill 和工具带来的删减。

第三,模型更强了。文章说从 Opus 4.5 开始,模型在单个循环里能处理的东西远超多数团队的预期;近来的模型也越来越会边做边汇报、边检查,harness 里一些部件因此多余。循环越简单,换下一代模型越容易。文章提到,在他们帮客户做过的迁移里,僵硬的多 agent 结构常常就是新模型没法多承担工作的原因。

单循环也有代价:系统提示要精心维护,skill 和工具的描述要在对的时机触发,上下文窗口、记忆和笔记都要专门处理。文章的安排是由一个中央团队负责端到端质量和系统提示,每个新工具、新评测上线前都由它审核,团队要小。

单循环长什么样

文章给出的目标形态是:一个模型、一个上下文窗口,跑一个开放式的工具循环,回合数、成本预算和写操作审批这些限制放在 harness 里。每一轮模型发出一批工具调用,harness 并行执行,把原始结果交回同一个模型,由它决定再发一批、问用户一个问题,还是给出答案。模型答完或预算耗尽时循环停止,之后可以再跑一道验证。模型在第一轮把计划写进上下文,随结果不断修改。文章说这是相对编排模式最主要的变化:写计划的和执行计划的是同一个模型,所以能在中途改计划。

原有的部件各有去处。那段按一套规则改写计划的代码可以删掉,每一步由模型自己决定;顺序和领域流程放进 skill;校验、审批关卡这类硬性限制,以及对话中途才用到的东西(比如查记忆),放进工具。代码仍可预先加载便宜又几乎总要用的内容,比如实体解析,也在工具内部处理拼装请求这类机械活。

子 agent 留给谁

文章明确说子 agent 仍有用处,在前沿研究里也还在用。它列了三种该用的情况:

  1. 单 agent 循环因为上下文膨胀出现了可测量的性能退化;
  2. 多个任务需要并行处理,每个任务用一个全新的上下文窗口,做完就丢掉;
  3. 单个 agent 难以选对工具,或者系统提示里的指令互相冲突。

确实要走多 agent,文章建议从最简单可行的模式起步,比如生成者加验证者,并且按上下文划分边界:交给每个子 agent 的工作只需要系统其余部分的很少信息,交回一个紧凑的结果。它点名的合适场景是独立的研究路径、接口清晰的独立组件、只看结果的黑盒验证。按问题类型拆分则会变成传话游戏,每交接一次就失真一点。下图是原文给的例子。

https://leafw-blog-pic.oss-cn-hangzhou.aliyuncs.com/fold-subagents-split-by-problem-vs-context.png

上半部分按问题类型拆:agent 1 写功能,交给 agent 2 写测试,再交给 agent 3 审代码,图注说每次交接都丢上下文,写测试的 agent 不知道实现时为什么那样决定。下半部分按上下文拆:一个 agent 既写功能又写测试,因为上下文本来就在它手里;另一个验证者只跑测试、报告结果,用不着实现时的上下文。

这和前面那篇论文能对上。论文里并发带来收益的三种情况是互补分工、并行尝试再挑选、独立验证,和文章列的场景很接近;它的失败分类里有一类「全局上下文」,占全部失败实例的 9.3%,说的就是各自干活的 agent 缺了把工作接起来所需的信息。

至于由子 agent 接管整段对话的完整交接,文章只建议用在它必须直接和用户对话的时候,其余都可以换成主循环里的 skill 加工具。

迁移怎么做

迁移路径可以画成下面这张流程图,根据原文和配套工具包整理:从建评测、跑基线开始,经过合并或包成工具,再把子 agent 逐个折进主循环,每折一个比一次评测;变差就先修,修完仍然更差,才退回,把这个子 agent 留作工具调用。

https://leafw-blog-pic.oss-cn-hangzhou.aliyuncs.com/fold-subagents-migration-flow.png

先建评测

第一步是建一套评测,用一组任务给系统打分,判断该不该折某个子 agent。文章见过行之有效的结构是:一套共享的端到端评测归中央团队,各团队再随自己的 skill 附上小评测集。10 个带标准答案的样例就够起步。

打分可以先用评分细则给最终回复打分。还有编排器时,同时跟踪路由准确率,看有没有选对子 agent;折进去之后,改成看 agent 有没有加载对 skill、调对工具。长期目标是任务完成度评测,比较不同架构时这个最重要。内部系统的环境难以重放时,文章提到 Anthropic 内部的一个办法:给重要事件记下时间戳,之后重放,当作有针对性的评测来跑。

合并、包成工具、折进去

往单循环演进,就是把子 agent 逐步变成工具和 skill。文章给了三种做法,下图是原文示意。

https://leafw-blog-pic.oss-cn-hangzhou.aliyuncs.com/fold-subagents-merge-as-tool-fold.png

左栏是合并:主 agent 下面原来挂着 A、B、C、D 四个子 agent,共享上下文的两两合并成 A+B 和 C+D。文章建议从使用最多的开始合并,对象是三类:一个依赖另一个的输出、读写同一份数据、经常被一起调用。

中栏是把子 agent 当工具调用:主 agent 通过工具调用拿回每个子 agent 的结果,自己继续掌握对话。这样可以给子 agent 定统一的返回格式,由主 agent 拿真实数据核对结论。这一步不用重写子 agent,文章认为适合当第一步,也能在折叠之前拿到基线。但问题还在:每个专家仍有自己的提示词、上下文、负责团队和评测;每次调用交回的仍是有损的摘要;每次调用都是一个嵌套的模型循环,会增加延迟。

右栏是折进 skill 和工具:子 agent 的提示词变成主 agent 的 skill,API 调用变成 MCP 工具。文章的做法是一次折一个,对比有没有这个子 agent 时的评测结果,再决定留哪些。

看哪些任务翻转

比较时,文章提醒别只看总分,要看哪些任务翻转了,也就是原来通过的变成失败,或者反过来。Anthropic 在一个示例客服 agent 上试过:把一个子 agent 折进另一个之后,延迟降了,却弄坏了一个原本通过的流程。主 agent 手里有了查订单的工具,就自己回答了,没去问物流专家要送达日期。

所以每次改动前,评测里要有任务覆盖生产中每一条连着跑的 agent 链,以及 agent 绝不能违反的每一条规则;每个任务要跑不止一次,因为上面那个问题在两次运行里只出现了一次。

多团队怎么分工

折完之后,各团队的职责从维护 agent 变成维护 skill 和工具,中央小团队继续管系统提示和端到端质量。文章按三种载体分工。

MCP 工具适合执行动作、读实时数据、返回固定格式的结果。文章建议按用户意图给工具分组,别一个 API 对应一个工具,因为系统提示里的工具定义超过 30 到 50 个时,选工具的效果往往变差。要配合工具搜索和延迟加载,必要的前置条件放进工具里检查:比如 Y 需要 X 的输出,就让 Y 的工具自己检查,缺了就返回一条模型能照着做的提示。权限也一样,每个工具检查调用它的用户能看什么、做什么,不允许就返回一句模型读得懂的拒绝,一个循环就能服务权限不同的用户。

skill 承载团队的做事方式,也就是原来写在专家子 agent 提示词里的步骤、规则和判断标准。为防止 skill 泛滥,文章建议每个团队指定直接负责人,保证 skill 写得好、互不重叠、附带评测。文章还提到两个 Claude Code 命令:/skill-creator 由官方插件提供,用来写出结构规范的新 skill,也能审计已有 skill,做精简、去重和重组;/skill-doctor 用来看库里每个 skill 的成本和实际使用频率,删掉没用的。

知识库放 agent 偶尔才需要的参考资料,比如政策、指标定义、产品规格,可以放在模型自己调用的查询工具后面,或者作为 skill 里的参考文件。文章特别说,避免由代码检索这些内容再贴进提示词。

这条有个外部案例可以对照。Skyvern 是一个开源的浏览器自动化框架,联合创始人兼 CEO Suchintan Singh 在 10 月 1 日的博文里写,他们去掉了由代码先截图、把网页压缩成元素列表再交给模型的预处理,改成让 agent 从最少的上下文出发,自己按需扫描 HTML 和截图。按他们在约 10 万次生产运行上的 A/B 测试,平均运行时间从 593 秒降到 262 秒,模型调用从平均 6.4 次增加到 23 次,每次调用的 token 从 2.9 万降到 1.2 万。

工具包里有什么

文章配套的 anthropics/single-agent-loop-kit,README 写明是参考实现,不维护、不收贡献。主体是一个 Claude Code skill,外加四个脚本、一个参考循环和一个能跑的示例。

六个步骤和四次停顿

把 skill/ 目录复制到自己 agent 仓库的 .claude/skills/ 下,在 Claude Code 里让它运行,它按六步走:审计、基线、合并、折叠、作为工具保留、日常维护。

审计给每个 agent 定一个结论:main(路由或编排器,将来变成单循环)、fold(默认,折成 skill 和工具)、merge(和另一个合并)、as-tool(保留独立上下文,作为工具调用)、keep(必须自己和用户多轮对话,或归外部公司所有)。判断子 agent 配不配独立上下文,步骤文件给了三条标准,满足一条即可。第一条比文章更具体:每次调用要读几万 token 级别的内容才算,几千不算,而且要先问工具能不能少返回一点;另外两条是并行或独立的工作,以及靠 skill 也解决不了的工具过多或指令冲突。它还列了几条不算理由的情况:归另一个团队管、有自己的人设、提示词长、工具多、步骤固定。固定步骤就是工作流,写成代码放进工具。

折叠时,子 agent 的提示词逐行分到五处:流程和领域知识进 skill;硬性限制进工具,由代码强制执行;参考资料进参考文件或查询工具;人设和问候语删掉,语气归主系统提示;为旧模型写的指令,比如大写强调、「一步一步想」,也删掉。

整个过程有四个固定停顿:审计之后、第一次花钱跑评测之前、基线之后、每次改动之后,每次都汇报发现、建议和一个要人回答的问题。评测的 token 由使用方自己出,花钱前要给出估算,README 建议从 10 个任务、每任务两三次开始。基线步骤还要求列一张破坏清单,规则丢失、主 agent 走捷径、选错工具、多出不该有的写操作、多轮对话断线等,适用的每一种都要有能发现它的任务;成本悄悄上涨和路由漂移两类不设任务,靠对比结果里的 token 和路径变化来看。

示例:一个虚构的客服台

examples/support-desk 是虚构家电零售商 Tamberwick Home 的客服 agent:一个路由加六个子 agent,管订单、物流、退货、账户、设备诊断和理赔。每个子 agent 都设计成有已知的正确结论,答案在 ANSWER-KEY.md 里。

路由的系统提示就是典型的拼凑提示:开头大写写着绝不能自己回答、必须转给专家;各团队的规则互相打架,订单团队说先调订单再调物流,物流团队说问送达时间先找物流。退货子 agent 有个叫 Remy 的热情人设,和品牌语气对不上;30 天退货期这类硬性限制只写在提示词里,后端并不检查。

答案表的预设结论是:订单和物流合并后再折叠,200 条合成轨迹里有 96 条调用了物流,每次都紧跟在订单后面;退货和账户折叠;设备诊断作为工具保留,因为它每次调用都读一份 900 行的设备日志,约 3 万输入 token,其他子 agent 只有 1,000 到 3,000;理赔保留完整交接,因为它由保险公司运营,要和客户多轮对话。

single_loop/ 是做完之后的终态:一个循环、一个退货 skill、八个工具、一个作为工具调用的诊断子 agent、一个转给理赔的交接。工具按用户意图重组,原来订单和物流两步,现在一个 track_order 就返回状态、承运商和预计送达。每个写操作都要过审批关卡。

两次真实运行

example-run/ 存了两次真实运行的记录,都是同一位使用者、一个模型(claude-opus-5)、每个任务跑两次。README 说运行后删掉了说明文字里的测量结论,但原始结果和轨迹都在,用 compare.py 能直接读出来。

第一次是 10 月 8 日,在 12 个任务上把退货子 agent 折进主循环。完成任务从 11.0/12 到 11.5/12,平均延迟从 27.3 秒降到 19.4 秒,模型调用从 6.3 次降到 4.8 次,输出 token 少了 32%。跨领域的 t11 从两次都失败变成都通过;问订单状态的 t01 却有一次失败。那次失败的轨迹里,主 agent 用刚拿到的查订单工具查到订单已发货,就回复说还没有送达日期,没去调物流子 agent,评测要求的 10 月 3 日没出现。我的理解是,文章里那个客服例子说的就是这一次:延迟降了,t01 坏了,两次里只出现一次;工具包的折叠步骤文件也写到,这个问题是在它自己的示例运行里暴露的。

第二次是 10 月 9 日,在 17 个任务上只把设备诊断子 agent 改成工具调用。完成任务从 16.0/17 到 15.5/17,又是 t01 一次失败,脚本判定「比基线差」。Claude Code 没有直接建议保留或退回,提议给 t01 和 t10 两边各补跑 4 次,共 16 次对话;补跑后两边全部通过,使用者保留了改动。

参考循环

reference_loop/loop.py 不到 300 行,按文章描述实现单循环。默认预算是最多 25 轮、40 万 token(子 agent 花的也算)、每轮最多 16 个工具调用。读操作并行,写操作在读完后按顺序逐个执行;只要有工具会写数据,就必须传入审批函数,否则直接报错。skill 只把名字和描述列进系统提示,模型用 load_skill 加载正文;延迟加载的工具走工具搜索。验证器只给一次修改机会,被否决两次的答案不返回给用户。

启发

结合文章和工具包,落到日常搭 agent 上,可以整理成几条:

  1. 新系统先从一个循环开始。工具包 README 建议,还没有子 agent 就从一个循环起步,测试表明需要时再加工具和 skill。
  2. 拆子 agent 之前,先对照那三种情况。提示词长、工具多都不算理由,分别交给 skill 按需加载和工具搜索;归别的团队管也不算,所有权可以转到 skill 和它的评测上。
  3. 硬性限制写进工具。退货期限、不许读出地址这类规则留在提示词里,折叠时最容易丢;放进工具由代码检查,再写单元测试证明它会拒绝。
  4. 评测按结果打分。工具包要求看系统里发生了什么变化、用户被告知了什么,路径检查在架构一变时就失效。
  5. 每个任务至少跑两次,盯住翻转的任务。示例里只看总分(11.0 到 11.5),会以为改动全是好处。

代价落在不同人身上:子 agent 多,延迟和交接丢掉的信息落在用户身上;折回单循环,守纪律的是中央团队,评测的 token 由做迁移的团队出,评测漏掉的链断了,还是用户承担。

局限

  • 关键数字的证据偏少。约 2 倍的运行时间来自一位客户,「质量常常更好」来自几家企业部署,文章没有给出评测分数、任务类型和样本量。
  • 80% 说的是 Claude Code 面向更强模型的系统提示,文章只说其中「包括」渐进式披露带来的删减,没拆出占多少。
  • 工具包的两次真实运行都是同一位使用者、一个模型、每任务两次,第二次靠补跑才定下结论。README 列出的没在真实模型上跑过的部分有:合并和维护两步、single_loop/ 终态、t18 和 t19 两个任务、从零建评测的流程,以及示例以外的任何系统;第二次运行后 skill 的措辞也改过,还没有人按新措辞跑过。
  • 文章和工具包有出入。文章说包成工具适合当第一步;工具包的工作清单是先合并、再折叠、最后工具化,折叠失败的也改成工具化。文章建议折叠后检查有没有加载对 skill、调对工具,工具包则只按结果打分,路径变化单独列出来人工看。
  • 文章的例子主要是企业里面向客户的 agent,对前沿研究只说子 agent 还在用,没有展开。长任务上该不该拆,文章没有回答;前面那篇论文测到的结果是有涨有跌。

写在最后

和前面那篇论文放在一起看,说的是同一件事。论文里最多的三种失败是子 agent 开太多耗光预算、过早被终止、交付物被覆盖,都和主 agent 怎么派活、怎么收尾有关。Anthropic 这篇文章给的办法,是先用评测确认某个子 agent 确实需要单独的上下文,拿不出证据的就并回主循环,由 skill 和工具接手它原来的工作。搭 agent 时可以先从一个循环起步,等评测测出退化,再考虑往外拆。

参考资料