Files
claude-code/docs/tools/what-are-tools.mdx
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

207 lines
8.4 KiB
Plaintext
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.
---
title: "工具系统设计 - AI 如何从说到做"
description: "深入理解 Claude Code 的 Tool 抽象设计:从类型定义、注册机制、调用链路到渲染系统,揭示 50+ 内置工具如何通过统一的 Tool 接口协同工作。"
keywords: ["工具系统", "Tool 抽象", "AI 工具", "function calling", "buildTool", "getTools"]
---
{/* 本章目标:基于 src/Tool.ts 和 src/tools.ts 揭示工具系统的完整架构 */}
## AI 为什么需要工具
大语言模型本质上只能做一件事:**根据输入文本,生成输出文本**。
它不能读文件、不能执行命令、不能搜索代码。要让 AI 真正"动手",需要一个桥梁——这就是 **Tool**(工具)。
工具是 AI 的双手。AI 说"我想读这个文件"工具系统替它真正去读AI 说"我想执行这条命令",工具系统替它真正去跑。
## Tool 类型35 个字段的统一接口
所有工具都实现 `src/Tool.ts:368` 的 `Tool<Input, Output, Progress>` 类型。这不是一个 class而是一个包含 35+ 字段的**结构化类型**structural typing任何满足该接口的对象就是一个工具
### 核心四要素
| 字段 | 类型 | 说明 |
|------|------|------|
| `name` | `string` | 唯一标识(如 `Read`、`Bash`、`Agent` |
| `description()` | `(input) => Promise<string>` | **动态描述**——根据输入参数返回不同描述(如 `Execute skill: ${skill}` |
| `inputSchema` | `z.ZodType` | Zod schema定义参数类型和校验规则 |
| `call()` | `(args, context, canUseTool, parentMessage, onProgress?) => Promise<ToolResult<Output>>` | 执行函数 |
### 注册与发现
| 字段 | 说明 |
|------|------|
| `aliases` | 别名数组(向后兼容重命名) |
| `searchHint` | 3-10 词的短语,供 ToolSearch 关键词匹配(如 `"jupyter"` for NotebookEdit |
| `shouldDefer` | 是否延迟加载(配合 ToolSearch 按需加载) |
| `alwaysLoad` | 永不延迟加载(如 SkillTool 必须在 turn 1 可见) |
| `isEnabled()` | 运行时开关(如 PowerShellTool 检查平台) |
### 安全与权限
| 字段 | 说明 |
|------|------|
| `validateInput()` | 输入校验(在权限检查之前),返回 `ValidationResult` |
| `checkPermissions()` | 权限检查(在校验之后),返回 `PermissionResult` |
| `isReadOnly()` | 是否只读操作(影响权限模式) |
| `isDestructive()` | 是否不可逆操作(删除、覆盖、发送) |
| `isConcurrencySafe()` | 相同输入是否可以并行执行 |
| `preparePermissionMatcher()` | 为 Hook 的 `if` 条件准备模式匹配器 |
| `interruptBehavior()` | 用户中断时的行为:`'cancel'` 或 `'block'` |
### 输出与渲染
| 字段 | 说明 |
|------|------|
| `maxResultSizeChars` | 结果字符上限(超出则持久化到磁盘,如 `100_000` |
| `mapToolResultToToolResultBlockParam()` | 将 Output 映射为 API 格式的 `ToolResultBlockParam` |
| `renderToolResultMessage()` | React 组件渲染工具结果到终端 |
| `renderToolUseMessage()` | React 组件渲染工具调用过程 |
| `backfillObservableInput()` | 在不破坏 prompt cache 的前提下回填可观察字段 |
### 上下文与 Prompt
| 字段 | 说明 |
|------|------|
| `prompt()` | 返回该工具的详细使用说明,注入到 System Prompt |
| `outputSchema` | 输出 Zod schema用于类型安全的结果处理 |
| `getPath()` | 提取操作的文件路径(用于权限匹配和 UI 显示) |
## 工具注册:`getTools()` 的分层组装
`src/tools.ts` 的 `getAllBaseTools()`(第 195 行)是工具注册的核心:
```
固定工具(始终可用):
AgentTool, BashTool, FileReadTool, FileEditTool, FileWriteTool,
NotebookEditTool, WebFetchTool, WebSearchTool, TodoWriteTool,
AskUserQuestionTool, SkillTool, EnterPlanModeTool, ExitPlanModeV2Tool,
TaskOutputTool, BriefTool, ListMcpResourcesTool, ReadMcpResourceTool
条件工具(运行时检查):
← hasEmbeddedSearchTools() ? [] : [GlobTool, GrepTool]
← isTodoV2Enabled() ? V2 Tasks : []
← isWorktreeModeEnabled() ? Worktree : []
← isAgentSwarmsEnabled() ? Teams : []
← isToolSearchEnabled() ? ToolSearch: []
← isPowerShellToolEnabled() ? PowerShell: []
Feature-flag 工具:
← feature('COORDINATOR_MODE') ? [coordinatorMode tools]
← feature('KAIROS') ? [SleepTool, SendUserFileTool, ...]
← feature('WEB_BROWSER_TOOL') ? [WebBrowserTool]
← feature('HISTORY_SNIP') ? [SnipTool]
Ant-only 工具:
← process.env.USER_TYPE === 'ant' ? [REPLTool, ConfigTool, TungstenTool]
```
`getTools()`(第 274 行)在 `getAllBaseTools()` 基础上应用权限过滤:
```typescript
export const getTools = (permissionContext): Tools => {
const base = getAllBaseTools()
// 过滤 blanket deny 规则命中的工具
return filterToolsByDenyRules(base, permissionContext)
}
```
**关键设计**:工具列表在每次 API 调用时组装(而非全局缓存),因为 `isEnabled()` 的结果可能随运行时状态变化。
## `buildTool()` 工厂函数
大多数工具通过 `buildTool()` 创建(`src/Tool.ts:789`),它是一个类型安全的构造器:
```typescript
export const BashTool: Tool<...> = buildTool({
name: 'Bash',
inputSchema: lazySchema(() => z.object({command: z.string(), ...})),
// ...其他字段
}) satisfies ToolDef<Input, Output, Progress>
```
`satisfies ToolDef` 确保编译时类型检查,`lazySchema` 延迟 Zod schema 解析(避免循环依赖)。
## 工具调用的完整链路
从 AI 发出 `tool_use` 到结果回传,经过以下步骤:
```
1. API 返回 tool_use block包含 name + input
2. StreamingToolExecutor.addTool() / runTools()
3. findToolByName() 查找工具
4. validateInput() — 输入校验
↓ 失败 → 返回错误 tool_result
5. canUseTool() — 权限 UIAsk 模式下弹确认)
↓ 拒绝 → 返回拒绝 tool_result
6. checkPermissions() — 规则匹配
7. call() — 执行实际操作
↓ onProgress() 回调实时更新 UI
8. 返回 ToolResult<Output>
9. mapToolResultToToolResultBlockParam() — 转为 API 格式
10. 新消息追加到对话 → 进入下一轮迭代
```
## 工具结果的预算控制
每个工具通过 `maxResultSizeChars` 声明输出上限:
- **BashTool**`30_000`(命令输出)
- **SkillTool**`100_000`(技能执行结果)
- **FileReadTool**`Infinity`(文件内容不走持久化,避免 Read→file→Read 循环)
超出上限的结果被 `applyToolResultBudget()``src/utils/toolResultStorage.ts`持久化到磁盘AI 只收到预览 + 文件路径。
## MCP 工具的扩展
MCP Server 提供的工具通过 `mcpInfo` 字段标记来源:
```typescript
mcpInfo?: { serverName: string; toolName: string }
```
MCP 工具的 `inputJSONSchema` 直接使用 JSON Schema而非 Zod因为 schema 来自远程协议。它们通过 `filterToolsByDenyRules()` 支持 `mcp__server` 前缀的 blanket deny 规则。
## 50+ 内置工具全景
<CardGroup cols={3}>
<Card title="文件操作" icon="file">
Read / Write / Edit / Glob / Grep / NotebookEdit
</Card>
<Card title="命令执行" icon="terminal">
Bash / PowerShell
</Card>
<Card title="对话管理" icon="comments">
Agent / SendMessage / AskUserQuestion
</Card>
<Card title="任务追踪" icon="list-check">
TaskCreate / TaskUpdate / TaskList / TaskGet / TaskOutput / TaskStop
</Card>
<Card title="Web 能力" icon="globe">
WebFetch / WebSearch / WebBrowser
</Card>
<Card title="规划与版本" icon="map">
EnterPlanMode / ExitPlanMode / Worktree / TodoWrite / ToolSearch
</Card>
</CardGroup>
## 工具的可视化渲染
工具不仅能"做事",还能"展示"。每个工具通过 React 组件定义 UI 渲染:
- **FileEdit** → `renderToolResultMessage` 展示语法高亮的 diff 视图
- **Bash** → 实时显示命令输出(通过 `onProgress` 回调),带进度指示
- **Grep** → 高亮匹配结果,显示文件路径和行号链接
- **Agent** → 显示子 Agent 的进度条和状态
- **SkillTool** → 渲染技能执行进度
`isSearchOrReadCommand()` 允许工具声明自己是搜索/读取操作,触发 UI 的折叠显示模式(避免大量搜索结果占满屏幕)。
`getActivityDescription()` 为 spinner 提供活动描述(如 "Reading src/foo.ts"、"Running bun test"),替代默认的工具名显示。