执行链路总览
一条Agent(prompt="修复 bug") 调用的完整路径:
两种子 Agent 路径:命名 Agent vs Fork
AgentTool.call() 根据是否提供 subagent_type 走两条完全不同的路径(AgentTool.tsx:322-356):
| 维度 | 命名 Agent(subagent_type 指定) | Fork 子进程(subagent_type 省略) |
|---|---|---|
| 触发条件 | subagent_type 有值 | isForkSubagentEnabled() && 未指定类型 |
| System Prompt | Agent 自身的 getSystemPrompt() | 继承父 Agent 的完整 System Prompt |
| 工具池 | assembleToolPool() 独立组装 | 父 Agent 的原始工具池(useExactTools: true) |
| 上下文 | 仅任务描述 | 父 Agent 的完整对话历史(forkContextMessages) |
| 模型 | 可独立指定 | 继承父模型(model: 'inherit') |
| 权限模式 | Agent 定义的 permissionMode | 'bubble'(上浮到父终端) |
| 目的 | 专业任务委派 | Prompt Cache 命中率优化 |
assistant 消息(所有 tool_use 块),用相同的占位符 tool_result 填充,只有最后一个 text 块包含各自的指令。这使得 API 请求前缀字节完全一致,最大化缓存命中。
Fork 递归防护
Fork 子进程保留 Agent 工具(为了 cache-identical tool defs),但通过两道防线防止递归 fork(AgentTool.tsx:332):
querySource检查(压缩安全):context.options.querySource === 'agent:builtin:fork'- 消息扫描(降级兜底):检测
<fork-boilerplate>标签
工具池的独立组装
子 Agent 不继承父 Agent 的工具限制——它的工具池完全独立组装(AgentTool.tsx:573-577):
- 权限模式独立:子 Agent 使用
selectedAgent.permissionMode(默认acceptEdits),不受父 Agent 当前模式的限制 - MCP 工具继承:
appState.mcp.tools包含所有已连接的 MCP 工具,子 Agent 自动获得 - Agent 级 MCP 服务器:
runAgent()中的initializeAgentMcpServers()可以为特定 Agent 额外连接专属 MCP 服务器
工具过滤的 resolveAgentTools
runAgent.ts:500-502 在工具组装后进一步过滤:
resolveAgentTools() 会根据 Agent 定义中的 tools 字段过滤可用工具,将 ['*'] 映射为全量工具。
Worktree 隔离机制
isolation: "worktree" 参数让子 Agent 在独立的 git worktree 中工作(AgentTool.tsx:590-593):
- 创建:在
.git/worktrees/下创建独立工作副本 - CWD 覆盖:
runWithCwdOverride(worktreePath, fn)让所有文件操作在 worktree 中执行 - 路径翻译:Fork + worktree 时注入路径翻译通知(
buildWorktreeNotice) - 清理(
cleanupWorktreeIfNeeded):- Hook-based worktree → 始终保留
- 有变更 → 保留,返回
worktreePath - 无变更 → 自动删除
生命周期管理:同步 vs 异步
异步 Agent(后台运行)
当run_in_background=true 或 selectedAgent.background=true 时,Agent 立即返回 async_launched 状态(AgentTool.tsx:686-764):
AbortController,不与父 Agent 共享——用户按 ESC 取消主线程不会杀掉后台 Agent。
同步 Agent(前台运行)
同步 Agent 的关键特性是 可后台化(AgentTool.tsx:818-833):
Promise.race 竞争下一条消息和后台化信号:
agentIterator.return()),新的 runAgent() 以 isAsync: true 重新启动,当前台的输出文件继续写入。
结果回传格式
mapToolResultToToolResultBlockParam() 根据状态返回不同格式(AgentTool.tsx:1298-1375):
| 状态 | 返回内容 |
|---|---|
completed | 内容 + <usage> 块(token/tool_calls/duration) |
async_launched | agentId + outputFile 路径 + 操作指引 |
teammate_spawned | agent_id + name + team_name |
remote_launched | taskId + sessionUrl + outputFile |
<usage> 块被省略——每周节省约 1-2 Gtok 的上下文窗口。
MCP 依赖的等待机制
如果 Agent 声明了requiredMcpServers,call() 会等待这些服务器连接完成(AgentTool.tsx:371-410):
failed 状态时立即停止等待。工具可用性通过 mcp__ 前缀工具名解析(mcp__serverName__toolName)判断。
适用场景
并行研究
多个 fork 子进程并行搜索不同方向,共享 Prompt Cache 前缀,只有指令不同
专业委派
使用命名 Agent(Explore/Plan/verification)执行专业任务,受限工具集 + 独立权限
隔离实验
isolation: "worktree" 在独立工作副本中尝试方案,不影响主分支后台构建
run_in_background: true 启动长时间构建/测试任务,主 Agent 继续工作