LogoSteve
  • 博客
  • 关于我
Claude Code 是如何做工具调用优化的
2026/04/05

Claude Code 是如何做工具调用优化的

看了 Claude Code 的源码之后,我发现它在工具调用上的优化不是靠某一个技巧,而是多层机制叠加的结果。

看了 claude-code 的源码之后,我发现它在工具调用上的优化不是靠某一个技巧,而是多层机制叠加的结果。

最有价值的部分可以分成六类。

1. 工具自己会"教模型怎么用它"

最直接的优化写在每个工具的 prompt 里。

GrepTool/prompt.ts 里明确说:"ALWAYS use GrepTool for search tasks","NEVER invoke grep or rg as Bash command"。GlobTool 的 prompt 会告诉模型这是按文件名模式找文件的工具,以及什么时候该用它。WebFetchTool 甚至会说,如果有更合适的专用工具,就优先用专用工具。

这些 prompt 不是在简单描述功能,而是在明确告诉模型:这个工具解决什么问题、什么时候应该用、什么时候不该用、它比别的工具好在哪里。这种引导对命中率提升很大。

在实际构建 agent 系统时,工具定义往往偏"schema 正确",但"选择引导"还不够。后面需要补上:什么时候 glob_files 优于 grep_code,什么时候 read_file_range 优于 read_text_file,等等。

2. 压低 Bash 的吸引力

BashTool/prompt.ts 里写了很多"不要用 Bash 做这些事"的规则:不要用 shell 做搜索、不要用 shell 读文件、不要用 shell 找文件,优先用专用工具。

这比单纯加新工具更重要。如果没有这层约束,模型经常会觉得 shell 更通用、更熟悉、也能凑合做,然后就回退到 Bash。

如果你已经在系统 prompt 里写了优先用专用工具,但还可以更强硬一点,比如明确说:"Do not use shell commands for file discovery, JSON reading, line-range reads, or git status when a dedicated tool exists."

这里的设计哲学是:万能工具是系统必备的 backup,但优先级必须低于专用工具。专用工具是经过抽丝剥茧后的最佳实践,而万能工具需要 agent 自己编排使用,难免出错。

3. 工具检索机制

代码里能看到 searchHint、toAutoClassifierInput、ToolSearchTool,以及按 searchHint 排序匹配的逻辑。

他们不是把所有工具平铺给模型,而是让每个工具先声明一个高信号的能力短语,比如"find files by name pattern"、"search file contents with regex"。当工具很多时,先用 ToolSearchTool 检索,再加载 schema。

这能显著减少"工具太多,模型不知道选哪个"的问题。

在工具数量还不大时,不必马上做完整的 ToolSearch。但可以先给每个工具补一条短而强的 capability hint,比如 glob_files 对应"find files by wildcard pattern",list_files 对应"inspect directory contents"。后面工具数再多起来时,再考虑轻量的工具检索机制。

4. 模型友好的 schema 和输出

GlobTool、GrepTool、FileReadTool 的共同特征是:输入 schema 很清楚,输出带结构字段,同时保留用户可读文本。还会显式告诉模型是否截断、有多少结果、当前返回的是哪一段。

这些字段(numFiles、truncated、startLine、totalLines 等)帮助模型形成稳定的使用习惯。模型能理解这个工具不是黑箱,返回的结果可分页、可缩小、可继续追问。

如果你正在设计类似的工具集,可以往这个方向走:加强 read_json 的结果边界控制,glob_files / list_files 的 limit 与 truncated 反馈,以及 read_file_range 更明确地突出起止行号。

这相当于让工具与 agent 之间产生交互,而不是让 agent 一味接收工具的结果。工具输出越具备语义,agent 越能基于这些语义决定下一步怎么走。

5. 系统上下文的提前影响

context.ts、systemInit.ts、systemPrompt.ts 和各类 tool prompt 会带 git 状态、当前日期、CLAUDE.md 等上下文。某些场景会在系统提示里明确声明工具使用约束,比如 Chrome/MCP 这类甚至会写:在用这些工具之前,必须先做某一步。

这说明他们非常重视在模型准备调用工具之前,就给它正确的行为暗示。

系统 prompt 的构建函数是非常关键的位置。如果要继续优化命中率,这里最值得打磨。特别是要把工具的使用策略写得更行为化,而不只是列名字。比如:

  • 用 list_files 理解目录结构
  • 用 glob_files 按模式找文件
  • 用 read_file_range 读大文件的局部
  • 用 read_json 理解 JSON 配置
  • 用 git_status 理解工作区状态
  • 只有在专用工具做不到时,才退回通用 shell 命令

system prompt 是每一轮都要传给模型的固定上下文,这部分如何拼接是关键。目前都是动态拼接:每个场景、每个工具的调用都会动态传入不同的提示词。

6. 缩小当前可见的工具集合

代码里有 getAllBaseTools()、getTools(),以及 deny rules、feature flags、simple mode、ToolSearch。他们会根据 feature flag、当前模式、deny rules、环境能力来缩小实际暴露给模型的工具集合。

工具越少,歧义越小;工具越聚焦,选择越稳定。

在初期不需要复杂的 feature flag,但可以做一件很有效的事:保持默认注册工具集尽量精简,不要太早加一堆功能重叠的工具。比如如果已经有 git_status,就不要再让模型在这个任务上偏向 shell 命令 + git status。


总结:claude-code 的工具调用优化不是单点技巧,而是 prompt 工程、schema 设计、工具检索、上下文管理和工具集合管理的叠加效果。对于正在构建 agent 系统的开发者来说,最值得优先做的是前两层:给工具更强的自我描述能力,以及在系统 prompt 里更明确地约束工具选择。

全部文章

作者

avatar for Steve
Steve

分类

  • Agent
1. 工具自己会"教模型怎么用它"2. 压低 Bash 的吸引力3. 工具检索机制4. 模型友好的 schema 和输出5. 系统上下文的提前影响6. 缩小当前可见的工具集合

更多文章

如何看待 Agent 记忆?
Agent

如何看待 Agent 记忆?

我更倾向按需记忆,而不是默认自动记忆。难点从来不是“要不要记”,而是记什么、什么时候记,以及怎么避免记忆变成噪音。

avatar for Steve
Steve
2026/03/30
Agent vs Harnessed Agent
Agent

Agent vs Harnessed Agent

Claude Code 适合高交互的探索;要把 Agent 拉进长程、可恢复、可审计的工程流程里,最后还是得靠代码去约束执行。

avatar for Steve
Steve
2026/03/30
Cursor Rules 入门指南:如何高效编写提示词
AI

Cursor Rules 入门指南:如何高效编写提示词

深入了解 Cursor 中的 Rules 分类与提示词结构,让 AI 成为你的顶级开发助手

avatar for Steve
Steve
2026/03/21
LogoSteve

Steve 的博客

© 2026 Steve