Claude Code | | 约 32 分钟 | 12,689 字

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 命令
访问 APIWebFetch获取外部数据

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 对话的核心能力。通过熟练掌握各种工具,我们可以:

  1. 高效处理文件 - Read/Write/Edit 完成代码操作
  2. 精准搜索 - Grep/Glob 快速定位内容
  3. 执行命令 - Bash 运行任何 shell 命令
  4. 访问网络 - WebFetch/WebSearch 获取外部信息
  5. 扩展能力 - MCP 自定义任意工具

工具不是目的,而是手段。掌握工具的使用艺术,让 AI 成为你编程旅程中最强大的伙伴!

工具的好坏不在于它本身,而在于使用它的人。学会有节制地使用工具,有思考地调用工具,你会发现 AI 不是在取代你,而是在成就你。


下期预告

在接下来的文章中,我们将继续探索 Claude Code 的更多高级功能,包括记忆系统、多代理协作等话题,敬请期待!

评论

加载中...

相关文章

分享:

评论

加载中...