Claude Code Tool Use 深入指南
掌握 Claude Code 工具调用能力,实现 AI 与外部系统的深度集成
什么是 Tool Use
Tool Use(工具调用)是 Claude Code 最核心的能力之一,它让 AI 能够主动使用各种工具来完成任务。不同于传统的 AI 对话只能生成文本回复,Tool Use 让 Claude Code 可以:
- 读取和修改文件
- 执行系统命令
- 搜索和分析代码
- 访问网页内容
- 调用外部 API
- 与任意系统集成
当 Claude Code 需要完成一个任务时,它会智能判断需要使用哪些工具,并以正确的参数调用它们。这种「思考-行动」的循环模式让我们与 AI 的协作更加高效和强大。
内置工具详解
Claude Code 内置了一系列强大的工具,涵盖了日常开发的大部分需求。
1. 文件操作工具
Read - 读取文件
# 读取单个文件
Read /path/to/file.ts
# 读取多个文件
Read /path/to/file1.ts /path/to/file2.ts
参数说明:
file_path: 必需,文件绝对路径limit: 可选,限制读取的行数offset: 可选,从指定行开始读取
// 读取文件的前 50 行
const config = await read({
file_path: '/project/src/config.ts',
limit: 50
});
Write - 写入文件
Write /path/to/new-file.ts --content "console.log('Hello')"
// 创建新文件
await write({
file_path: '/project/src/utils/helper.ts',
content: `export function formatDate(date: Date): string {
return date.toISOString().split('T')[0];
}`
});
Edit - 编辑文件
# 精确替换
Edit /path/to/file.ts --old_string "旧内容" --new_string "新内容"
# 替换所有匹配
Edit /path/to/file.ts --old_string "const API_URL" --new_string "const API_URL_V2" --replace_all
// 修改函数实现
await edit({
file_path: '/project/src/api/client.ts',
old_string: `async function fetchData(url: string) {
const response = await fetch(url);
return response.json();
}`,
new_string: `async function fetchData(url: string, options?: RequestInit) {
const response = await fetch(url, {
...options,
headers: {
'Content-Type': 'application/json',
...options?.headers
}
});
if (!response.ok) {
throw new Error(\`HTTP \${response.status}\`);
}
return response.json();
}`
});
2. 搜索工具
Grep - 内容搜索
# 搜索包含特定文本的文件
Grep "function handleSubmit" --path /project/src
# 使用正则表达式
Grep "class \w+ extends" --type ts
# 只显示匹配数量
Grep "TODO" --output_mode count
// 搜索并查看上下文
const results = await grep({
pattern: 'useState',
path: '/project/src/components',
output_mode: 'content',
context: 3 // 显示前后 3 行
});
// 输出格式
// src/components/Button.tsx:15: const [loading, setLoading] = useState(false);
// src/components/Button.tsx:16: const [error, setError] = useState<string | null>(null);
Glob - 文件名搜索
# 查找所有 TypeScript 文件
Glob "**/*.ts" --path /project/src
# 查找特定目录下的配置文件
Glob "config.*" --path /project
# 查找测试文件
Glob "**/*.test.ts" --path /project
// 批量查找并处理
const files = await glob({
pattern: '**/*.test.ts',
path: '/project/src'
});
// 对每个测试文件进行处理
for (const file of files) {
const content = await read({ file_path: file });
// 分析测试文件...
}
3. 命令执行工具
Bash - 执行 Shell 命令
# 执行命令
Bash "npm run build"
# 执行多条命令
Bash "npm install && npm run build"
# 后台运行
Bash "python server.py" --run_in_background true
// 安装依赖并构建
const installResult = await bash({
command: 'npm install',
description: '安装项目依赖'
});
if (installResult.exitCode === 0) {
const buildResult = await bash({
command: 'npm run build',
description: '构建生产版本'
});
}
4. Web 访问工具
WebFetch - 获取网页内容
# 获取网页内容
WebFetch https://api.github.com/users/octocat
# 带提示词的分析
WebFetch https://example.com --prompt "提取页面中的所有文章标题"
// 获取并解析 API 数据
const response = await webfetch({
url: 'https://api.github.com/repos/anthropics/claude-code/stats/contributors',
prompt: '提取每个贡献者的提交数量和用户名,格式化为 JSON'
});
// response.content[0].text 包含解析后的数据
WebSearch - 网络搜索
# 搜索最新文档
WebSearch "Claude Code documentation 2026"
# 搜索特定问题
WebSearch "Claude Code API integration best practices"
自定义工具开发
除了内置工具,我们还可以创建自定义工具来满足特定需求。
1. 创建自定义 Skill
Skill 是最简单的方式,适合封装常用操作序列:
<!-- .claude/skills/refactor-component.md -->
# 重构 React 组件
将类组件转换为函数组件,并应用现代 React 模式。
## 执行步骤
1. 分析当前组件结构
2. 使用 useState/useEffect 替代 this.state/componentDidMount
3. 使用 Hooks 提取重复逻辑
4. 添加 TypeScript 类型
5. 运行测试确保功能正常
$ARGUMENTS
使用方式:
/refactor-component MyComponent
2. 自定义命令
命令适合快速执行特定任务:
<!-- .claude/commands/generate-test.md -->
# 生成测试文件
为指定的源文件生成对应的测试文件。
## 步骤
1. 分析源文件的导出函数/类
2. 创建测试文件结构
3. 生成基本测试用例
4. 确保测试可以运行
$ARGUMENTS
3. MCP 工具集成
通过 MCP(Model Context Protocol),我们可以添加更强大的自定义工具:
安装现有 MCP
# 添加文件系统 MCP
claude mcp add filesystem /path/to/mcp-filesystem
# 添加 GitHub MCP
claude mcp add npm:@anthropic-ai/mcp-server-github
# 添加数据库 MCP
claude mcp add npm:@modelcontextprotocol/server-sqlite
创建自定义 MCP Server
// my-mcp-server/src/index.ts
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
CallToolRequestSchema,
ListToolsRequestSchema
} from '@modelcontextprotocol/sdk/types.js';
const server = new Server(
{ name: 'project-tools', version: '1.0.0' },
{ capabilities: { tools: {} } }
);
// 定义可用工具
server.setRequestHandler(ListToolsRequestSchema, async () => {
return {
tools: [
{
name: 'create_component',
description: '创建一个新的 React 组件及其测试文件',
inputSchema: {
type: 'object',
properties: {
name: { type: 'string', description: '组件名称' },
type: {
type: 'string',
enum: ['function', 'class'],
description: '组件类型'
},
withTypescript: { type: 'boolean', description: '是否使用 TypeScript' }
},
required: ['name']
}
},
{
name: 'generate_types',
description: '从接口数据生成 TypeScript 类型定义',
inputSchema: {
type: 'object',
properties: {
json: { type: 'string', description: 'JSON 格式的接口数据' },
rootName: { type: 'string', description: '根类型名称' }
},
required: ['json', 'rootName']
}
},
{
name: 'run_lint_fix',
description: '运行 ESLint 并自动修复',
inputSchema: {
type: 'object',
properties: {
path: { type: 'string', description: '要检查的文件或目录路径' }
},
required: ['path']
}
}
]
};
});
// 工具实现
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
switch (name) {
case 'create_component': {
const { name, type = 'function', withTypescript = true } = args;
const ext = withTypescript ? 'tsx' : 'jsx';
const content = type === 'function'
? `export function ${name}() {\n return <div>${name}</div>;\n}`
: `class ${name} extends React.Component {\n render() {\n return <div>${name}</div>;\n }\n}`;
return {
content: [{
type: 'text',
text: `已创建组件: src/components/${name}.${ext}`
}]
};
}
case 'generate_types': {
// 简化实现:实际应该用 quicktype 库
const data = JSON.parse(args.json);
const rootName = args.rootName;
// ... 生成类型定义
return {
content: [{
type: 'text',
text: '生成的类型定义...'
}]
};
}
case 'run_lint_fix': {
const result = await exec(`npx eslint ${args.path} --fix`);
return {
content: [{
type: 'text',
text: result.stdout || 'Lint 完成'
}]
};
}
default:
throw new Error(`未知工具: ${name}`);
}
});
// 启动服务器
const transport = new StdioServerTransport();
await server.connect(transport);
工具使用最佳实践
1. 合理选择工具
不同场景使用不同的工具:
| 场景 | 推荐工具 | 说明 |
|---|---|---|
| 读取配置文件 | Read | 精确读取,不解析 |
| 搜索代码 | Grep | 支持正则和上下文 |
| 查找文件名 | Glob | 快速定位文件 |
| 执行构建 | Bash | 运行 npm/build 命令 |
| 访问 API | WebFetch | 获取外部数据 |
2. 批量操作优化
// 不推荐:逐个读取
for (const file of files) {
await read({ file_path: file });
}
// 推荐:批量读取
const contents = await Promise.all(
files.map(f => read({ file_path: f }))
);
3. 错误处理
async function safeRead(filePath: string) {
try {
return await read({ file_path: filePath });
} catch (error) {
if (error.message.includes('ENOENT')) {
return null; // 文件不存在
}
throw error; // 其他错误继续抛出
}
}
4. 上下文管理
在 CLAUDE.md 中定义项目的工具使用规范:
# 工具使用规范
## 文件操作
- 修改文件前先读取内容
- 使用 Edit 而非 Write 进行小修改
- 大面积重写时使用 Write
## 命令执行
- 构建命令使用 npm run build
- 测试使用 npm test
- 代码检查使用 npx eslint
## 安全
- 不执行 rm -rf /
- 不修改 .env 文件
- 执行危险操作前需要确认
实际应用案例
案例一:自动代码审查
// 使用多个工具协作进行代码审查
async function codeReview(filePath: string) {
// 1. 读取文件
const content = await read({ file_path: filePath });
// 2. 搜索潜在问题
const consoleLogs = await grep({
path: filePath,
output_mode: 'content',
pattern: 'console\\.(log|error|warn)'
});
const todos = await grep({
path: filePath,
output_mode: 'content',
pattern: 'TODO|FIXME|HACK'
});
// 3. 检查测试覆盖
const testFile = filePath.replace(/\.(ts|tsx)$/, '.test.$1');
const hasTest = await glob({ path: testFile });
return {
file: filePath,
issues: {
consoleLogs: consoleLogs.length,
todos: todos.length,
hasTests: hasTest.length > 0
}
};
}
案例二:批量重命名重构
// 批量重命名组件
async function renameComponent(oldName: string, newName: string) {
// 1. 找到所有引用
const references = await grep({
pattern: oldName,
path: '/src',
output_mode: 'files_with_matches'
});
// 2. 逐个文件替换
for (const file of references) {
await edit({
file_path: file,
old_string: oldName,
new_string: newName,
replace_all: true
});
}
// 3. 重命名文件
const componentFiles = await glob({
pattern: `**/*${oldName}*`,
path: '/src'
});
for (const file of componentFiles) {
const newPath = file.replace(oldName, newName);
await bash({
command: `mv ${file} ${newPath}`
});
}
}
案例三:自动化文档生成
// 从代码生成 API 文档
async function generateAPIDocs() {
// 1. 查找所有导出的函数
const sourceFiles = await glob({
pattern: '**/api/**/*.ts',
path: '/src'
});
const docs = [];
for (const file of sourceFiles) {
const content = await read({ file_path: file });
// 2. 解析 JSDoc 注释
const functions = await grep({
path: file,
output_mode: 'content',
pattern: '/\\*\\*[\\s\\S]*?\\*/\\s*(export\\s+)?function\\s+(\\w+)'
});
for (const fn of functions) {
docs.push({
file,
function: fn.match[2],
doc: fn.match[1]
});
}
}
// 3. 生成 Markdown 文档
const markdown = docs.map(d => `## ${d.function}\n\n${d.doc}\n`).join('\n');
await write({
file_path: '/docs/api.md',
content: `# API 文档\n\n${markdown}`
});
}
工具调用进阶技巧
1. 链式调用
多个工具可以链式调用形成工作流:
// 读取 -> 分析 -> 修改 -> 测试
const content = await read({ file_path: '/src/utils.ts' });
const improved = await analyzeAndImprove(content);
await write({ file_path: '/src/utils.ts', content: improved });
await bash({ command: 'npm test -- --coverage' });
2. 条件分支
根据文件内容决定使用哪些工具:
const content = await read({ file_path: '/src/main.ts' });
if (content.includes('React')) {
// React 项目处理
await installDependencies(['react', 'react-dom']);
} else if (content.includes('Vue')) {
// Vue 项目处理
await installDependencies(['vue']);
} else {
// 原生 JS 处理
console.log('原生 JS 项目');
}
3. 并行执行
独立任务并行执行提高效率:
// 并行执行多个独立的搜索
const [errors, warnings, todos] = await Promise.all([
grep({ path: '/src', output_mode: 'count', pattern: 'Error' }),
grep({ path: '/src', output_mode: 'count', pattern: 'Warning' }),
grep({ path: '/src', output_mode: 'count', pattern: 'TODO' })
]);
console.log({ errors, warnings, todos });
常见问题
Q1: 工具执行失败怎么办
Claude Code 会自动重试失败的命令,并在失败时提供详细的错误信息。检查:
- 文件路径是否正确
- 命令语法是否正确
- 依赖是否已安装
Q2: 如何调试工具调用
使用 --verbose 模式查看详细的工具调用日志:
claude --verbose
Q3: 可以自定义工具的返回格式吗
可以,通过 MCP Server 的响应格式控制。推荐返回结构化的 JSON:
return {
content: [{
type: 'text',
text: JSON.stringify({
success: true,
data: { ... }
})
}]
};
Q4: 工具调用有频率限制吗
目前没有严格的频率限制,但建议:
- 批量操作时适当添加延迟
- 避免极端高频的调用
- 合理利用缓存减少重复查询
总结
Tool Use 是 Claude Code 区别于普通 AI 对话的核心能力。通过熟练掌握各种工具,我们可以:
- 高效处理文件 - Read/Write/Edit 完成代码操作
- 精准搜索 - Grep/Glob 快速定位内容
- 执行命令 - Bash 运行任何 shell 命令
- 访问网络 - WebFetch/WebSearch 获取外部信息
- 扩展能力 - MCP 自定义任意工具
工具不是目的,而是手段。掌握工具的使用艺术,让 AI 成为你编程旅程中最强大的伙伴!
工具的好坏不在于它本身,而在于使用它的人。学会有节制地使用工具,有思考地调用工具,你会发现 AI 不是在取代你,而是在成就你。
下期预告
在接下来的文章中,我们将继续探索 Claude Code 的更多高级功能,包括记忆系统、多代理协作等话题,敬请期待!
相关文章
Claude Code MCP 深入:自定义 Server 开发实战
手把手教你开发自定义 MCP Server,扩展 Claude Code 的能力边界,实现与任意系统集成
🤖Claude Codeoh-my-claudecode 项目分析:它用到了 Claude Code 的哪些功能?
深入分析 oh-my-claudecode 这个多智能体编排框架,探索它如何充分利用 Claude Code 的各种功能,从 Agent 定义到 Skill 系统再到 MCP 集成
🤖Claude CodeClaude Code Skills 技能系统完全指南
深入了解 Claude Code 的 Skills 技能系统,包括内置技能、自定义配置和实战用法
评论
加载中...
评论
加载中...