21 KiB
工具系统详解
本文件说明:详细介绍 Claude Code 的工具系统,包括所有内置工具的功能、输入 schema、权限模型和核心逻辑。
1. 工具系统架构
1.1 工具注册表
所有内置工具在 tools.ts 中注册:
export function getAllBaseTools(): Tools {
return [
AgentTool,
TaskOutputTool,
BashTool,
GlobTool,
GrepTool,
ExitPlanModeV2Tool,
FileReadTool,
FileEditTool,
FileWriteTool,
NotebookEditTool,
WebFetchTool,
TodoWriteTool,
WebSearchTool,
TaskStopTool,
AskUserQuestionTool,
SkillTool,
EnterPlanModeTool,
// ... 更多工具
]
}
1.2 工具调用流程
用户输入/模型决策
│
▼
checkPermissions() ────► 权限检查
│
▼
validateInput() ────► 输入验证
│
▼
call() ───────────► 工具执行
│
▼
renderToolResultMessage() ────► 结果渲染
1.3 工具基类接口
所有工具都实现以下核心方法:
| 方法 | 描述 |
|---|---|
call(args, context, canUseTool, parentMessage) |
工具执行入口 |
description(input, options) |
获取工具描述 |
inputSchema |
输入参数 Zod Schema |
checkPermissions(input, context) |
权限检查 |
validateInput(input, context) |
输入验证 |
renderToolUseMessage(input, options) |
渲染工具调用消息 |
renderToolResultMessage(content, options) |
渲染工具结果 |
2. BashTool - Shell 命令执行
2.1 功能描述
BashTool 是 Claude Code 最核心的工具之一,负责在用户授权下执行 Shell 命令。
2.2 输入 Schema
const inputSchema = z.object({
command: z.string().describe('要执行的命令'),
cwd: z.string().optional().describe('工作目录'),
timeout: z.number().optional().describe('超时时间(毫秒)'),
})
2.3 权限模型
权限检查规则:
- 检查命令是否匹配
alwaysAllowRules - 检查命令是否匹配
alwaysDenyRules - 检查命令是否属于危险命令(如
rm -rf) - 用户确认后执行
危险命令警告:
rm -rf类删除命令- 格式化命令(如
mkfs) - 覆盖系统文件
2.4 核心逻辑
async call({ command, cwd, timeout }, context) {
// 1. 展开路径
const fullCommand = expandPath(command)
// 2. 权限检查
const decision = await checkBashPermission(fullCommand, context)
// 3. 决定是否使用沙箱
const shouldSandbox = await shouldUseSandbox(fullCommand)
// 4. 执行命令
if (shouldSandbox) {
return executeInSandbox(fullCommand, cwd, timeout)
} else {
return executeDirect(fullCommand, cwd, timeout)
}
// 5. 追踪文件变更
if (result.modifiedFiles) {
for (const file of result.modifiedFiles) {
updateFileHistory(file, 'modified')
}
}
}
2.5 沙箱执行
Claude Code 支持使用沙箱执行危险命令:
async function shouldUseSandbox(command: string): Promise<boolean> {
// 检测命令是否危险
const isDangerous = detectDangerousCommand(command)
// 检查用户是否设置了沙箱偏好
const sandboxPreference = getSandboxPreference()
return isDangerous || sandboxPreference === 'always'
}
3. FileReadTool - 文件读取
3.1 功能描述
FileReadTool 用于读取文件内容,支持多种文件类型:
- 纯文本文件
- 图片文件(PNG, JPG, GIF, WebP)
- PDF 文档
- Jupyter Notebooks
3.2 输入 Schema
const inputSchema = z.object({
file_path: z.string().describe('要读取的文件绝对路径'),
offset: z.number().int().nonnegative().optional().describe('起始行号'),
limit: z.number().int().positive().optional().describe('读取行数'),
pages: z.string().optional().describe('PDF 页码范围(如 "1-5")'),
})
3.3 权限模型
- 检查文件路径是否在允许目录下
- 检查是否匹配 deny rules
- 检查是否为会话相关文件(特殊处理)
3.4 核心逻辑
async call({ file_path, offset = 1, limit, pages }, context) {
const ext = path.extname(file_path).toLowerCase()
// 根据文件类型处理
if (ext === '.ipynb') {
return readNotebook(file_path)
} else if (IMAGE_EXTENSIONS.has(ext)) {
return readImage(file_path)
} else if (ext === '.pdf') {
return readPDF(file_path, pages)
} else {
return readTextFile(file_path, offset, limit)
}
}
3.5 特殊处理
Deduplication(去重):
- 如果文件未修改且读取范围相同,返回
file_unchangedstub - 避免重复发送相同内容浪费 Token
内存新鲜度提示:
function memoryFileFreshnessNote(mtimeMs: number): string {
const age = Date.now() - mtimeMs
if (age < 60000) return '(updated seconds ago)'
if (age < 3600000) return `(updated ${Math.floor(age/60000)}m ago)`
// ...
}
4. FileWriteTool - 文件写入
4.1 功能描述
FileWriteTool 用于创建或覆盖文件内容。
4.2 输入 Schema
const inputSchema = z.object({
file_path: z.string().describe('文件路径'),
content: z.string().describe('文件内容'),
})
4.3 权限模型
- 写入权限检查
- 目录创建权限
- 危险路径保护(如
/etc、/System)
4.4 核心逻辑
async call({ file_path, content }, context) {
// 1. 验证路径
const fullPath = expandPath(file_path)
// 2. 安全检查
if (isDangerousPath(fullPath)) {
throw new Error('Cannot write to protected path')
}
// 3. 确保目录存在
const dir = path.dirname(fullPath)
await ensureDirExists(dir)
// 4. 写入文件
await writeFile(fullPath, content)
// 5. 更新文件状态缓存
context.readFileState.set(fullPath, {
content,
timestamp: Date.now(),
})
return { success: true, path: fullPath }
}
5. FileEditTool - 文件编辑
5.1 功能描述
FileEditTool 支持两种编辑模式:
- Search/Replace 模式:通过 old_string 和 new_string 进行替换
- Edit 模式:直接编辑文件内容
5.2 输入 Schema
const inputSchema = z.object({
file_path: z.string().describe('文件路径'),
old_string: z.string().optional().describe('要替换的文本(精确匹配)'),
new_string: z.string().optional().describe('替换后的文本'),
// 或者使用 partial_diff
partial_diff: z.object({
replacements: z.array(z.object({
old_string: z.string(),
new_string: z.string(),
}))
}).optional()
})
5.3 权限模型
- 需要有效的 old_string(防止意外覆盖)
- 不能用于删除整个文件
- 禁止编辑二进制文件
5.4 核心逻辑
async call({ file_path, old_string, new_string, partial_diff }, context) {
// 1. 读取当前文件内容
const content = await readFile(file_path)
// 2. 执行替换
let newContent: string
if (partial_diff) {
// 批量替换
newContent = content
for (const { old_string, new_string } of partial_diff.replacements) {
newContent = applyReplacement(newContent, old_string, new_string)
}
} else {
// 单次替换
newContent = applyReplacement(content, old_string, new_string)
}
// 3. 验证 old_string 存在且唯一
const occurrences = countOccurrences(content, old_string)
if (occurrences === 0) {
throw new Error('old_string not found in file')
}
if (occurrences > 1) {
throw new Error('old_string appears multiple times, be more specific')
}
// 4. 写入文件
await writeFile(file_path, newContent)
// 5. 更新缓存
context.readFileState.set(file_path, {
content: newContent,
timestamp: Date.now(),
})
}
6. GlobTool - 文件模式匹配
6.1 功能描述
使用 glob 模式查找文件。
6.2 输入 Schema
const inputSchema = z.object({
pattern: z.string().describe('Glob 模式(如 "**/*.ts")'),
cwd: z.string().optional().describe('搜索根目录'),
})
6.3 核心逻辑
async call({ pattern, cwd }, context) {
// 使用 ripgrep 的 glob 功能实现高性能搜索
const results = await execFile('rg', [
'--files-with-matches',
'--glob', pattern,
cwd || process.cwd()
])
return {
files: results.split('\n').filter(Boolean)
}
}
7. GrepTool - 代码搜索
7.1 功能描述
在代码库中搜索匹配文本。
7.2 输入 Schema
const inputSchema = z.object({
pattern: z.string().describe('搜索模式(支持正则)'),
cwd: z.string().optional().describe('搜索目录'),
context: z.number().optional().describe('上下文行数'),
file_pattern: z.string().optional().describe('文件过滤模式'),
})
7.3 核心逻辑
async call({ pattern, cwd, context = 3, file_pattern }, context) {
const args = [
'--json',
'-C', context.toString(),
pattern,
]
if (file_pattern) {
args.push('--glob', file_pattern)
}
args.push(cwd || '.')
const results = await execFile('rg', args)
// 解析 JSON 输出
const matches = JSON.parse(results)
return {
matches: matches.map(parseMatch),
count: matches.length
}
}
8. WebFetchTool - 网页获取
8.1 功能描述
获取网页内容。
8.2 输入 Schema
const inputSchema = z.object({
url: z.string().url().describe('网页 URL'),
})
8.3 权限模型
预批准域名列表:
- anthropic.com
- claude.ai
- github.com
- 主要新闻和文档站点
8.4 核心逻辑
async call({ url }, context) {
// 1. URL 安全检查
if (!isPreapprovedUrl(url)) {
const decision = await context.requestPrompt('web_fetch', url)
if (!decision.approved) {
throw new Error('URL not approved')
}
}
// 2. 获取网页
const response = await fetch(url)
// 3. 解析 HTML
const text = await extractText(response)
// 4. 清理和格式化
return {
content: cleanHtml(text),
title: extractTitle(response),
url,
}
}
9. WebSearchTool - 网络搜索
9.1 功能描述
执行网络搜索。
9.2 输入 Schema
const inputSchema = z.object({
query: z.string().describe('搜索查询'),
})
9.3 核心逻辑
async call({ query }, context) {
// 使用搜索引擎 API
const results = await searchEngine.query(query)
return {
results: results.map(r => ({
title: r.title,
url: r.url,
snippet: r.snippet,
})),
total: results.length,
}
}
10. AgentTool - 子 Agent
10.1 功能描述
AgentTool 允许 Claude 创建和管理子 Agent 来并行执行任务。
10.2 输入 Schema
const inputSchema = z.object({
agent: z.enum(['general', 'plan', 'explore', ...]).describe('Agent 类型'),
prompt: z.string().describe('给 Agent 的指令'),
agentId: z.string().optional().describe('现有 Agent ID(用于恢复)'),
maxTurns: z.number().optional().describe('最大轮次'),
})
10.3 Agent 类型
| 类型 | 描述 |
|---|---|
general |
通用任务执行 |
plan |
计划制定 |
explore |
代码探索 |
verification |
验证检查 |
10.4 核心逻辑
async call({ agent, prompt, maxTurns }, context) {
// 1. 创建或恢复 Agent
const agentId = await createSubAgent({
type: agent,
prompt,
maxTurns,
})
// 2. 执行 Agent
const result = await runAgent(agentId, context)
// 3. 返回结果
return {
output: result.output,
agentId,
turns: result.turns,
}
}
11. SkillTool - 技能执行
11.1 功能描述
SkillTool 用于执行用户定义的技能(Skills),这些技能以 Markdown 文件形式保存在本地目录中。
11.2 输入 Schema
const inputSchema = z.object({
name: z.string().describe('技能名称'),
args: z.string().optional().describe('传递给技能的参数'),
})
11.3 技能定义格式
技能目录结构:
~/.claude/skills/my-skill/
└── skill.md
skill.md 格式:
---
name: my-skill
description: 这个技能做什么
---
# My Skill
这个技能用于执行特定任务...
## 使用方法
执行时会运行以下脚本...
11.4 核心逻辑
async call({ name, args }, context) {
// 1. 查找技能定义
const skill = await findSkill(name)
if (!skill) {
throw new Error(`Skill not found: ${name}`)
}
// 2. 解析技能定义
const { prompt, script } = parseSkillDefinition(skill)
// 3. 执行脚本
const output = await executeScript(script, { args })
return {
output,
skillName: name,
}
}
12. MCPTool - Model Context Protocol
12.1 功能描述
MCPTool 是 MCP(Model Context Protocol)协议的工具包装器,允许调用 MCP 服务器提供的工具。
12.2 输入 Schema
const inputSchema = z.object({
server: z.string().describe('MCP 服务器名称'),
tool: z.string().describe('工具名称'),
arguments: z.record(z.string(), z.unknown()).optional().describe('工具参数'),
})
12.3 核心逻辑
async call({ server, tool, arguments }, context) {
// 1. 获取 MCP 客户端
const client = context.mcpClients.find(c => c.name === server)
if (!client) {
throw new Error(`MCP server not found: ${server}`)
}
// 2. 发送工具调用请求
const result = await client.callTool(tool, arguments)
// 3. 返回结果
return result
}
13. LSPTool - 语言服务器协议
13.1 功能描述
LSPTool 提供对 Language Server Protocol 的访问,用于代码导航、诊断等。
13.2 核心功能
- 跳转到定义 (Go to Definition)
- 查找引用 (Find References)
- 代码补全 (Completions)
- 诊断信息 (Diagnostics)
14. NotebookEditTool - Jupyter Notebook 编辑
14.1 功能描述
NotebookEditTool 专门用于编辑 Jupyter Notebook 文件。
14.2 输入 Schema
const inputSchema = z.object({
file_path: z.string().describe('Notebook 文件路径'),
cell_id: z.string().optional().describe('要编辑的单元格 ID'),
new_source: z.string().optional().describe('新单元格内容'),
action: z.enum(['insert', 'delete', 'move']).optional().describe('操作类型'),
})
15. Task 系列工具
15.1 概述
Task 系列工具提供完整的任务管理功能:
| 工具 | 描述 |
|---|---|
TaskCreateTool |
创建新任务 |
TaskGetTool |
获取任务详情 |
TaskUpdateTool |
更新任务状态 |
TaskListTool |
列出任务 |
TaskStopTool |
停止任务 |
TaskOutputTool |
获取任务输出 |
15.2 TaskCreateTool 输入 Schema
const inputSchema = z.object({
description: z.string().describe('任务描述'),
status: z.enum(['pending', 'in_progress', 'completed']).optional(),
priority: z.enum(['low', 'medium', 'high']).optional(),
})
15.3 任务状态流转
pending ──► in_progress ──► completed
│ │
└──────► failed
16. SendMessageTool - 团队消息
16.1 功能描述
SendMessageTool 用于向团队成员发送消息。
16.2 输入 Schema
const inputSchema = z.object({
recipient: z.string().describe('收件人标识'),
message: z.string().describe('消息内容'),
})
17. TeamCreateTool - 创建团队
17.1 功能描述
TeamCreateTool 创建一个 Agent 团队,团队成员可以协作完成任务。
17.2 输入 Schema
const inputSchema = z.object({
name: z.string().describe('团队名称'),
members: z.array(z.object({
name: z.string(),
role: z.enum(['coordinator', 'worker', 'reviewer']),
agentType: z.string().optional(),
})).describe('团队成员'),
})
17.3 团队角色
| 角色 | 描述 |
|---|---|
coordinator |
协调者,负责分配任务 |
worker |
执行者,负责完成任务 |
reviewer |
审核者,负责检查结果 |
18. EnterPlanModeTool / ExitPlanModeTool
18.1 功能描述
计划模式允许 Claude 在执行前先制定计划,用户确认后再执行。
18.2 输入 Schema
// EnterPlanModeTool
const inputSchema = z.object({
prompt: z.string().optional().describe('计划提示'),
})
// ExitPlanModeTool
// 无需参数
19. EnterWorktreeTool / ExitWorktreeTool
19.1 功能描述
用于创建和切换 Git Worktree,便于在多个分支上同时工作。
19.2 输入 Schema
// EnterWorktreeTool
const inputSchema = z.object({
branch: z.string().describe('分支名'),
path: z.string().optional().describe('Worktree 路径'),
})
// ExitWorktreeTool
const inputSchema = z.object({
path: z.string().optional().describe('要删除的 Worktree 路径'),
})
20. ToolSearchTool - 工具搜索
20.1 功能描述
ToolSearchTool 允许模型在运行时搜索可用工具,当工具过多时会延迟加载。
20.2 输入 Schema
const inputSchema = z.object({
query: z.string().describe('搜索查询'),
})
20.3 延迟加载机制
// 当工具数量超过阈值时启用延迟加载
const TOOL_SEARCH_THRESHOLD = 50
if (totalTools > TOOL_SEARCH_THRESHOLD) {
// 工具标记为 shouldDefer: true
// 首次调用时需要通过 ToolSearchTool 激活
}
21. CronCreateTool - 定时任务
21.1 功能描述
CronCreateTool 创建定时执行的任务。
21.2 输入 Schema
const inputSchema = z.object({
schedule: z.string().describe('Cron 表达式'),
command: z.string().describe('要执行的命令'),
name: z.string().optional().describe('任务名称'),
})
22. RemoteTriggerTool - 远程触发
22.1 功能描述
RemoteTriggerTool 允许从远程触发任务执行。
22.2 输入 Schema
const inputSchema = z.object({
trigger_id: z.string().describe('触发器 ID'),
payload: z.record(z.string(), z.unknown()).optional().describe('传递的数据'),
})
23. SleepTool - 延迟执行
23.1 功能描述
SleepTool 用于在任务执行中引入延迟。
23.2 输入 Schema
const inputSchema = z.object({
duration: z.number().describe('延迟时间(秒)'),
})
24. SyntheticOutputTool - 结构化输出
24.1 功能描述
SyntheticOutputTool 用于提供符合 JSON Schema 的结构化输出。
24.2 输入 Schema
const inputSchema = z.object({
schema: z.record(z.string(), z.unknown()).describe('JSON Schema'),
data: z.record(z.string(), z.unknown()).describe('输出数据'),
})
24.3 验证机制
async call({ schema, data }, context) {
// 使用 Zod 验证数据
const validator = z.object(schema)
const result = validator.safeParse(data)
if (!result.success) {
throw new Error(`Invalid output: ${result.error.message}`)
}
return { validated: result.data }
}
25. 工具权限系统总结
25.1 权限模式
| 模式 | 描述 | 行为 |
|---|---|---|
default |
默认模式 | 询问危险操作 |
auto |
自动模式 | 基于规则自动决定 |
bypass |
绕过模式 | 允许所有操作 |
plan |
计划模式 | 强制计划模式 |
25.2 权限检查流程
1. validateInput() - 验证输入有效性
│
▼
2. checkPermissions() - 检查权限规则
│
├──► alwaysAllow → 返回允许
│
├──► alwaysDeny → 返回拒绝
│
└──► 需要询问 → 等待用户确认
25.3 权限规则匹配
// 权限规则支持通配符模式
const rules = {
'Bash(rm *)': 'deny', // 拒绝所有 rm 命令
'Bash(git *)': 'allow', // 允许所有 git 命令
'Read(/home/user/src/*)': 'allow', // 允许读取特定目录
}
26. 工具渲染系统
26.1 渲染方法
| 方法 | 用途 |
|---|---|
renderToolUseMessage |
渲染工具调用消息 |
renderToolUseTag |
渲染工具标签(如超时标记) |
renderToolUseProgressMessage |
渲染进度消息 |
renderToolResultMessage |
渲染工具结果 |
renderToolUseErrorMessage |
渲染错误消息 |
renderToolUseRejectedMessage |
渲染拒绝消息 |
26.2 渲染选项
interface RenderOptions {
style?: 'condensed' | 'full'
theme?: ThemeName
verbose?: boolean
isTranscriptMode?: boolean
terminalSize?: { columns: number; rows: number }
}
27. 总结
Claude Code 的工具系统设计遵循以下原则:
- 一致性:所有工具实现统一的 Tool 接口
- 安全性:细粒度的权限控制和验证
- 可扩展性:支持 MCP、插件、技能等多种扩展机制
- 用户控制:用户可精确控制每个工具的使用权限
- 高性能:支持流式执行、缓存、去重等优化