1. 前言

上一篇文章中,我们深入剖析了 Context Management 的设计——Agent 如何在有限的上下文窗口中管理记忆、压缩历史和治理信息。如果说 Agent Loop 是 Agent 的"心跳",Tool System 是 Agent 的"双手",Context Management 是 Agent 的"记忆系统",那么 SubAgent System(子Agent系统)就是 Agent 的"团队协作能力"——它决定了单个 Agent 能否将复杂任务拆解、委托给多个专职子 Agent 并行执行,再将结果汇合为一个整体产出。

这是 Agent 从"单兵作战"升级为"团队协作"的关键一跃。考虑一个真实的编程场景:用户说"帮我重构这个模块,把数据库层从 PostgreSQL 迁移到 MySQL,同时重写所有测试"。在传统单 Agent 模式下,主 Agent 需要先读 Schema、再改 ORM 代码、再迁移数据、再改写测试——每一步的结果都灌进同一个上下文窗口,很快上下文就会膨胀到填满。更糟的是,这些任务天然可并行(改 ORM 和写测试完全可以同时进行),但单 Agent 只能串行。

SubAgent System 解决了这个根本矛盾,在保持主会话可控的前提下,将独立子任务剥离到独立的执行上下文中,并行推进,结果按需回流。这个设计目标看似简单,但要在工程上做好,涉及一套完整的子系统设计:子 Agent 如何创建?父子之间共享什么、隔离什么?子 Agent 之间如何通信?结果如何汇合?worktree 隔离做到什么程度?

最近这一年来,SubAgent System 的研究已经从实验室走向了超大规模的生产实践。2026 年初,Anthropic 研究员 Nicholas Carlini 进行了一项轰动一时的实验1用 16 个并行 Claude Agent、近 2,000 个 session、两周时间,从零写出一个 10 万行的 C 编译器。 这个编译器能通过 GCC torture test suite 99% 的测试用例,能成功编译 Linux 6.9 内核、QEMU、FFmpeg、SQLite、Postgres 和 Redis。API 费用约 $20,000。有点小贵,但对比一个资深工程师团队两周的人力成本,已经进入了"经济上可行"的区间。与此同时,Anthropic 工程团队也公开了他们在构建**长运行 Agent(Long-running Agent)**时的系统性实践经验2,提出了一套让 Agent 跨越多个上下文窗口持续工作的 Harness 设计。

这些实践表明,SubAgent System 早已不是理论架构,而是正在被实际部署、能够产出工业级软件的真实工程系统。本文将从四个主流开源项目的源码分析入手,同时融入这些前沿实践的洞察,从工程角度总结 SubAgent System 的设计原则和关键权衡。

2. SubAgent System 的本质

2.1 从"函数调用"到"多Agent Runtime"

子 Agent 实现简单示例如下:

function spawn_subagent(task):
    child = new_agent(task, reduced_tools)
    result = child.run()
    return result

但真实场景需要回答的问题包括:

  • 子 Agent 是同步阻塞还是异步后台运行?
  • 父子 Agent 之间共享哪些上下文,隔离哪些状态?
  • 子 Agent 的错误、取消、超时如何传导回主 Agent?
  • 多个子 Agent 并行时,如何防止文件系统互相踩踏?
  • 子 Agent 能否递归创建孙 Agent?如果能,递归深度怎么控制?
  • 子 Agent 的结果是直接返回给用户,还是由主 Agent 二次整理后再呈现?
  • 子 Agent 的工具集如何裁剪?哪些能力不该下放?

这些问题促生了 SubAgent System 从单次函数调用,演进为一套边界清晰的多 Agent 运行时

2.2 SubAgent System 的通用抽象

无论具体实现如何差异,所有成熟的 SubAgent System 都共享同一套核心抽象:

flowchart TD
    A[父Agent判断任务可委托] --> B[Spawn: 创建子Agent运行时]
    B --> C[Delegate: 构造子Agent的prompt与toolset]
    C --> D[Execute: 子Agent独立运行Agent Loop]
    D --> E[Await: 等待子Agent完成或取消]
    E --> F[Fan-in: 结果回流与汇合]
    F --> G[主Agent消费结果并继续]

这套分层抽象让主 Agent 在保持对用户最终发言权的前提下,把可独立的子任务交给受控的、能力裁剪过的子 Agent 异步执行,结果通过内部协议回流。

其实这很像一个 Tech Lead 的工作方式:自己负责理解需求、设计方案、与客户(用户)沟通,但把具体模块的实现委托给不同工程师并行推进,最后自己把关、整合、向客户汇报。好的 SubAgent System 就是让 Agent 拥有这种"团队管理"能力。

这里有个关键点是,决定是否启动子 Agent 这一判断本身,不同的项目不约而同地采用了同一个策略:不靠硬编码调度规则,而是把判断权交给模型。 运行时只负责提供 spawn / Agent 这类 tool 的能力描述,模型在 tool-selection 阶段根据当前任务特征自行决定是否委托。任务的复杂度、并行机会、上下文污染风险,这些判断本身就依赖对任务语义的深层理解,硬编码的启发式规则远不如模型自己的判断准确,这需要时刻注意。

3. 主流项目的 SubAgent System 设计

3.1 Codex CLI3:共享控制面、隔离执行面

Codex CLI 的设计最接近"平台级多 Agent 运行时"。它的核心思想是:子 Agent 不是父 Agent 的一个并发函数,而是同一 session tree 中受控、可通信、可恢复的独立线程。

架构上分三层——控制面负责整棵 agent tree 的生命周期管理(spawn/resume/shutdown),注册层维护并发 slot 和嵌套深度配额,执行层创建独立线程。子 Agent 拿到的是全新的 Session 和 event queue,spawn 时从父 turn 派生配置、计算深度、注册 slot、启动后台 completion watcher 监听终态。

Codex 最突出的设计是 “共享控制面、隔离执行面”——认证、模型、技能、MCP 等基础设施共享以降低启动成本,但 Session、ContextManager、rollout 等执行状态严格隔离。Agent 间通信也设计得干净:V2 使用结构化消息直接投递为接收方的 prompt item,子 Agent 完成后父 Agent 在下个 turn 中自然消费。递归深度用 agent_max_depth 硬控制,默认值 1,只允许一级委托。

3.2 Claude Code4:双轨并存,统一内核

Claude Code 的 SubAgent System 是四个项目中最复杂的——它同时存在两套子 Agent 机制,但共用同一个 query() 执行引擎:

  1. Subagent:一次性委托 worker,复用主进程的 Agent Loop,通过 sidechain transcript 和 Task 实现可暂停、可恢复的生命周期。
  2. Teammate / Swarm Worker:持续存活的并行协作者,支持 in-process 和 pane/tmux 两种形态,通过 mailbox、task list、permission sync 实现 agent 间协作。

架构上分四层:Spawn/Routing 层决定走哪条路径(普通/fork/background/remote/teammate),Runtime 层为每个 agent 构建独立的 ToolUseContext,Task/Persistence 层管理 background task 和 resume 路径,Swarm Coordination 层提供 agent 间 IPC。

两个核心设计值得关注。一是上下文隔离采用 capability-based 模型——默认隔离几乎所有可变状态,只在显式打开 shareSetAppState 等少数 flag 时才共享,安全性比"全部共享再逐步限制"高得多。二是 Swarm mailbox 本质上是轻量 IPC 总线——不只传文本消息,还承载权限请求/响应、shutdown 协商、idle 通知等结构化协议消息,是四个项目中唯一把 agent 间通信当作"协议总线"设计的。

但也要指出,“两套系统并存"更像是需求不断叠加的结果而非一开始就规划好的。Subagent 和 Teammate 在 spawn 路径、通信协议、结果汇合上走不同的代码路径,增加了理解和维护成本。

3.3 pi5:进程级隔离,Extension 层实现

pi 的子 Agent 与其他项目有本质不同:它不是内核 built-in 能力,而是通过 extension 层以独立进程方式实现的 delegation。 父 Agent 调用 subagent tool → 发现 agent 配置 → spawn 新 pi 子进程 → 子进程按独立 prompt、toolset、模型运行 → 父进程消费 stdout JSON event stream → 收集结果回灌。

几个鲜明的设计决策:

进程级强隔离。 子进程 --no-session、独立 prompt、独立工具配置,天然不继承对话历史、session tree 和 compaction state。隔离最彻底,但 spawn 成本也最高。

父子协议是 JSON event stream。 没有自定义 socket 协议,直接复用 pi 的 stdout JSONL 流。父进程解析事件投影子 Agent 的内部状态,而非共享内存。

三种委派模式。 Single 单任务、Parallel 有界 fan-out(上限 8 任务,并发度 4,输出 50KB cap)、Chain 顺序 handoff({previous} 占位符替换上一步输出)。Chain 模式极简——协议只有 11 个字符的占位符,但 handoff 完全依赖 prompt discipline,脆弱性明显。

无自动 worktree 隔离。 只支持 cwd 注入,多个子 Agent 同目录并行写时可能冲突。这是 pi 最明显的能力缺口。

pi 的哲学是"把子 Agent 当作可流式观察的外部进程”,隔离性最强但启动成本最高,适合任务粒度较大的场景。

3.4 nanobot6:做减法的后台 Worker

nanobot 的设计是四个项目中最克制的。它只有一条路径:主 Agent 调 spawn → 登记后台协程 → 子 Agent 复用主执行内核但缩小 toolset + 缩短迭代上限 → 完成后通过 MessageBus 回流 system message → 主 AgentLoop 消费并二次改写后呈现用户。

三个"做减法"的决策:

子 Agent 绝对不对用户发言。 执行权下放,发言权保留在主 Agent。子 Agent 完成后只构造内部 system message 回流,由主 Agent 负责自然语言汇总。这从根本上杜绝了多 agent 输出顺序混乱和风格不统一的问题。

上下文采用"显式委托"而非"历史继承"。 子 Agent 的初始 prompt 极小——一段身份说明 + 一条 task 文本。主会话历史、channel metadata、长期记忆全部不继承。主 Agent 必须在 task 里把背景交代清楚——用"显式交代"换"上下文卫生"。

工具集激进裁剪。 只有基础读写和搜索能力,刻意排除 message(不发言)、spawn(不递归)、cron(不调度)、MCP tools(不继承外部工具)。子 Agent 被严格限定为"执行者",不是"第二个主 Agent"。

nanobot 的哲学是"用减法换可预测性"——它把容易失控的点全卡住了,但也因此不适合需要深层递归分解的复杂任务。

3.5 实践视角:Anthropic 的 Agent Teams 与长运行 Harness

Anthropic 工程团队在 2025-2026 年间公开的两项实践研究,则提供了从"效果"角度的验证。它们证明了一件事:SubAgent System 的工程质量,直接决定了 Agent 能否从"demo"升级为"工业级产品"。

3.5.1 C 编译器实验:16 个并行 Claude 的协作范式

2026 年 2 月,Anthropic 研究员 Nicholas Carlini 发表了"Building a C compiler with a team of parallel Claudes"1 一文,详细记录了他如何让 16 个 Claude Agent 并行协作,从零写出一个 10 万行的 Rust C 编译器。这项实验的核心工程设置如下:

并行协调机制。 实验面临的首要问题是如何让 16 个 Agent 同时工作而不互相踩踏。Carlini 的方案非常工程化:

  1. Docker 容器隔离:每个 Agent 运行在独立的 Docker 容器中,拥有自己的仓库克隆副本。这与 Claude Code 的 worktree 隔离思路一致,但粒度更粗——进程级 + 文件系统级隔离,16 个 Agent 完全互不干扰。
  2. 文件级任务锁:Agent 通过在共享 current_tasks/ 目录下写文本文件来声明自己正在处理哪个任务。如果两个 Agent 同时声明同一个任务,Git 的同步机制会迫使第二个 Agent 选择不同任务。这是一种极简但有效的分布式锁,只靠 Git就能实现。
  3. 自主合并冲突解决:Agent 完成一个任务后,从上游 pull、自己处理合并冲突、再 push。这意味着 Agent 不只是"写代码",还要完成完整的 Git 协作工作流。

专职 Agent 角色。 并行不只是"把任务切成 N 份同时跑"。Carlini 发现,为 Agent 赋予不同角色能显著提升整体产出质量:

  • Code Coalescer:专门寻找并合并重复代码,减少代码库的熵
  • Performance Optimizer:专门优化编译器速度和输出效率
  • Rust Critic:审查 Rust 代码质量,提出并执行结构优化
  • Documenter:持续维护 README 和进度追踪文档

这四种角色不是一开始就设计好的,而是在实验过程中根据实际需要逐步演化出来的。这与软件工程中"团队角色自然浮现"的模式高度一致——好的 SubAgent System 应该允许这种角色演化,而不是把 Agent 角色写死。

实验也暴露了一些关键的工程教训:

  • 模型不擅长追踪时间:Agent 可能在一个庞大的测试套件上无限运行。解决方案是为测试 harness 加 --fast 选项,让每个 Agent 只跑 1%-10% 的测试子集。
  • 上下文窗口污染:测试失败时,Agent 倾向于 dump 数千行无意义输出进上下文。解决方案是让测试失败时输出标准关键词(如 ERROR),便于 Agent 快速 grep 定位。
  • 大规模并行场景中的 Oracle 模式:当 Agent 在编译 Linux 内核时反复互相覆盖修复,Carlini 使用 GCC 作为"已知正确的编译器 Oracle"——Agent 用 GCC 编译部分内核,用自己的编译器编译另一部分,逐步缩小 bug 搜索范围。

测试 harness 的设计、输出格式、Oracle 的可用性,这些看似"外围"的基础设施,实际上决定了 Agent 协作的天花板。这个项目也有一个天然的优势,即存在所谓的编译器Oracle GCC,这不是每个项目都能有的。对于大部分创新项目来说,天然还是存在一些障碍的。

4. SubAgent System 的关键设计维度

4.1 Spawn / Delegate / Await 生命周期

项目Spawn 机制Delegate 内容Await 方式
Codex创建独立 CodexThread + Sessionchild config + 初始 user inputsubscribe_status() 等终态
ClauderunAgent() 或 fork agentprompt messages + ToolUseContext同步等待 / 异步 task notification
nanobotasyncio.create_task 后台协程最小 prompt(system + task)事件驱动回流,不阻塞主 Agent
pispawn 新 pi 子进程agent persona + Task 文本消费 JSON event stream,等进程 close

核心权衡在同步 vs 异步回流:同步简单直观但不适合长任务,异步灵活但需要 notification 机制和 resume 路径。

4.2 Context 共享与隔离

项目共享内容隔离内容隔离粒度
CodexAuth/Models/Skills/MCP ManagerSession, ContextManager, rollout_path线程级
Claude少数 capability flag(opt-in)readFileState, toolDecisions, UI callback 等字段级
nanobotworkspace 路径, provider 配置主会话历史, ContextBuilder 产物会话级
picwd, 环境变量, 文件系统对话历史, session tree, compaction state进程级

共识很明确:默认隔离,显式共享。 隔离粒度从会话级到进程级不等,越彻底越安全但启动成本越高。nanobot 和 pi 选择让子 Agent 初始上下文极小,把"共享历史"换成了"显式委托指令"。

4.3 工具集裁剪

项目裁剪机制排除的典型能力
CodexFeature flag + tool surface 动态决定按 flag 禁用(如 SpawnCsv/Collab)
Claudeagent definition + allowlist取决于 agent type
nanobot硬编码排除列表message, spawn, cron, MCP tools
pifrontmatter tools allowlist取决于 agent 配置

两条共识:子 Agent 不应直接对用户发言(发言权归主 Agent),递归 spawn 必须受控(深度限制或直接禁止)。

4.4 子 Agent 通信协议

项目通信协议协议载体子 Agent 间直连
CodexV2 结构化消息 / 兼容层 notification写入接收方 history不支持
ClaudeSendMessage / Swarm mailboxtask queue / file-based mailbox支持(teammate)
nanobotInboundMessage(system/subagent)半结构化文本回流主 loop不支持
piJSON event stream + {previous} 占位符stdout JSONL / task 文本替换不支持

分歧点:Codex 和 Claude 把 agent 间通信当作一等公民(结构化协议、消息队列、状态同步),nanobot 和 pi 则简化为"子→父回流,父决定下一步"。Claude 的 Swarm mailbox 是唯一把权限同步、shutdown 协商等也纳入同一总线的设计。

4.5 Worktree 隔离

项目自动 worktreecwd 级隔离清理机制
Codex无,靠外层策略支持无内置
Claudeisolation: "worktree" 显式创建支持自动回收无变更的 worktree
nanobot共享 workspace
pi支持 cwd 注入

Claude Code 是唯一内置自动 worktree 隔离的,任务结束无改动则自动回收。Docker 容器隔离是更"重"但更彻底的替代——隔离越彻底冲突越少,但结果合并成本越高。

4.6 结果汇合(Fan-in)

项目同步汇合异步汇合多任务汇合
Codextool_result 内联completion watcher → 结构化消息wait tool + CSV fanout
Claudetool_result 内联task_notification无内置 join barrier
nanobot无(全部异步)System message 回流主 loop逐条回流,per-session lock 串行
pitoolResult.content无异步模式parallel 文本拼接 + 50KB cap

两种哲学:函数返回值式(当场内联,简单但阻塞)vs 消息驱动回流式(不阻塞但需要 notification 调度)。pi 的 50KB cap 是唯一在模型可见层做截断的设计。

4.7 递归深度控制

项目是否支持递归控制机制默认行为
Codex支持agent_max_depth 硬限制depth=1(不允许孙 Agent)
Claude部分支持fork child 禁止,普通允许fork 路径禁递归
nanobot不支持不注册 spawn tool硬禁止
pi技术上可行无显式 depth 控制取决于 allowlist

Codex 的 agent_max_depth 最干净;Claude fork child 禁递归是因为共享了父级 prompt cache 前缀,递归会导致 cache key 混乱。

5. 设计共识

抛开实现差异,所有项目在以下原则上高度一致:

  1. 子 Agent 是受控执行单元,不是第二个主 Agent。 执行权可以下放,但发言权和最终决策权必须留在主 Agent。nanobot 最极端——子 Agent 连 message tool 都没有。

  2. 默认隔离,显式共享。 子 Agent 默认不继承对话历史、运行时状态和上下文产物。共享的能力通过显式配置开放,而非默认暴露。

  3. 工具集必须裁剪。 至少移除直接对用户发言的能力和不受控的递归 spawn。裁剪越激进越可预测,但能力范围也越窄。

  4. 委托判断权在模型,不在运行时调度器。 是否启动子 Agent、选哪个 agent、用什么模式——这些决策依赖语义理解,硬编码规则不如模型自主判断。

  5. 回流走统一协议,不另起通道。 结构化消息、system message、JSON event stream——形态各异,但都复用主 Agent 的现有消息处理管线。

  6. 递归深度必须有显式上限。 机制可以不同(agent_max_depth、fork gate、tool allowlist),但都不能放任无限嵌套。

  7. 文件系统隔离是并行写安全的前提。 从 worktree 到 Docker 容器,本质是在预防冲突和解决冲突的成本之间权衡。目前只有 Claude Code 做到了自动集成。

这些共识都在回答同一个问题:如何在不引入失控复杂度的前提下,让单个 Agent 获得任务分拆与并行执行的能力。

6. 总结

SubAgent System 是 Agent 从"单兵作战"升级为"团队协作"的关键一跃。从朴素的 spawn + run + return result 到成熟的多 Agent Runtime。SubAgent System 的演进体现了分布式系统设计的核心思想:通过清晰的边界定义、能力的显式裁剪、上下文的审慎隔离、结果的可靠汇合,把"并发委托"的复杂度控制在可理解和可测试的范围内。

SubAgent System 的设计工程原则是:子 Agent 是受控的执行单元,不是独立的人格——执行权可以下放,发言权和最终决策权必须留在主 Agent。隔离不是目的,可控才是目的——共享什么、隔离什么,每一处都应该有明确的理由。 多 Agent 系统从"能跑"到"可靠"的关键跨越,不在于更复杂的调度算法,而在于更扎实的工程基础设施。

下一篇,我们将深入探讨 Agent 的 权限与安全系统(Permission & Security) 设计,分析如何让 Agent 在拥有强大执行能力的同时,不变成安全隐患。

参考文献


  1. Nicholas Carlini, “Building a C compiler with a team of parallel Claudes,” Anthropic Engineering Blog, Feb 2026, https://www.anthropic.com/engineering/building-c-compiler ↩︎ ↩︎

  2. Anthropic, “Effective harnesses for long-running agents,” Engineering at Anthropic, Nov 2025, https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents ↩︎

  3. OpenAI, “Codex CLI,” https://github.com/openai/codex ↩︎

  4. Anthropic, “Claude Code,” https://code.claude.com/docs ↩︎

  5. pi, https://github.com/badlogic/pi-mono ↩︎

  6. nanobot, https://github.com/HKUDS/nanobot ↩︎