Claude Code 真正厉害的,不是会调用工具
很多人把 Claude Code 理解成“模型加一堆工具”。真正值得学的是它如何把工具发现、权限、hooks、sandbox 和结果回流组织成一条可验证的 agent loop。
我最开始理解 Claude Code 的时候,也很容易把它想成一件简单的事:Claude 后面接了一组工具。模型觉得该读文件,就调 Read;觉得该改代码,就调 Edit;觉得该跑测试,就调 Bash。
这个理解没有错,但太浅了。
如果 Claude Code 只是“会调用工具”,它不会比一个接了 function calling 的聊天框强太多。真正让它可以进入真实项目的,不是工具数量,而是它把这些工具放进了一条可以持续推进、不断验证、遇到风险能被拦住的循环里。
这篇笔记想讲的不是“Claude Code 有哪些工具”,而是另一个更重要的问题:
当模型开始真正改文件、跑命令、连外部系统时,什么样的工具系统才配得上真实开发环境?
我的答案是:Claude Code 的重点不是 tool calling,而是 agent runtime。
工具调用的误解
我们平时说“工具调用”,很容易想到一个 API 过程:
模型判断意图
-> 选择函数
-> 按 schema 填参数
-> 函数返回结果
-> 模型继续回答这套模型适合解释天气查询、数据库问答、简单的业务 API 调用。但它不足以解释 Claude Code。
因为开发任务不是一次函数调用能完成的。
你让 Claude Code 处理一个登录测试失败,它不知道失败原因在哪里;它要先跑测试,看错误;再读测试文件;再搜相关实现;再改代码;再跑测试;如果失败继续读日志;如果改动影响了别的模块,还要扩大验证范围。
这不是“调用一个工具拿答案”,而是一条循环:
观察当前状态
-> 选择下一步行动
-> 执行工具
-> 接收结果
-> 更新判断
-> 再选择下一步这才是 Claude Code 和普通聊天模型的分界线。普通聊天模型主要生成文本,Claude Code 会在这个循环里持续改变工作环境:读文件、改文件、跑命令、查文档、调用外部系统。
但一旦模型能改变环境,问题就不再是“给它多少工具”,而是“怎样让它正确地使用工具”。
一次失败测试背后的真实链路
假设你打开 Claude Code,说:
登录测试挂了,帮我修一下。看起来这只是一个很小的任务。实际发生的事情会复杂得多。
Claude Code 第一反应通常不是直接改代码,因为它还不知道测试怎么挂,也不知道登录逻辑在哪,更不知道项目用的是哪套测试框架。它需要先看见现场。最直接的方式是跑测试:
npm test -- login如果测试输出里出现:
Expected redirect to /dashboard
Received redirect to /login?next=/dashboard下一步判断就变了。Claude 可能会读测试文件,看断言上下文;再用搜索找 next=、redirect、dashboard;如果项目有 middleware 或 auth guard,它还会继续读这些文件。
也就是说,Bash 返回的不是一个“答案”,而是下一轮推理的依据。Read 不是单纯读文件,而是在补齐当前任务的事实。Grep 不是搜索工具本身,而是在缩小问题空间。Edit 不是最终动作,后面还必须有验证。
这条链路大概长这样:
Bash 跑测试
-> 得到失败现场
-> Read 读测试和实现
-> Grep 找调用点
-> Read 读相关代码
-> Edit 修改
-> Bash 再跑测试
-> 根据结果继续调整或收束这就是我说它不是工具箱的原因。工具箱只是把锤子、螺丝刀、扳手放在一起。Claude Code 更像一个工作台:工具、当前材料、操作顺序、检查点和安全边界都被组织在同一个流程里。
工具不是越多越好
一旦接入 MCP,这个问题会变得更明显。
本地开发里,Claude Code 常用的内置工具并不算太多:找文件、搜代码、读文件、改文件、跑命令、查网页。它们覆盖了程序员的基本闭环。
但 MCP 会把 Claude Code 接到更大的世界:GitHub、Jira、数据库、监控平台、浏览器、内部 API。每接一个系统,都会多出一批工具。GitHub 有 issue、PR、comment、file、review;Sentry 有 event、issue、release;数据库有 schema、query、migration;公司内部工具又会继续膨胀。
工具越多,问题越不是“模型能不能调”,而是“模型能不能找到当前真正该用的那个工具”。
如果把所有工具定义一股脑塞进上下文,至少有两个坏处。
第一,工具定义会吃掉大量上下文。工具名、描述、参数 schema、返回格式,每一个都要 token。工具一多,上下文先被工具清单塞满,真正的任务材料反而变少。
第二,工具太多会降低选择质量。很多工具名字相近、参数相近、边界相近。模型一次看到太多能力,不一定更聪明,反而更容易选错。
这就是 ToolSearch 这类机制出现的位置。
Grep 搜的是代码,WebSearch 搜的是网页,ToolSearch 搜的是能力。它解决的不是“事实在哪里”,而是“当前有没有一个工具能让我做这件事”。
这个区别很关键。Claude Code 不应该在任务开始时背着全部工具定义工作,而应该在需要某类能力时,按需发现工具,再把少量相关工具定义带进上下文。
所以 MCP 和 ToolSearch 的关系可以这样理解:
MCP 解决工具从哪里来
ToolSearch 解决工具太多后怎么找到这对我们自己设计 agent 也很有启发。很多人给 agent 加工具时,只关心“能不能接上 API”。但真正影响效果的,往往是工具能不能被发现、边界是否清楚、返回结果是否高信号。
一个叫 query 的万能工具,看似灵活,实际很难被模型稳定使用。一个叫 search_sentry_events 的工具,在用户说“查一下最近登录失败的线上报错”时就清楚得多。
工具设计不是后端 API 封装,而是给模型设计行动空间。
能执行之前,先要被约束
工具调用请求只是意图,不应该等于执行。
这是 Claude Code 和普通 function calling 最大的差异之一。因为 Claude Code 的工具有真实副作用。
读源码和删文件不是一回事。跑测试和执行部署脚本不是一回事。查数据库和改生产数据库不是一回事。发 Slack、创建 PR、关闭 issue、改配置,这些都不是“生成文本”级别的风险。
所以 Claude Code 需要多层边界。
第一层是权限。哪些工具可以自动执行,哪些要询问用户,哪些应该直接拒绝。Read 某个源码文件通常可以自动放行,npm test 也可以预先允许;但 rm -rf、生产数据库写操作、外部消息发送,就应该被拦住或要求确认。
第二层是 hooks。权限回答“能不能执行”,hooks 回答“执行前后必须发生什么”。比如读取 .env 前拦截,改文件后自动格式化,任务结束前跑测试,压缩上下文前归档 transcript。这些规则不应该只写在提示词里,而应该变成运行时机制。
第三层是 sandbox。权限和 hooks 仍然在 Claude Code 层面判断,sandbox 则限制命令执行时到底能访问哪些文件、网络和系统资源。
第四层是 checkpoint。文件改坏了,能不能回退。这里要特别区分:checkpoint 能回滚本地文件修改,但不能回滚外部副作用。如果一个工具已经写了生产数据库、调用了远程 API、发出了消息,本地 checkpoint 并不能让世界恢复原状。
这几层合在一起,才让 Claude Code 从“敢调用工具”变成“可以被放进真实项目里用”。
工具是否可见
-> 调用是否被允许
-> 执行前后是否触发 hook
-> 命令是否被 sandbox 限制
-> 文件修改是否可以 checkpoint 回退
-> 结果是否能被验证如果没有这些边界,工具越多,agent 越危险。
工具结果不是日志垃圾桶
工具调用还有一个常被低估的问题:结果怎么回到模型。
如果跑测试只输出三行错误,直接放进上下文没问题。但如果命令输出几万行日志,或者数据库工具返回上万行记录,全部塞回上下文就会污染后续判断。
Agent 的上下文不是垃圾桶。工具结果应该服务下一步决策。
一个工具返回:
{
"rows": [...]
}看起来很完整,实际上可能把判断压力全部扔给模型。另一个工具返回:
{
"summary": "过去 24 小时登录失败集中在 OAuth callback",
"top_errors": [...],
"suggested_next_queries": [...]
}反而更适合 agent,因为它提供的是下一步行动所需的高信号信息。
这也是为什么“把现有 API 包一层给模型用”通常不够。人类 API 的设计目标是给工程师调用,agent 工具的设计目标是帮助模型判断下一步。两者不是一回事。
好的 agent 工具应该有几个特征:
- 名字明确,让模型知道什么时候该用。
- 参数少而清楚,不把业务判断藏在一个万能字符串里。
- 返回结果有摘要、有证据、有下一步提示。
- 对大结果做过滤、分页或聚合。
- 明确说明副作用和权限边界。
Claude Code 给我们的启发不是“多接工具”,而是“工具也要为推理链路设计”。
真正值得学的是收束能力
如果只看工具清单,Claude Code 并不神秘。
读文件、搜代码、改文件、跑命令、查网页、接 MCP,这些能力很多 agent 都有。真正差异在于:Claude Code 能不能让一次任务从混乱状态逐步收束到可验证结果。
这件事比工具数量更重要。
一个不会收束的 agent,会一直搜、一直读、一直改,最后把上下文塞满,把项目弄乱。一个能收束的 agent,会不断问:
- 当前最缺的事实是什么?
- 哪个工具能以最低成本拿到这个事实?
- 这一步有没有副作用?
- 结果是否足够支持下一步?
- 什么时候该停止,停止前要验证什么?
这才是 Claude Code 的工具系统最值得借鉴的地方。
它不只是回答“模型怎么调用函数”,而是在回答:
当工具越来越多、任务越来越长、副作用越来越真实的时候,怎样让模型仍然只看见该看的东西,只做被允许做的事,并且每一步都能被验证?
这也是我觉得很多 AI 编程工具会分化的地方。
早期大家比的是模型够不够强、能不能写出代码。接下来会越来越多地比 runtime:上下文怎么组织,工具怎么发现,权限怎么约束,结果怎么回流,任务怎么验证,失败怎么回退。
模型能力当然重要,但在真实工程里,模型不是单独工作的。它必须被放进一套能收束的系统里。
Claude Code 真正厉害的,不是会调用工具。
它厉害的是:它把工具调用变成了一个可以持续行动、可以被约束、可以被验证的工作流。
参考资料
- Claude Code Tools reference
- How Claude Code works
- Agent SDK: How the agent loop works
- Scale to many tools with tool search
- Connect Claude Code to tools via MCP
- Claude Code Permission modes
- Agent SDK permissions
- Claude Code Hooks guide
- Claude Code sandboxing
- Introducing advanced tool use on the Claude Developer Platform
- Writing effective tools for AI agents