first commit

This commit is contained in:
H
2026-04-03 13:01:19 +08:00
commit 538eced414
2575 changed files with 645911 additions and 0 deletions

View File

@@ -0,0 +1,949 @@
# 工具系统详解
本文件说明:详细介绍 Claude Code 的工具系统,包括所有内置工具的功能、输入 schema、权限模型和核心逻辑。
## 1. 工具系统架构
### 1.1 工具注册表
所有内置工具在 `tools.ts` 中注册:
```typescript
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
```typescript
const inputSchema = z.object({
command: z.string().describe('要执行的命令'),
cwd: z.string().optional().describe('工作目录'),
timeout: z.number().optional().describe('超时时间(毫秒)'),
})
```
### 2.3 权限模型
**权限检查规则**
1. 检查命令是否匹配 `alwaysAllowRules`
2. 检查命令是否匹配 `alwaysDenyRules`
3. 检查命令是否属于危险命令(如 `rm -rf`
4. 用户确认后执行
**危险命令警告**
- `rm -rf` 类删除命令
- 格式化命令(如 `mkfs`
- 覆盖系统文件
### 2.4 核心逻辑
```typescript
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 支持使用沙箱执行危险命令:
```typescript
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
```typescript
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 核心逻辑
```typescript
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_unchanged` stub
- 避免重复发送相同内容浪费 Token
**内存新鲜度提示**
```typescript
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
```typescript
const inputSchema = z.object({
file_path: z.string().describe('文件路径'),
content: z.string().describe('文件内容'),
})
```
### 4.3 权限模型
- 写入权限检查
- 目录创建权限
- 危险路径保护(如 `/etc``/System`
### 4.4 核心逻辑
```typescript
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 支持两种编辑模式:
1. **Search/Replace 模式**:通过 old_string 和 new_string 进行替换
2. **Edit 模式**:直接编辑文件内容
### 5.2 输入 Schema
```typescript
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 核心逻辑
```typescript
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
```typescript
const inputSchema = z.object({
pattern: z.string().describe('Glob 模式(如 "**/*.ts"'),
cwd: z.string().optional().describe('搜索根目录'),
})
```
### 6.3 核心逻辑
```typescript
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
```typescript
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 核心逻辑
```typescript
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
```typescript
const inputSchema = z.object({
url: z.string().url().describe('网页 URL'),
})
```
### 8.3 权限模型
**预批准域名列表**
- anthropic.com
- claude.ai
- github.com
- 主要新闻和文档站点
### 8.4 核心逻辑
```typescript
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
```typescript
const inputSchema = z.object({
query: z.string().describe('搜索查询'),
})
```
### 9.3 核心逻辑
```typescript
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
```typescript
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 核心逻辑
```typescript
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
```typescript
const inputSchema = z.object({
name: z.string().describe('技能名称'),
args: z.string().optional().describe('传递给技能的参数'),
})
```
### 11.3 技能定义格式
技能目录结构:
```
~/.claude/skills/my-skill/
└── skill.md
```
skill.md 格式:
```markdown
---
name: my-skill
description: 这个技能做什么
---
# My Skill
这个技能用于执行特定任务...
## 使用方法
执行时会运行以下脚本...
```
### 11.4 核心逻辑
```typescript
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 是 MCPModel Context Protocol协议的工具包装器允许调用 MCP 服务器提供的工具。
### 12.2 输入 Schema
```typescript
const inputSchema = z.object({
server: z.string().describe('MCP 服务器名称'),
tool: z.string().describe('工具名称'),
arguments: z.record(z.string(), z.unknown()).optional().describe('工具参数'),
})
```
### 12.3 核心逻辑
```typescript
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
```typescript
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
```typescript
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
```typescript
const inputSchema = z.object({
recipient: z.string().describe('收件人标识'),
message: z.string().describe('消息内容'),
})
```
## 17. TeamCreateTool - 创建团队
### 17.1 功能描述
TeamCreateTool 创建一个 Agent 团队,团队成员可以协作完成任务。
### 17.2 输入 Schema
```typescript
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
```typescript
// EnterPlanModeTool
const inputSchema = z.object({
prompt: z.string().optional().describe('计划提示'),
})
// ExitPlanModeTool
// 无需参数
```
## 19. EnterWorktreeTool / ExitWorktreeTool
### 19.1 功能描述
用于创建和切换 Git Worktree便于在多个分支上同时工作。
### 19.2 输入 Schema
```typescript
// 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
```typescript
const inputSchema = z.object({
query: z.string().describe('搜索查询'),
})
```
### 20.3 延迟加载机制
```typescript
// 当工具数量超过阈值时启用延迟加载
const TOOL_SEARCH_THRESHOLD = 50
if (totalTools > TOOL_SEARCH_THRESHOLD) {
// 工具标记为 shouldDefer: true
// 首次调用时需要通过 ToolSearchTool 激活
}
```
## 21. CronCreateTool - 定时任务
### 21.1 功能描述
CronCreateTool 创建定时执行的任务。
### 21.2 输入 Schema
```typescript
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
```typescript
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
```typescript
const inputSchema = z.object({
duration: z.number().describe('延迟时间(秒)'),
})
```
## 24. SyntheticOutputTool - 结构化输出
### 24.1 功能描述
SyntheticOutputTool 用于提供符合 JSON Schema 的结构化输出。
### 24.2 输入 Schema
```typescript
const inputSchema = z.object({
schema: z.record(z.string(), z.unknown()).describe('JSON Schema'),
data: z.record(z.string(), z.unknown()).describe('输出数据'),
})
```
### 24.3 验证机制
```typescript
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 权限规则匹配
```typescript
// 权限规则支持通配符模式
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 渲染选项
```typescript
interface RenderOptions {
style?: 'condensed' | 'full'
theme?: ThemeName
verbose?: boolean
isTranscriptMode?: boolean
terminalSize?: { columns: number; rows: number }
}
```
## 27. 总结
Claude Code 的工具系统设计遵循以下原则:
1. **一致性**:所有工具实现统一的 Tool 接口
2. **安全性**:细粒度的权限控制和验证
3. **可扩展性**:支持 MCP、插件、技能等多种扩展机制
4. **用户控制**:用户可精确控制每个工具的使用权限
5. **高性能**:支持流式执行、缓存、去重等优化