AgentTool:子 Agent 生成与递归防护,一次讲透
你有没有想过当你在 Claude Code 里输入一句「帮我并行搜索三个模块的 bug」背后发生了什么很多工程师第一反应是Claude 肯定是自己分三次搜索的。错了。它其实悄悄派出了三个「克隆人」让它们并行干活然后把结果汇总给你。而这一切只需要调用一个叫AgentTool的工具。更骚的是这个工具还得防止这些克隆人不停地再克隆新克隆人搞出无限递归——Claude Code 用两道防线解决了这个问题代码加起来不超过 10 行。今天我们就把这个机制彻底讲透。01 AgentTool 是什么一个工具三条路AgentTool的入口在src/tools/AgentTool/AgentTool.tsx第 387 行附近。它的核心 schema 很简单接收prompt任务描述、可选的subagent_type指定 Agent 类型、name昵称和run_in_background是否异步。一旦 Claude 调用了Agent(prompt修复 bug)就会触发完整的执行链路AI 生成 tool_use: { prompt: 修复 bug, subagent_type: Explore } ↓ AgentTool.call() ← 入口AgentTool.tsx:387 ├── 解析 effectiveTypefork vs 命名 agent vs GP 回退 ├── filterDeniedAgents() ← 权限过滤 ├── assembleToolPool(workerPermissionContext) ← 独立组装工具池 ├── createAgentWorktree() ← 可选 worktree 隔离 ↓ runAgent() ← 核心执行runAgent.ts ├── getAgentSystemPrompt() ← 构建 agent 专属 system prompt ├── executeSubagentStartHooks() ← Hook 注入 └── query() ← 进入标准 agentic loop设计点子 Agent 走的是完整的query()主循环和主 Agent 用的是同一套引擎。它不是某种简化版的「副本」而是一个拥有独立工具池、独立权限上下文的完整 Agent 实例。根据subagent_type参数和 Fork 实验开关执行走三条不同路径维度命名 Agentsubagent_type有值Fork 子进程Fork 开启且未指定类型General-purpose 回退触发条件subagent_type有值Fork 开启 未指定类型Fork 关闭 未指定类型System PromptAgent 自身的getSystemPrompt()继承父 Agent 完整 System PromptGP Agent 的getSystemPrompt()工具池独立组装父 Agent 原始工具池cache 对齐独立组装上下文仅任务描述父 Agent 完整对话历史仅任务描述权限模式Agent 定义的permissionModebubble上浮到父终端Agent 定义的permissionMode02 Fork 路径Prompt Cache 共享的工程学Fork 是 Claude Code 里最有意思的设计之一解决的核心问题如何让并行子 Agent 共享昂贵的 Prompt CacheAnthropic 的 Prompt Cache 按请求前缀命中只要请求头部字节完全一致就能复用缓存。问题来了如果每个子 Agent 都带着不同的任务描述前缀就不同缓存命中率就崩了。Fork 的解法非常精巧——把所有 fork 子进程的请求构造成「前 N-1 块完全相同只有最后一块不同」// forkSubagent.ts:93 — 所有 fork 子进程共享相同的占位结果constFORK_PLACEHOLDER_RESULTFork started — processing in background// buildForkedMessages() 构建两条消息// [// assistant(父的全量 tool_use 块), ← 完全一致cache 100% 命中// user([// placeholder_results..., ← 相同占位符cache 继续命中// { type: text, text: 子进程指令 } ← 只有最后这一块不同// ])// ]这样 Anthropic API 能最大化缓存利用率。Fork 的启用条件很严格必须同时满足三个前提feature flagFORK_SUBAGENT已启用、当前不在 Coordinator 模式中、且不是非交互式会话。任一条件不满足省略subagent_type会静默降级为 General-purpose Agent。03 递归防护两道防线一个都不能少最有趣的工程问题来了如果 Fork 子进程也能调用AgentTool会不会无限递归理论上会所以有两道防线。防线一querySource 检查压缩安全子进程启动时querySource被标记为agent:builtin:fork。主循环在每次决定是否允许 Fork 时会先检查这个字段——发现自己已经是 fork 了就不再生成新的 fork。为什么叫「压缩安全」因为 Compaction上下文压缩会重建 messages如果只靠消息里的标记来判断压缩后标记会消失。querySource 存在运行时 context 里不受压缩影响。防线二消息扫描降级兜底Fork 子进程启动时系统会在消息里注入一个fork-boilerplate标签。主循环在启动前扫描消息历史发现这个标签就认为「我已经在 fork 里了」拒绝再次 fork。为什么要两道防线querySource是内存状态理论上可能在某些边缘场景如进程恢复、序列化/反序列化丢失。消息里的标签是持久化的作为最后一道保险。这个「双保险」模式是一个普适的工程哲学对于不可逆的灾难性操作运行时检查 持久化标记双保险比任何单一防线都可靠。04 命名 Agent 的工具池独立组装命名 Agent指定了subagent_type最关键的特性工具池完全独立于父 Agent 重新组装。// AgentTool.tsx 中的工具池组装consttoolPermissionContextmodepermissionModeacceptEdits// 独立权限模式// 独立调用 assembleToolPool不继承父 Agent 的工具限制constassembleToolPoolmcptools// MCP 工具从全局状态继承// runAgent.ts:508 — 工具进一步过滤const// Fork: 直接用父工具保证 cache 一致resolveAgentToolsresolvedToolsClaude Code 内置了几个核心 Agent各有明确的职责边界Agent模型权限工具集用途ExploreHaiku轻量只读Read/Grep/Glob代码库搜索探索Plan继承父模型只读受限Plan Mode 研究信息收集General-purpose继承父模型全量工具全部复杂通用任务statusline-setup继承父模型受限受限状态栏配置关键设计决策权限模式独立子 Agent 不受父 Agent 当前模式限制、MCP 工具全局继承子 Agent 自动获得所有已连接的 MCP 工具、Fork 工具完全继承useExactTools: true保证 cache 命中。05 模型解析与 Worktree 隔离模型解析优先级链src/utils/model/agent.ts1. CLAUDE_CODE_SUBAGENT_MODEL 环境变量 ← 全局覆盖 ↓未设置时 2. 每次调用的 model 参数 ← AgentTool 入参 ↓未指定时 3. Agent 定义的 model frontmatter ← 如 sonnet, haiku, inherit ↓未定义时 4. 继承父对话模型conversation model ← getDefaultSubagentModel() 返回 inheritinherit不是简单地传递父模型 ID——它经过getRuntimeMainLoopModel()解析确保 plan mode 下的opusplan→Opus等运行时映射正确生效。Worktree 隔离当 Agent 定义设置了isolation: worktree时子 Agent 在独立的 git worktree 中工作constagent-${earlyAgentId.slice(0, 8)}awaitcreateAgentWorktree// 生命周期: 创建 worktree → CWD 覆盖 → 子 Agent 操作 → 任务完成后清理这解决了经典问题主 Agent 正在重构模块 A同时派出子 Agent 重构模块 B两个 Agent 可能同时修改共享文件如index.ts的导出。有了 worktree每个子 Agent 在自己的 git 工作副本里操作互不干扰。06 设计洞察五条可迁移的工程经验① 子 Agent 走完整 query() 循环不是精简版这意味着子 Agent 享有和主 Agent 完全相同的工具执行、错误恢复、token 预算控制能力。工程上的权衡是更高的内存和 CPU 开销换来更强的一致性保证。② 工具池隔离是权限最小化的实践Explore Agent 只有三个工具不是因为懒是因为搜索任务根本不需要写权限。给子 Agent 最小工具集是防止「聪明的 Claude 想出奇怪方法绕过限制」的工程护栏。③ Fork 的 cache 共享是真实的工程收益实测数据来自 Anthropic 内部同一个任务用 Fork 并行比串行执行cache 命中率提升 40%-60%API 成本显著降低。这不是理论上的优化是有实际 ROI 的工程决策。④ 双保险防护优于单一防线querySource内存fork-boilerplate持久化的组合覆盖了两类故障模式正常运行时的递归和状态丢失后的意外恢复。这个模式在分布式系统里叫「幂等 外部标记」Claude Code 把它用在了递归防护上。⑤ 命名 Agent 是「角色化 AI」的雏形Explore、Plan、General-purpose每个 Agent 都有自己的系统提示、工具集和权限模式。这是一种「角色化」的 AI 设计范式——通过约束工具集和权限而不是只靠 prompt来确保 Agent 行为的可预测性。总结AgentTool 是 Claude Code 最复杂的单一工具但设计非常克制。三条路径各有所长命名 Agent 换取专业化Fork 换取 cache 效率GP 作为通用兜底递归防护要双保险runtime contextquerySource 持久化标签fork-boilerplate两道防线缺一不可工具池独立组装是权限最小化防止子 Agent 越权是真实的安全机制而非过度设计Fork 的 Prompt Cache 共享是真正的工程亮点用占位符 tool_result 对齐请求前缀把并行代价降到最低worktree 隔离是多 Agent 协作的基础设施没有它并行写文件就是一场灾难inherit 不等于简单继承模型解析有四层优先级链跨 provider 降级是真实的踩坑风险学AI大模型的正确顺序千万不要搞错了2026年AI风口已来各行各业的AI渗透肉眼可见超多公司要么转型做AI相关产品要么高薪挖AI技术人才机遇直接摆在眼前有往AI方向发展或者本身有后端编程基础的朋友直接冲AI大模型应用开发转岗超合适就算暂时不打算转岗了解大模型、RAG、Prompt、Agent这些热门概念能上手做简单项目也绝对是求职加分王给大家整理了超全最新的AI大模型应用开发学习清单和资料手把手帮你快速入门学习路线:✅大模型基础认知—大模型核心原理、发展历程、主流模型GPT、文心一言等特点解析✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑✅开发基础能力—Python进阶、API接口调用、大模型开发框架LangChain等实操✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经以上6大模块看似清晰好上手实则每个部分都有扎实的核心内容需要吃透我把大模型的学习全流程已经整理好了抓住AI时代风口轻松解锁职业新可能希望大家都能把握机遇实现薪资/职业跃迁这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】