Appearance
06 — Tool 系统
概述
Tool 是 Claude Code 的核心执行单元——模型的所有能力都通过 Tool 来体现。当模型需要读文件、执行命令、搜索代码,它返回一个 tool_use JSON 块,Claude Code 解析后调用对应的 Tool 实现,再将结果作为 tool_result 返回给模型。
理解 Tool 系统需要理解三层架构:
- Tool 定义层 — 每个工具是什么、接受什么参数、返回什么结果
- Tool 执行层 — 工具如何被调度、权限如何检查、并发如何管理
- Tool 注册层 — 工具如何被发现和组装到模型可用的工具列表中
Tool 接口 (Tool.ts)
每个 Tool 实现核心需要提供:
typescript
interface Tool {
name: string // 工具名称 (模型看到的名字)
description: string // 描述 (模型用来判断何时使用)
inputSchema: ToolInputJSONSchema // 参数 JSON Schema
isReadOnly(): boolean // 是否只读 (影响权限默认行为)
needsPermissions(input): boolean // 该次调用是否需要权限确认
call(input, context: ToolUseContext): Promise<ToolResult> // 执行
renderToolUse?(input): ReactNode // 可选:自定义调用 UI
renderToolResult?(result): ReactNode // 可选:自定义结果 UI
}Tool 的 call() 方法接收两个参数:
input— 模型提供的参数(已通过 JSON Schema 校验)context—ToolUseContext(见 03-State),通过它访问 AppState、发送通知、检查中断等
Tool 执行层
StreamingToolExecutor — 并发调度器
这是 Tool 执行的核心调度器。它的关键创新是:在 API 还在 streaming 时就开始执行只读工具。
并发安全性判断
每个 Tool 实现 isConcurrencySafe(input) 方法:
- 并发安全 (可并行):
FileReadTool,GlobTool,GrepTool,WebFetchTool,WebSearchTool,LSPTool等只读工具 - 不并发安全 (须串行):
BashTool,FileEditTool,FileWriteTool,AgentTool等可能修改状态的工具
StreamingToolExecutor 将连续的并发安全工具分批并行执行,遇到不安全工具则等待前面所有工具完成后串行执行。
错误级联
关键设计:如果 Bash 工具出错,会通过 siblingAbortController.abort('sibling_error') 取消所有同批次的兄弟工具。这是因为 Bash 错误往往意味着环境状态异常(如依赖安装失败),继续执行其他工具没有意义。
完整执行流水线
执行服务文件
| 文件 | 说明 |
|---|---|
services/tools/StreamingToolExecutor.ts | 并发调度器 (~520 行) |
services/tools/toolOrchestration.ts | 旧版顺序执行路径 (fallback) |
services/tools/toolExecution.ts | 实际执行逻辑 (runToolUse()) |
services/tools/toolHooks.ts | Pre/Post 工具钩子执行 |
工具分类详表
📁 文件系统工具
| 工具 | 目录 | 只读? | 说明 |
|---|---|---|---|
| FileReadTool | tools/FileReadTool/ | ✅ | 读取文件(支持图片→base64、PDF 解析、Jupyter Notebook) |
| FileWriteTool | tools/FileWriteTool/ | ❌ | 创建/覆盖文件 |
| FileEditTool | tools/FileEditTool/ | ❌ | 精确字符串替换编辑(模型提供 old_string → new_string) |
| GlobTool | tools/GlobTool/ | ✅ | 文件名模式搜索 (**/*.ts) |
| GrepTool | tools/GrepTool/ | ✅ | 文件内容搜索(基于 ripgrep) |
| NotebookEditTool | tools/NotebookEditTool/ | ❌ | Jupyter Notebook 编辑 |
🖥️ 执行工具
| 工具 | 目录 | 说明 |
|---|---|---|
| BashTool | tools/BashTool/ | Bash 命令执行 — 最复杂的工具,有多层安全机制 |
| PowerShellTool | tools/PowerShellTool/ | Windows PowerShell 执行 |
🤖 Agent / Task 工具
| 工具 | 目录 | 说明 |
|---|---|---|
| AgentTool | tools/AgentTool/ | 启动子代理(独立对话循环) |
| SendMessageTool | tools/SendMessageTool/ | 向已有子代理发送消息 |
| TaskCreateTool | tools/TaskCreateTool/ | 创建后台任务 |
| TaskGetTool | tools/TaskGetTool/ | 查询任务状态 |
| TaskUpdateTool | tools/TaskUpdateTool/ | 更新任务进度 |
| TaskListTool | tools/TaskListTool/ | 列出所有任务 |
| TaskStopTool | tools/TaskStopTool/ | 停止任务 |
| TaskOutputTool | tools/TaskOutputTool/ | 获取任务输出 |
| TeamCreateTool | tools/TeamCreateTool/ | 创建 Teammate (Swarm) |
| TeamDeleteTool | tools/TeamDeleteTool/ | 删除 Teammate |
🌐 外部集成工具
| 工具 | 目录 | 说明 |
|---|---|---|
| MCPTool | tools/MCPTool/ | 代理调用 MCP 服务器上的工具 |
| ReadMcpResourceTool | tools/ReadMcpResourceTool/ | 读取 MCP 资源 |
| ListMcpResourcesTool | tools/ListMcpResourcesTool/ | 列出 MCP 资源 |
| McpAuthTool | tools/McpAuthTool/ | MCP OAuth 认证 |
| LSPTool | tools/LSPTool/ | LSP 操作(定义跳转、引用查找等) |
| WebFetchTool | tools/WebFetchTool/ | 网页抓取 |
| WebSearchTool | tools/WebSearchTool/ | 网页搜索 |
🧭 模式控制工具
| 工具 | 目录 | 说明 |
|---|---|---|
| EnterPlanModeTool | tools/EnterPlanModeTool/ | 进入规划模式(限制写操作) |
| ExitPlanModeTool | tools/ExitPlanModeTool/ | 退出规划模式 |
| EnterWorktreeTool | tools/EnterWorktreeTool/ | 进入 Git Worktree |
| ExitWorktreeTool | tools/ExitWorktreeTool/ | 退出 Git Worktree |
🔧 其他工具
| 工具 | 目录 | 说明 |
|---|---|---|
| AskUserQuestionTool | tools/AskUserQuestionTool/ | 向用户提问(模型主动发问) |
| ConfigTool | tools/ConfigTool/ | 修改运行时配置 |
| SkillTool | tools/SkillTool/ | 执行 Skill(可复用 prompt) |
| ToolSearchTool | tools/ToolSearchTool/ | 搜索延迟加载的工具定义 |
| TodoWriteTool | tools/TodoWriteTool/ | 更新 Todo 列表 |
| BriefTool | tools/BriefTool/ | Brief 上传 |
| RemoteTriggerTool | tools/RemoteTriggerTool/ | 远程触发器 |
| ScheduleCronTool | tools/ScheduleCronTool/ | Cron 任务调度 |
| SleepTool | tools/SleepTool/ | 等待/睡眠 |
| SyntheticOutputTool | tools/SyntheticOutputTool/ | 合成输出(内部使用) |
BashTool 深度剖析
BashTool 是最复杂的工具,有 多层安全检查 确保模型不会执行危险操作:
BashTool 的文件结构及每个文件的职责:
| 文件 | 职责 | 与其他文件的关系 |
|---|---|---|
BashTool.tsx | 主逻辑:解析输入、协调安全检查、执行命令、收集输出 | 调用所有其他文件 |
prompt.ts | 提供给 System Prompt 的 Bash 使用指南 | 影响模型如何调用 Bash |
bashSecurity.ts | 安全扫描(检测命令注入、危险模式) | 最先执行 |
bashPermissions.ts | 权限判断(是否需要用户确认) | 输出 allow/deny/ask |
commandSemantics.ts | 命令语义分析(读 vs 写 vs 网络) | 供权限和沙箱判断用 |
destructiveCommandWarning.ts | 检测 rm -rf、git push --force 等 | 触发额外警告 |
modeValidation.ts | 检查 Plan/ReadOnly 模式兼容性 | 可能直接拒绝 |
readOnlyValidation.ts | 只读模式下阻止写命令 | 可能直接拒绝 |
pathValidation.ts | 检查路径是否在允许范围内 | 可能直接拒绝 |
sedValidation.ts / sedEditParser.ts | 解析 sed 编辑命令 | 让权限弹窗展示编辑内容 |
shouldUseSandbox.ts | 决定是否启用沙箱 | 路由到沙箱或直接执行 |
UI.tsx / BashToolResultMessage.tsx | 结果渲染 | 最后执行 |
AgentTool 与内置 Agent
AgentTool 启动一个独立的对话循环(子代理),它有自己的 Tool 集合和 System Prompt。
内置 Agent 类型
| Agent | 工具权限 | 用途 | 何时使用 |
|---|---|---|---|
general-purpose | 全部工具 | 通用多步骤任务 | 复杂任务需要隔离上下文 |
Explore | 只读 (无 Edit/Write/Agent) | 代码库探索 | 搜索代码、回答问题 |
Plan | 只读 (无 Edit/Write/Agent) | 设计实现方案 | 需要规划再动手 |
claude-code-guide | Glob/Grep/Read/Web | Claude Code 使用指南 | 回答 "How do I..." |
verification | 配置文件限定 | 验证代码变更 | 测试/审查 |
statusline-setup | Read/Edit | 状态栏配置 | 配置 status line |
Agent 执行流程
用户自定义 Agent 从 ~/.claude/agents/ 目录加载,格式为 Markdown front matter + system prompt 内容。
Tool 注册与发现
工具最终汇聚到 AppState 的 tools 字段。来源有三个:
MCP 工具的名称格式为 mcp__<serverName>__<toolName>,避免与内置工具冲突。