Files
claude-code/docs/features/fork-subagent.md
claude-code-best c5edee431f docs: 文档检查/check 20260419 (#296)
* docs: 修复文档巡检发现的 4 处错误

- daemon.md: 反映实际实现状态(supervisor/worker 已实现而非 stub)
- bridge-mode.md: API 操作数量从 7 修正为 9
- web-search-tool.md: 文件路径从 src/tools/ 修正为 packages/builtin-tools/src/tools/
- remote-control-self-hosting.md: 补充缺失的 RCS_WS_IDLE_TIMEOUT 和 RCS_WS_KEEPALIVE_INTERVAL 配置项

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 Safety 和 Context 文档中的代码引用和类型错误

- permission-model: 修正规则来源从"五层"到八层,优先级顺序对齐代码
- permission-model: PermissionUpdate 类型改为实际的 addRules/replaceRules 等
- permission-model: 补充 acceptEdits 和 dontAsk 两种权限模式
- permission-model: DENIAL_LIMITS 字段名对齐实际代码
- plan-mode: 工具路径从 src/tools/ 改为 packages/builtin-tools/src/tools/
- compaction: 修正 COMPACTABLE_TOOLS 和 POST_COMPACT_* 的行号
- project-memory: 修正 ENTRYPOINT_NAME 常量的行号
- system-prompt: 修正 SystemPrompt 类型定义文件路径和多个行号引用

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修复 introduction 文档中的错误路径和行号引用

- why-this-whitepaper.mdx: BashTool 路径从 src/tools/ 修正为 packages/builtin-tools/src/tools/
- what-is-claude-code.mdx: 移除不存在的 Azure provider,改为实际的 7 种 provider
- architecture-overview.mdx: State 类型行号从 204 修正为 207

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修复 conversation/features 文档中的错误

- streaming.mdx: queryStreamRaw → queryModelWithStreaming 函数名修正
- streaming.mdx: Azure 提供商不存在,替换为实际 7 个提供商
- debug-mode.mdx: --inspect-wait 描述错误,实际使用 BUN_INSPECT 环境变量
- buddy.mdx: 补充缺失的 companionReact.ts、CompanionCard.tsx、index.ts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修复文档巡检中的源码引用错误

- feature-flags.mdx: 修正 feature() 兜底描述,实际从 bun:bundle 导入而非 cli.tsx:3 内联
- feature-flags.mdx: 修正工具 require 路径为 @claude-code-best/builtin-tools 包路径
- ant-only-world.mdx: 修正 tools.ts 中 require 路径为包路径
- ant-only-world.mdx: 修正 INTERNAL_ONLY_COMMANDS 行号 (267-295) 和数量 (24+)
- skills.mdx: 修正 COMMANDS memoize 行号 258 → 299
- mcp-protocol.mdx: 修正 fetchToolsForClient LRU 缓存上限 20 → 100
- streaming.mdx: 修正流式事件引用
- file-operations.mdx: 修正工具路径引用
- search-and-navigation.mdx: 修正搜索工具引用
- shell-execution.mdx: 修正 shell 工具引用
- buddy.mdx: 补充缺失的 frontmatter 字段
- debug-mode.mdx: 修正调试模式描述

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 tools/agent 文档中的文件路径和行号引用

- 修正 TodoWriteTool、AgentTool、ToolSearchTool 等工具路径
  src/tools/ → packages/builtin-tools/src/tools/
- 更新 Tool.ts、tools.ts、BashTool.tsx 中过时的行号引用
- 修正 WebSearchTool/WebFetchTool/EnterWorktreeTool/ExitWorktreeTool 路径
- 修正 AgentTool.tsx 中多行行号引用

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 feature 文档中的文件路径和行号引用

- ultraplan.md: 更新文件行数(525/349/127)
- fork-subagent.md: 路径迁移 src/tools/ → packages/builtin-tools/
- mcp-skills.md: 修正 getMcpSkillCommands 行号 547→604,client.ts 行号 117→129
- kairos.md: 修正 getBriefSection/getProactiveSection 行号
- proactive.md: 修正 getProactiveSection 行号 860→864

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正顶层文档中的路径迁移和行号引用

- auto-updater.md: config.ts 行号 1735→1737,标注未接入启动流程的函数
- external-dependencies.md: WebSearchTool/WebFetchTool 路径迁移到 builtin-tools 包,Vertex 行号修正
- lsp-integration.md: LSPTool 路径从 src/tools/ 迁移到 packages/builtin-tools/
- stub-recovery-design-1-4.md: 修正 Windows 绝对路径链接为标准代码引用

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 task 文档中的文件扩展名和路径引用

- task-004: AssistantSessionChooser.ts → .tsx, assistant.ts → .tsx
- task-003: cli.tsx 行号 249→272, markdownConfigLoader.ts 行号 29→35
- lan-pipes: SendMessageTool 路径迁移到 packages/builtin-tools/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 补充 computer-use-tools-reference 缺失的 Windows 工具

添加遗漏的 open_terminal 和 activate_window 两个 Windows 专属工具,
修正工具总数 37→39,Windows 工具数 10→12。

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 audit/bash-classifier/token-budget/tree-sitter 文档

- feature-flags-audit: ScheduleCronTool 路径迁移、DAEMON 状态更新为 COMPLETE、assistant 文件标记已补全、UDS 标记已实现
- bash-classifier: BashPermissionRequest 文件路径修正、withRetry 行号移除
- token-budget: attachments.ts 行号范围修正
- tree-sitter-bash: bashPermissions.ts 路径迁移到 packages/builtin-tools

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 langfuse-monitoring AgentTool 路径迁移

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 bridgeApi 行号和 Tool.ts 行号引用

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 Safety/Extensibility 文档中的工具路径迁移和行号引用

- sandbox.mdx: shouldUseSandbox.ts 和 bashPermissions.ts 路径迁移至 packages/builtin-tools
- why-safety-matters.mdx: bashPermissions.ts 路径迁移(3 处)
- plan-mode.mdx: EnterPlanModeTool/prompt.ts 路径迁移
- auto-mode.mdx: Auto mode 指令行号 3464→3481
- hooks.mdx: AgentTool/runAgent.ts 路径迁移
- skills.mdx: SkillTool.ts 路径迁移
- custom-agents.mdx: Agent built-in 目录和 exploreAgent.ts 路径迁移

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 internals 文档引用计数和路径

- ant-only-world: USER_TYPE 引用计数 465→410+,工具路径迁移到 builtin-tools
- growthbook-ab-testing: growthbook.ts 行数 1156→1258
- hidden-features: 语音模式状态更新(audio-napi 已恢复)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正工具文档中的行号引用

- sub-agents: AgentTool.call 入口行号 340→387
- shell-execution: ShellCommand onTimeout 行号 129→144

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 feature 文档中的状态、路径和计数

- all-features-guide: 修正 feature flag 启用范围(dev only vs dev+build)
- tier3-stubs: 大量状态修正(stub→已实现),缩减过时条目
- workflow-scripts: 路径迁移到 builtin-tools,状态更新
- web-browser-tool: 工具状态缺失→已实现,路径迁移
- context-collapse: CtxInspectTool 状态缺失→已实现
- computer-use: 行号引用更新,平台分发描述修正
- computer-use-tools-reference: 工具数 39→38
- voice-mode: voiceModeEnabled 行数 55→54

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 更新 the-loop 查询循环行号引用

query.ts 代码变更后终止原因行号整体偏移约 40 行

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 补充 feature-flags-audit 完整 build 默认 feature 列表

添加 ULTRATHINK/LODESTONE/ACP/DAEMON 等 19 个缺失的 build 默认 feature,
修正 dev-only 特征标注(UDS_INBOX/LAN_PIPES/BG_SESSIONS/TEMPLATES)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 feature-flags-audit ConfigTool 路径迁移

ConfigTool 路径从 src/tools/ 迁移到 packages/builtin-tools/src/tools/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 feature-flags-audit BashTool 路径迁移

BashTool 路径从 src/tools/ 迁移到 packages/builtin-tools/src/tools/

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 修正 feature-flags-audit SkillTool 路径迁移

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* docs: 更新 feature-flags-audit WorkflowTool 状态为已实现

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-19 09:30:00 +08:00

196 lines
7.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# FORK_SUBAGENT — 上下文继承子 Agent
> Feature Flag: `FEATURE_FORK_SUBAGENT=1`
> 实现状态:完整可用
> 引用数4
## 一、功能概述
FORK_SUBAGENT 让 AgentTool 生成"fork 子 agent",继承父级完整对话上下文。子 agent 看到父级的所有历史消息、工具集和系统提示,并且与父级共享 API 请求前缀以最大化 prompt cache 命中率。
### 核心优势
- **Prompt Cache 最大化**:多个并行 fork 共享相同的 API 请求前缀,只有最后的 directive 文本块不同
- **上下文完整性**:子 agent 继承父级的完整对话历史(包括 thinking config
- **权限冒泡**:子 agent 的权限提示上浮到父级终端显示
- **Worktree 隔离**:支持 git worktree 隔离,子 agent 在独立分支工作
## 二、用户交互
### 触发方式
`FORK_SUBAGENT` 启用时AgentTool 调用不指定 `subagent_type` 时自动走 fork 路径:
```
// Fork 路径(继承上下文)
Agent({ prompt: "修复这个 bug" }) // 无 subagent_type
// 普通 agent 路径(全新上下文)
Agent({ subagent_type: "general-purpose", prompt: "..." })
```
### /fork 命令
注册了 `/fork` 斜杠命令(当前为 stub。当 FORK_SUBAGENT 开启时,`/branch` 命令失去 `fork` 别名,避免冲突。
## 三、实现架构
### 3.1 门控与互斥
文件:`packages/builtin-tools/src/tools/AgentTool/forkSubagent.ts:32-39`
```ts
export function isForkSubagentEnabled(): boolean {
if (feature('FORK_SUBAGENT')) {
if (isCoordinatorMode()) return false // Coordinator 有自己的委派模型
if (getIsNonInteractiveSession()) return false // pipe/SDK 模式禁用
return true
}
return false
}
```
### 3.2 FORK_AGENT 定义
```ts
export const FORK_AGENT = {
agentType: 'fork',
tools: ['*'], // 通配符:使用父级完整工具集
maxTurns: 200,
model: 'inherit', // 继承父级模型
permissionMode: 'bubble', // 权限冒泡到父级终端
getSystemPrompt: () => '', // 不使用:直接传递父级已渲染 prompt
}
```
### 3.3 核心调用流程
```
AgentTool.call({ prompt, name })
isForkSubagentEnabled() && !subagent_type?
├── No → 普通 agent 路径
└── Yes → Fork 路径
递归防护检查
├── querySource === 'agent:builtin:fork' → 拒绝
└── isInForkChild(messages) → 拒绝
获取父级 system prompt
├── toolUseContext.renderedSystemPrompt首选
└── buildEffectiveSystemPrompt回退
buildForkedMessages(prompt, assistantMessage)
├── 克隆父级 assistant 消息
├── 生成占位符 tool_result
└── 附加 directive 文本块
[可选] buildWorktreeNotice()
runAgent({
useExactTools: true,
override.systemPrompt: 父级,
forkContextMessages: 父级消息,
availableTools: 父级工具,
})
```
### 3.4 消息构建buildForkedMessages
文件:`packages/builtin-tools/src/tools/AgentTool/forkSubagent.ts:107-169`
构建的消息结构:
```
[
...history (filterIncompleteToolCalls), // 父级完整历史
assistant(所有 tool_use 块), // 父级当前 turn 的 assistant 消息
user(
占位符 tool_result × N + // 相同占位符文本
<fork-boilerplate> directive // 每个 fork 不同
)
]
```
**所有 fork 使用相同的占位符文本**`"Fork started — processing in background"`。这确保多个并行 fork 的 API 请求前缀完全一致,最大化 prompt cache 命中。
### 3.5 递归防护
两层检查防止 fork 嵌套:
1. **querySource 检查**`toolUseContext.options.querySource === 'agent:builtin:fork'`。在 `context.options` 上设置抗自动压缩autocompact 只重写消息不改 options
2. **消息扫描**`isInForkChild()` 扫描消息历史中的 `<fork-boilerplate>` 标签
### 3.6 Worktree 隔离通知
当 fork + worktree 组合时,追加通知告知子 agent
> "你继承了父 agent 在 `{parentCwd}` 的对话上下文,但你在独立的 git worktree `{worktreeCwd}` 中操作。路径需要转换,编辑前重新读取。"
### 3.7 强制异步
`isForkSubagentEnabled()` 为 true 时,所有 agent 启动都强制异步。`run_in_background` 参数从 schema 中移除。统一通过 `<task-notification>` XML 消息交互。
## 四、Prompt Cache 优化
这是整个 fork 设计的核心优化目标:
| 优化点 | 实现 |
|--------|------|
| **相同 system prompt** | 直传 `renderedSystemPrompt`避免重新渲染GrowthBook 状态可能不一致) |
| **相同工具集** | `useExactTools: true` 直接使用父级工具,不经过 `resolveAgentTools` 过滤 |
| **相同 thinking config** | 继承父级 thinking 配置(非 fork agent 默认禁用 thinking |
| **相同占位符结果** | 所有 fork 使用 `FORK_PLACEHOLDER_RESULT` 相同文本 |
| **ContentReplacementState 克隆** | 默认克隆父级替换状态,保持 wire prefix 一致 |
## 五、子 Agent 指令
`buildChildMessage()` 生成 `<fork-boilerplate>` 包裹的指令:
- 你是 fork worker不是主 agent
- 禁止再次 spawn sub-agent直接执行
- 不要闲聊、不要元评论
- 直接使用工具
- 修改文件后要 commit报告 commit hash
- 报告格式:`Scope:` / `Result:` / `Key files:` / `Files changed:` / `Issues:`
## 六、关键设计决策
1. **Fork ≠ 普通 agent**fork 继承完整上下文,普通 agent 从零开始。选择依据是 `subagent_type` 是否存在
2. **renderedSystemPrompt 直传**:避免 fork 时重新调用 `getSystemPrompt()`。父级在 turn 开始时冻结 prompt 字节
3. **占位符结果共享**:多个并行 fork 使用完全相同的占位符,只有 directive 不同
4. **Coordinator 互斥**Coordinator 模式下禁用 fork两者有不兼容的委派模型
5. **非交互式禁用**pipe 模式和 SDK 模式下禁用,避免不可见的 fork 嵌套
## 七、使用方式
```bash
# 启用 feature
FEATURE_FORK_SUBAGENT=1 bun run dev
# 在 REPL 中使用(不指定 subagent_type 即走 fork
# Agent({ prompt: "研究这个模块的结构" })
# Agent({ prompt: "实现这个功能" })
```
## 八、文件索引
| 文件 | 行数 | 职责 |
|------|------|------|
| `packages/builtin-tools/src/tools/AgentTool/forkSubagent.ts` | ~210 | 核心定义 + 消息构建 + 递归防护 |
| `packages/builtin-tools/src/tools/AgentTool/AgentTool.tsx` | — | Fork 路由 + 强制异步 |
| `packages/builtin-tools/src/tools/AgentTool/prompt.ts` | — | "When to Fork" 提示词段落 |
| `packages/builtin-tools/src/tools/AgentTool/runAgent.ts` | — | useExactTools 路径 |
| `packages/builtin-tools/src/tools/AgentTool/resumeAgent.ts` | — | Fork agent 恢复 |
| `src/constants/xml.ts` | — | XML 标签常量 |
| `src/utils/forkedAgent.ts` | — | CacheSafeParams + ContentReplacementState 克隆 |
| `src/commands/fork/index.ts` | — | /fork 命令stub |