"子 Agent"这个词在多 Agent 系统的讨论中频繁出现,却鲜有人把它说清楚。它是一个能力弱化的 Agent,类似一个 Agent 化的工具?还是一个拥有更小上下文的原始 Agent,像从主 Agent fork 出来的进程?还是一个在指挥体系里听从领导 Agent、但拥有更强资源和能力的 Agent?

这三种直觉都不完全准确。本文从 Anthropic、LangChain、Claude Code 等权威来源出发,厘清子 Agent 的真实本质,并探讨一个更深层的问题:"子 Agent"究竟是能力描述,还是关系描述?

子 Agent 的上下文隔离与专门化

三种直觉,三种误解

在深入定义之前,先把三种常见直觉逐一检验。

误解一:子 Agent 是能力弱化的 Agent

这种直觉来自于"子"字的字面含义——子集、子系统、子进程,往往意味着更小、更弱。但 LangChain 官方文档明确指出:

“An interesting aspect of this approach is that sub-agents may have the exact same capabilities as the main agent.”

子 Agent 可以拥有与主 Agent 完全相同的能力。它不是弱化版,不是受限版,更不是"工具的高级包装"。

误解二:子 Agent 是拥有更小上下文的 fork

这种直觉来自操作系统的进程模型——子进程从父进程 fork,继承部分状态,但资源受限。这个类比有一定道理,但关键词不是"更小",而是"独立且干净"。

Anthropic 官方工程博客描述其多 Agent 研究系统时写道:

“Subagents facilitate compression by operating in parallel with their own context windows, exploring different aspects of the question simultaneously before condensing the most important tokens for the lead research agent.”

子 Agent 拥有独立的上下文窗口(own context windows),而不是主 Agent 上下文的子集。这个上下文窗口是全新的、干净的,不是"更小的"。

误解三:子 Agent 是听从指挥但能力更强的下属

这种直觉来自军事或企业的层级模型——将领指挥士兵,但士兵在具体战术上可能比将领更专业。这个类比在某些场景下成立,但它把"子 Agent"理解成了一种永久的身份,而非一种临时的关系

真正的问题在于:一个 Agent 是否是"子 Agent",取决于它在当前任务中的角色,而非它的固有属性。

子 Agent 的真实本质

综合 Anthropic、Claude Code、LangChain 的权威定义,子 Agent 的本质可以用一句话概括:

子 Agent 是一个完整的、专门化的 Agent 实例,运行在独立的上下文窗口中,由主 Agent 通过工具调用方式协调,其核心价值在于上下文隔离,而非能力弱化。

四个核心特征

1. 上下文隔离

这是子 Agent 最核心的价值。LangChain 的表述最为精辟:

“This provides context isolation: each subagent invocation works in a clean context window, preventing context bloat in the main conversation.”

每次调用子 Agent,都是在一个干净的上下文窗口里开始工作。主 Agent 的历史对话、工具调用记录、中间推理过程,都不会污染子 Agent 的上下文。这防止了主 Agent 的上下文膨胀(context bloat)。

2. 完整的 Agent 能力

子 Agent 不是工具(Tool)。工具是单一功能的函数,被动执行,没有决策能力,没有 Agent Loop。子 Agent 是完整的 Agent 实例,拥有:

  • 独立的推理-行动循环(Agent Loop)
  • 自主规划和决策能力
  • 多步骤任务执行能力
  • 执行期间的短期记忆

3. 调用连续性由产品契约决定

新建的普通子 Agent 通常从干净 context 开始,但“子 Agent 一律无状态”不是稳定结论。Claude Code 的 custom 与 general-purpose subagent 可以恢复已有会话并保留完整对话;Explore 和 Plan subagent 是一次性执行。外部进度、artifact 和验证证据仍应由可持久化状态承接,不能只依赖某个产品的 resume 能力。

4. 专门化任务处理

子 Agent 通过自定义 system prompt 定义专门职责,可以针对特定领域优化。这种专门化不是能力的限制,而是能力的聚焦。

把上面四点放到一张图里,子 Agent 的工作机制就是:

flowchart LR
    subgraph Main["主 Agent 上下文窗口"]
        M["主 Agent<br/>(编排者)"]
        Mem["对话历史<br/>工具调用记录<br/>中间推理过程"]
    end

    subgraph Sub["子 Agent 上下文窗口 (clean)"]
        S["子 Agent<br/>(专门化执行)"]
    end

    M ==>|"① 最小化任务 prompt<br/>目标 · 约束 · 输出格式"| S
    S ==>|"② 压缩后的结果摘要"| M

    style Mem fill:#fff3cd,stroke:#856404,color:#333
    style Main fill:#fef9e7,stroke:#856404
    style Sub fill:#d1ecf1,stroke:#0c5460

主 Agent 把"对话历史、工具记录、中间推理"这些消耗上下文的内容留在自己的窗口里,只把任务必需的最小信息发出去;子 Agent 在干净窗口里完成任务后,回传的也只是结果摘要而非全过程。这就是"上下文隔离"的物理含义。

递归派发是版本化能力

Claude Code 早期不允许子 Agent 继续派发,当前文档已经更新:从 v2.1.172 起支持嵌套 subagent,最大深度为 5。这个限制仍用于控制递归成本和编排复杂度,旧版的不可嵌套结论已经过时。

递归深度、并发数和哪些内置 Agent 可以继续委托,都属于产品版本契约。LangGraph 则通过 graph 与 subgraph 组织嵌套执行。是否允许递归派发不能用来定义子 Agent 的本质。

与此形成对比的是 Skill 机制。Skill(如 Claude Code 中的 SKILL.md)本质上是系统提示的动态扩展,而非 Agent 实例的创建。当一个 Skill 被触发时,它的内容被加载到当前 Agent 的上下文中,Agent 按照 Skill 的指令行动。整个过程发生在同一个上下文窗口内。因此,Skill A 可以触发 Skill B,Skill B 可以触发 Skill C,形成多层调用链——这是上下文内的行为扩展,不涉及新 Agent 实例的创建,受上下文窗口容量约束。

概念 本质 调用链能力
子 Agent 完整的 Agent 实例,通常拥有独立上下文窗口 取决于平台和版本(Claude Code 当前最大深度 5)
Skill 系统提示的动态扩展 可以形成多层调用链(受窗口容量约束)

两种调用链的机制差异可以直观对照:

flowchart TB
    subgraph A["子 Agent 派发:每层一个独立上下文窗口"]
        direction TB
        A1["主 Agent · 上下文 #1"]
        A2["子 Agent · 上下文 #2"]
        A3["孙 Agent · 上下文 #3"]
        A1 ==>|"创建新实例"| A2
        A2 -.->|"Claude Code 当前允许<br/>最大深度 5"| A3
    end

    subgraph B["Skill 调用链:始终在单一上下文窗口内"]
        direction TB
        B0["Agent 上下文窗口 (唯一)"]
        SkA["Skill A"] -.->|"加载到"| B0
        SkB["Skill B"] -.->|"加载到"| B0
        SkC["Skill C"] -.->|"加载到"| B0
    end

    style A fill:#fdecea,stroke:#c0392b
    style B fill:#e8f5e9,stroke:#27ae60

这个区别揭示了一个设计原则:Agent 实例的创建是重量级操作(需要独立上下文窗口),各平台倾向于约束它;而上下文内的行为扩展是轻量级操作,可以自由组合。

"子 Agent"是关系描述,不是能力描述

当我们说某个 Agent 是"子 Agent"时,我们描述的是它在当前任务中与其他 Agent 的关系,而不是它的固有属性或能力等级。

以 Oh My OpenCode 的 Agent 团队为例:

1
2
3
4
5
6
7
8
用户请求

Sisyphus(主编排器)
├─→ Hephaestus(深度工作)
├─→ Prometheus(战略规划)
├─→ Oracle(架构咨询)
├─→ Librarian(文档研究)
└─→ Explore(代码搜索)

在这个架构图里,Prometheus、Oracle、Librarian 看起来是 Sisyphus 的"子 Agent"。但这个判断是错误的,或者说是不完整的。

Prometheus、Oracle、Librarian 都可以独立运行。

  • 用户可以直接对话 Prometheus,让它制定战略规划,完全不经过 Sisyphus
  • 用户可以直接调用 Oracle 进行架构咨询
  • Librarian 可以作为独立的文档研究 Agent 被任何工作流调用

它们之所以在某些场景下表现为 Sisyphus 的"子 Agent",仅仅是因为 Sisyphus 在那个特定的任务中扮演了编排者的角色,通过工具调用的方式协调了它们。一旦任务结束,这种"主-子"关系就消失了。

这与传统软件工程中的"子系统"概念截然不同。子系统是静态的架构关系,一旦被设计为子系统,就永远是子系统。而 Agent 的"主-子"关系是动态的、任务级别的

类比:项目中的角色 vs 职位

一个更直观的类比:

在一个软件项目中,张三是"项目经理",李四是"开发工程师"。但在另一个项目中,李四可能是项目经理,张三是开发工程师。他们的职位(固有属性)没有变,但他们在不同项目中的角色(关系描述)是不同的。

Agent 的"主-子"关系正是如此。Prometheus 的固有属性是"战略规划专家",但它在不同的任务中可以是:

  • 独立运行的规划 Agent(直接与用户对话)
  • Sisyphus 的子 Agent(被 Sisyphus 通过工具调用协调)
  • 某个更高层编排器的子 Agent(在更复杂的多层架构中)

子 Agent vs Tool:本质区别

既然子 Agent 不是弱化的 Agent,那它和 Tool 的区别是什么?

维度 Tool 子 Agent
本质 单一功能的函数/方法 完整的 Agent 实例
上下文 无独立上下文 拥有独立上下文窗口
决策能力 无,被动执行 有,可自主规划
循环能力 拥有 Agent Loop(推理-行动循环)
记忆 执行期间有短期记忆
复杂度 单步操作 多步骤复杂任务
状态 由调用方管理 执行期间有状态;跨调用连续性取决于 resume 与外部状态契约

何时用 Tool,何时用子 Agent?

  • Tool:任务是单步的、确定性的、不需要推理的(读文件、执行命令、调用 API)
  • 子 Agent:任务需要多步骤推理、需要上下文隔离、需要专门化处理

上下文隔离的代价

上下文隔离不是免费的。每次创建子 Agent 都意味着:

  • 信息损失:协调者必须在 prompt 中显式传递所有相关上下文,压缩过程不可避免地丢失细节。子 Agent 不知道"之前发生了什么",它只知道 prompt 告诉它的内容。
  • 延迟与成本:每个子 Agent 调用是一次完整的 API 请求,有网络延迟和额外的 token 消耗。
  • 协调开销:任务拆分、结果汇总、异常处理都需要协调者的额外上下文空间。

因此,上下文隔离是一种权衡:用信息传递的精确性换取上下文空间的清洁。任务越复杂、上下文污染风险越高,这个交换越值得;任务越简单,直接在主 Agent 内处理的效率越高。

实践含义

理解子 Agent 的本质,对实际的多 Agent 系统设计有直接影响:

1. 不要把"子 Agent"设计成永久的层级关系

如果你的系统里有一个 Agent 永远只能被另一个 Agent 调用,永远不能独立运行,这往往是过度设计的信号。好的 Agent 应该是可以独立运行的,"主-子"关系是任务级别的协调,而非架构级别的约束。

2. 上下文隔离是选择子 Agent 的核心理由

当你考虑是否要用子 Agent 时,最重要的问题不是"这个任务需要多强的能力",而是"这个任务需要独立的上下文吗?"如果任务足够简单,一个 Tool 就够了;如果任务需要多步骤推理但上下文不需要隔离,在主 Agent 内处理就够了;只有当任务需要多步骤推理需要上下文隔离时,才需要子 Agent。

3. Skill 是上下文内的行为扩展,子 Agent 是上下文外的任务委托

这两种机制解决的是不同层面的问题。Skill 扩展的是当前 Agent 的行为能力,子 Agent 委托的是独立的任务执行。前者是"让我学会新技能",后者是"把这个任务交给专家去做"。

4. 协调者 Agent 应该专注调度

在多 Agent 团队中,协调者 Agent 应当专注于任务分解、进度追踪和质量把控,而不直接参与执行细节。

原因有二。第一,执行细节(代码 diff、编译错误、测试输出)会迅速填满上下文窗口,挤压协调者对全局目标和约束条件的掌控——就像一个项目经理如果整天埋头写代码,就会忘记关注项目风险和交付时间线。第二,子 Agent 从干净上下文开始工作,只接收最小化的任务描述,不会被协调者的历史对话和无关信息污染。

这是分治思想在 Agent 系统中的体现:调度层保持轻量,随时准备调整策略;执行层可以承接大量工具调用和错误重试。两层职责分离后,系统更容易复盘和调整。“协调者不写代码”可以是一种工作流策略,但不是所有任务的普遍规则;阶段高度耦合时,直接在主会话执行反而能减少信息转移。

委派子 Agent 时还有一个容易被忽略的杠杆:不是所有任务都需要用最强的模型。 一个"重命名变量"的任务和一个"重构认证模块"的任务,对模型能力的要求完全不同。协调者在委派时可以根据任务性质指定不同等级的模型——轻量快速模型处理简单操作,重量级推理模型处理架构级变更——在保证质量的同时显著降低运行成本。

总结

子 Agent 的本质是上下文隔离的专门化 Agent 实例,而非能力弱化的 Agent 或资源受限的进程。

几个关键结论:

  • 子 Agent 是完整的 Agent,可以拥有与主 Agent 相同甚至更强的能力
  • 上下文隔离是核心价值,不是能力限制
  • 递归派发是平台和版本特定能力,Claude Code 当前支持最大深度为 5 的嵌套 subagent
  • "子 Agent"是关系描述,不是能力描述——Prometheus、Oracle、Librarian 这样的 Agent 可以独立运行,也可以在特定任务中作为子 Agent 被协调
  • 主-子关系是动态的、任务级别的,不是静态的架构约束

会话切换、工作阶段和 Agent 委托是三种不同边界。《Agent 会话边界设计》进一步讨论它们怎样通过 checkpoint 与恢复测试组合。

参考资料