Claude Code 嵌套 sub-agent 实战:5 层套娃、token 怎么算、3 个翻车点
(updated )

Claude Code 嵌套 sub-agent 实战:5 层套娃、token 怎么算、3 个翻车点

2026 年大半年里,“sub-agent 不能再 spawn sub-agent”一直是 Claude Code 文档里的硬规则——专门为了防止无限递归留的栏杆。6 月 10 日 v2.1.172 上线,这条规则被一行 changelog 悄悄打破:sub-agent 可以嵌套了,最深 5 层。

这功能新到什么程度?官方的 sub-agent 参考页到现在还在说嵌套不可能。如果你已经熟悉单层委托,升级本身并不难——但 token 怎么算、配置面怎么写、哪些情况会翻车,跟你过去的习惯完全不是一套。这篇是你在第一次跑出后悔的嵌套链之前,应该先看一眼的指南。

嵌套 sub-agent 能做什么,不能做什么

不能
在 sub-agent 内部再 spawn sub-agent,最深 5 层跳过 toolsmodelmaxTurns 的配置——默认会从父级继承一切
给每层路由不同模型(opussonnethaiku在嵌套 sub-agent 之间共享上下文——每个都是独立的 200K 窗口
Agent(name1, name2) 限制 sub-agent 只能 spawn 指定的子 agent单独停掉父 agent 而不连带停掉它的所有后代
定义只在某个 sub-agent 生命期内运行的内联 mcpServershooks在嵌套 sub-agent 里用 EnterPlanModeAskUserQuestion(这些工具依赖主线程状态)
permissions.deny: ["Agent(name)"] 全局屏蔽特定 sub-agent指望官方 sub-agent 文档页——它还没更新到 2.1.172

30 秒心智模型:嵌套 sub-agent 是带 5 帧栈上限的递归,每一帧自己持有 system prompt 和模型。父级只读叶子的摘要。中间那些上下文都要花 token,跑完就没了。

决策框架:什么时候该嵌套(什么时候别嵌套)

适合嵌套的场景

  1. 任务是树而不是列表——比如顶层 reviewer 需要对同一个 diff 问三个专项 sub-reviewer(security、perf、style)同一个问题,每个专项还各自挂着不同的 MCP 服务或 skill。
  2. 任务本身就是递归形状——探索 monorepo 时每个 packages/* 目录都需要带着自己的约定做单独探索,叶子摘要逐层上卷。
  3. 第 1 层已经撑上下文了——单层 sub-agent 返回 30K token 的报告把主会话淹了,再往下推一层让每个叶子先压缩再上交,能缓过来。

不要嵌套的场景

  1. 任务是序列——五个有依赖关系的步骤应该塞进一个 sub-agent 配 maxTurns: 20,而不是拆成五次嵌套调用。每加一层都是一次不可逆的上下文切分和一次 system prompt 写入。
  2. 想要并行 worker 互相沟通——那是 agent teams 干的事,不是嵌套。嵌套 sub-agent 只能上下传,不能横向通信。
  3. 叶子就调一个工具——这时候你花一整个 sub-agent 的 system prompt 跑一个 Read 或 Grep,不如父 agent 自己调。

Stop rule

动手嵌套之前,先把你预期的叶子摘要写一张便签。如果 ~500 token 以下,或者父 agent 用两次 tool call 就能自己产出,别嵌套。嵌套划得来的前提是:叶子做了有意义的工作,返回有意义的压缩答案。

系统要求

要求验证命令
Claude Code v2.1.172 或更新claude --version
父 sub-agent 的 tools(白名单)里必须有 Agent 工具cat .claude/agents/<parent>.md | grep -i agent
Anthropic 官方 API 或 Anthropic 兼容网关(如 ofox.ai)echo $ANTHROPIC_BASE_URL
.claude/agents/~/.claude/agents/ 里至少有一个子 sub-agent 定义ls -1 .claude/agents/ ~/.claude/agents/ 2>/dev/null

如果你还在 2.1.171 或更老版本,跑 npm i -g @anthropic-ai/claude-code 升级。CLI 启动时会打印解析到的版本号;老版本对嵌套调用不会报错,会把内层的 Agent tool use 当成普通 Read 静默忽略。

实操:搭一条嵌套 sub-agent 链

下面的例子搭一条三层链:顶层 triage-lead 给新来的 bug 报告分类,委托给 repro-runner 确认能否复现,后者再委托给 log-summariser 把原始容器日志压成 200 行摘要。

Step 1:定义叶子节点

新建 .claude/agents/log-summariser.md

---
name: log-summariser
description: Reads raw container logs and returns a structured summary of errors, timing, and suspicious patterns.
tools: Read, Grep
model: haiku
maxTurns: 8
---

You are a log summariser. Given a path to a log file, return:
1. Top 5 distinct error signatures with frequency
2. Earliest and latest timestamps observed
3. Any panic, OOM, or segfault entries with line numbers
Return strictly Markdown — no preamble.

预期效果:通过 /agents 创建立刻生效;直接改盘上文件的话,下次启动会话才生效。

Step 2:定义中间层

新建 .claude/agents/repro-runner.md

---
name: repro-runner
description: Reproduces a bug from a description, captures logs, and returns whether the failure is deterministic.
tools: Agent(log-summariser), Read, Bash
model: sonnet
maxTurns: 12
---

You reproduce bugs. Run the failing command, capture logs to /tmp/repro.log,
then call the log-summariser sub-agent to compress the output before returning.
Report: deterministic? yes/no, plus the summary.

tools: Agent(log-summariser) 是新东西。2.1.172 之前,Agent(...) 写在 sub-agent 定义里完全无效。现在它是这个 sub-agent 被允许 spawn 的白名单。

Step 3:定义根节点

新建 .claude/agents/triage-lead.md

---
name: triage-lead
description: Triages incoming bug reports end-to-end — classification, reproduction, log review.
tools: Agent(repro-runner), Read, Grep, Bash
model: opus
maxTurns: 15
---

Classify the bug (P0/P1/P2), delegate reproduction to repro-runner, then
return a triage memo with severity, repro status, and the summarised logs.

链路至此:主会话 → triage-lead(Opus)→ repro-runner(Sonnet)→ log-summariser(Haiku)。三层。

Step 4:从主会话发起

> Use the triage-lead agent on the bug report at ./bugs/2026-06-11-checkout-500.md

Claude 会读 description 字段自动路由整条链。也可以显式强制委托:Use triage-lead。每一次交接都会在 /agents 视图里显示成一个独立面板,并标出嵌套深度。

Step 5:确认嵌套真的发生了

跑完之后看 /agents(Running 标签页),或者翻 transcript 找三个不同的 sub-agent 面板。如果只看到一个,说明父级把 Agent(...) 调用当成普通工具调用了——几乎一定是版本不对。重跑 claude --version 确认 2.1.172+。

/agents
> [Running]
>   triage-lead         opus       depth 1   ✓ completed
>     repro-runner      sonnet     depth 2   ✓ completed
>       log-summariser  haiku      depth 3   ✓ completed

深度 3 是”跑通了”的下限。5 层上限是栈限制不是目标——大多数有用的链活在 2-3 层。

嵌套常见报错(和修法)

现象大概率原因快速修法
sub-agent 的可用工具里没有 Agent2.1.172 之前的行为,或父 agent 的 tools 字段里漏写 Agent升级 Claude Code,然后在父 agent 的 tools 里加 Agent(child-name)
sub-agent spawn 子 agent,但子 agent 没有父 agent 的 MCP 服务MCP 服务不会跨嵌套继承——每个 sub-agent 都按自己 frontmatter 重新连接在子 agent 的 mcpServers 字段里加上对应服务名,或者上提到用户级 settings.json
升级之后 Agent(x) 还是被忽略限制写在 plugin 引用的 sub-agent 定义里(安全策略会从 plugin agent 里剥掉 permissionMode/hooks/mcpServers把 agent 文件复制到 .claude/agents/~/.claude/agents/,别留在 plugin 里
嵌套到第 6 层就停了,没有清晰错误5 层递归上限触顶;某些 transcript 里第 6 层调用是静默失败重构:要么扁平掉一层,要么拆成两次顶层调用
父 agent 报”completed”但子 agent 还卡在”active”2.1.172 修了最常见的那种;后台 sub-agent 还可能复现升级到 2.1.172+,或者从 /agents 的 Running 标签页杀掉子 agent 重跑
token 账单暴涨 7-12× 但行为看不出变化每加一层都要写一次 system prompt;默认模型继承主会话(很多人主会话是 Opus)CLAUDE_CODE_SUBAGENT_MODEL=haiku 强制让所有未显式 override 的 sub-agent 走 Haiku,然后逐 agent 提升

第三行那条特别坑团队。v2.1.172 changelog 里明确写了修了”嵌套子 agent 被停掉之后后台 sub-agent 卡在 active 状态”这个 bug——如果你在恢复一个老版本启动的会话,先重启一次清掉继承下来的状态。

token 怎么算:嵌套为什么每条分支 ~7×

这是决定这套技术能不能用的核心算账。单线程 Claude Code 会话跨 turn 复用同一份缓存的 system prompt。sub-agent 在自己的上下文窗口里跑自己的 system prompt(比主会话的小,但不免费)。嵌套一层,每层都要交一次这笔开销。

深度要写什么能复用什么单次调用约略开销
0(主)主 system prompt + tools + CLAUDE.md复用(跨 turn 命中缓存)基线
1(sub-agent)sub-agent system prompt + 工具列表 + 任务描述部分——工具列表在分支内缓存基线 +30-60%
2(嵌套)内层 sub-agent prompt + 工具列表 + 来自父级摘要的任务描述更低——每个子 agent 都重写前缀在第 1 层之上再 +30-60%
3-5(深嵌套)同样形状,累加几乎没有——每个叶子的前缀都短命累计 ~5-7× 单线程

官方成本管理文档里那句”~7× token 消耗”是 sub-agent 密集型流程的标准最坏情况。嵌套不会让这个数字无上限放大——叶子调用做的活少、用便宜模型——但只要树是宽的,你就会被推向这个数字。

两个杠杆能跟这套算账对冲:

  1. 按深度分配模型。叶子很少需要 Opus。一个典型 triage 链的配置:根 Opus、第 1 层 Sonnet、第 2 层起 Haiku。Opus 和 Haiku 的输入 token 单价大约相差一个数量级,叶子层省下的钱在每次嵌套调用上都会复利累积。
  2. 每层都设 maxTurns。不设的话,叶子可能”为了帮忙”churn 30+ turn。叶子盖 8 turn、中间层盖 12 turn;大部分时候你都碰不到上限,碰到了就是任务描述写错了的信号。

想深入看 Claude Code 会话经济学的成本模型,参考 Claude Code token 优化指南。里面的 cache_read_input_tokens 分析在每条 sub-agent 分支上都适用,不只针对主线程。

3 个翻车点

翻车点 1:通用递归导致套娃失控

最省事的写法是给每个 sub-agent 都写 tools: Agent(无限制白名单),让模型自己琢磨该 spawn 谁。几个小时内你就会看到这种 transcript:triage agent spawn 了一个”通用 researcher”,researcher 又 spawn 了”investigation specialist”,再 spawn 了”log reader”,再 spawn 了……又一个通用 researcher。每加一层都烧 token。5 层深度上限救得了你的无限循环,救不了你的账单。

修法:永远用显式白名单。tools: Agent(repro-runner, log-summariser) 是 sub-agent 和它的孩子之间的契约。如果模型用这些孩子完不成任务,那是任务描述写错了——去改任务描述,不要去扩白名单。

翻车点 2:Opus 铺满

默认让每个 sub-agent 都用主会话的模型——这是默认行为,也恰恰是多层树最不该做的事。根用 Opus 合理(你在做综合判断)。叶子读个日志文件数数错误频率也用 Opus?你在拿最高档的价格买 Haiku 一个零头就能干的活。

修法:在 shell 层面设 CLAUDE_CODE_SUBAGENT_MODEL=haiku,让所有不显式 override 的 sub-agent 都走 Haiku。然后只把真的需要更强模型的 agent 提级——一般也就根和第 1 层。具体怎么按任务选模型,Claude Code 混合路由模式 讲了思路。

翻车点 3:Agent 白名单不写参数就提交到仓库

项目 sub-agent 文件会进版本控制。tools: Agent 不带括号在开发期能跑,看起来很宽容——但下个月队友加了个 migration-runner sub-agent,现有 triage 链就会被悄悄授权能 spawn 它,因为白名单接受任何东西。

修法:在文件里显式锚定白名单:tools: Agent(repro-runner, log-summariser), Read, Grep, Bash。改这个列表当成 security review 来走,跟改 permissions.allow 一样严。Claude Code 安全指南 讲了更大的原则:每个跟权限相关的字段都是一道安全边界。

团队 / 多人开发的配置约定

跨多个仓库共享 Claude Code 设置的团队,下面三条约定能把嵌套 sub-agent 控在便宜、可预期、可 review 的范围内:

约定写在哪为什么重要
共享 shell rc 里设 CLAUDE_CODE_SUBAGENT_MODEL=haiku个人 dotfiles从默认就堵掉”Opus 铺满”的漏;需要 Sonnet/Opus 的团队按文件 override
所有共享 sub-agent 都 commit 到 .claude/agents/,并显式写 Agent(name1, name2) 白名单每个仓库code review 能看见嵌套变化;新加的 sub-agent 不会被自动授权
sub-agent 密集型项目里写 permissions.deny: ["Agent(general-purpose)"].claude/settings.json强制使用专项委托;堵掉递归翻车点

跨多个仓库标准化的组织,还可以考虑用 dotfiles 管 ~/.claude/agents/ 目录放跨项目的通用 agent(review、security、doc-summariser)。用户级定义只在项目级没重名时才胜出,所以惯例是”通用共享放用户域,仓库专用放项目域”。

进阶:通过 ofox 给不同层路由不同模型

CLAUDE_CODE_SUBAGENT_MODEL 环境变量对每个没设 model 的 sub-agent 都生效。指向 Anthropic 兼容网关时,一个变量就能把你整个叶子层从一个模型别名切到另一个,所有 sub-agent 文件都不用动。接入就是一个环境变量加一个模型别名:

export ANTHROPIC_BASE_URL=https://api.ofox.ai/anthropic
export ANTHROPIC_API_KEY=<your_ofox_key>
export CLAUDE_CODE_SUBAGENT_MODEL=haiku

claude

任何深度上不显式 override model 字段的 sub-agent 现在都经 ofox 走 Haiku。根 agent 和显式写了 model: opusmodel: sonnet 的 sub-agent 经 ofox 走对应档位——CLAUDE_CODE_SUBAGENT_MODEL 是默认,不是 override。Claude Code ofox 接入指南 讲了完整配置,包括 cache_control header 如何透传,让父级也吃到提示缓存的节省。

ofox 同时接受 Claude Code 的裸别名(opussonnethaiku)和带 provider 前缀的显式 ID(anthropic/claude-opus-4.8anthropic/claude-sonnet-4.6anthropic/claude-haiku-4.5),后者是直接走 Anthropic 时会用到的写法。别名能让 sub-agent frontmatter 在直连 Anthropic 和走网关之间无缝迁移;显式 ID 把你钉到具体版本。ofox.ai/models 模型广场里能看到当前 Claude 全线在架,按这个去估你的分层树实际账单。

跑非常长的嵌套时,5 分钟的默认提示缓存 TTL 会变成下一个约束。ENABLE_PROMPT_CACHING_1H=1 能把它延长到 1 小时,代价是缓存写入费 2×——单次 triage 链超过 15 分钟墙钟之后通常都值。

本文核对过的来源

  • Claude Code CHANGELOG v2.1.172(2026-06-11 核对):github.com/anthropics/claude-code/blob/main/CHANGELOG.md — 确认 “Sub-agents can now spawn their own sub-agents (up to 5 levels deep)” 和后台 sub-agent 卡 active 的 bug 修复
  • Claude Code sub-agent 参考页(2026-06-11 核对):code.claude.com/docs/en/sub-agents — 完整 frontmatter schema(toolsmodelmaxTurnsmcpServershookspermissionMode);注意该页仍然在说嵌套不可能,跟 2.1.172 的 changelog 矛盾
  • Claude Code 成本管理指南(2026-06-11 核对):code.claude.com/docs/en/costs — “sub-agent 密集型工作流 ~7× token” 这个数字的出处
  • Claude Code changelog 镜像(2026-06-11 核对):code.claude.com/docs/en/changelog — 2.1.172 条目的二次确认
  • ofox 模型广场快照(2026-06-11 核对):ofox.ai/models — 当前 anthropic/claude-opus-4.8anthropic/claude-sonnet-4.6anthropic/claude-haiku-4.5 在架

头条说”最深 5 层”,有用的数字是”深度 2”。多数嵌套链划得来的配置都是根 Opus、中间 Sonnet、叶子 Haiku——三层、三档模型、每次交接一个显式 Agent(name) 白名单。白名单或分层任一缺一,5 层上限就从第一道防线变成了钱包的最后一道防线。