Claude Code 源码精读 | 03 Tool工具如何让模型长出双手?
这是「Claude Code 源码精读」系列的第 3 篇。上一篇我们拆解了 Agent 主循环。这一篇我们讲,循环里反复出现的”工具”,到底是什么?
读完这篇,你会搞清楚以下4件事:
-
• 什么是 Agent 工具?ClaudeCode 内置的40+工具是哪些? -
• CC 对于 Tool 的底层设计哲学是什么? -
• 为什么说提示词才是工具设计的关键环节? -
• 保证安全的权限设计和 /permissions 的 CC 使用技巧
序言
什么是 Agent 工具?
上一篇讲主循环的时候,有提到,工具是大模型成为Agent的关键一步。是它让大模型实现了,从回答对话到完成任务的跨越。
就像人的大脑和双手的关系,对 Agent来说,大模型是大脑,工具就是手、腿、眼睛。
大模型原生是不具备搜索能力的,所以它需要有搜索API,作为获取实时信息的眼睛。需要有bash,去执行命令,需要有文件读取工具等等。
不止如此,在 Claude Code 里,很多我们熟知的概念Skill、MCP、Plan 模式、子 Agent,这些封装的功能模块和概念,它在代码层面,对于CC来说都是 Tool 工具。
-
模型进入计划模式,本质是调用了 EnterPlanModeTool
-
执行一个斜杠命令,本质是调用了 SkillTool
-
使用一个 MCP,本质是调用了 MCPTool
换句话说,”工具”是模型能做的一切事情的统一抽象。
从模型的视角看,它只有一件事可以做:调用工具。
不管是使用Skill、MCP、切换Plan 模式、调度子Agent,在模型眼里都是同一种操作。选一个工具,填参数,发出去。
所以,对Tool 工具设计的拆解,是理解CC agent设计思路的核心部分。
Claudecode 的40+工具
CC 的源码中,包含的工具共 40个工具,分 7 大类。
|
|
|
|
|---|---|---|
| 文件操作 |
|
|
| 系统执行 |
|
|
| 网络 |
|
|
| 任务与调度 |
|
|
| Agent 协作 |
|
|
| 交互与流程控制 |
|
|
| MCP 集成 |
|
|
| 内部工具 |
|
|
篇幅所限,这些工具的深入探讨,我们将放在后面的篇章详细展开。
今天,这一期,我们先以最简单的 FileWriteTool 为例,详细拆解一下 CC 的 Tool工具设计哲学。
深入源码:Tool.ts
在拆解细节之前,先建立一个宏观视角。
下面这张图,是 CC 工具执行的完整路径:

整个过程分五步:AI大模型决定使用工具(输出 tool_use ) → 进入工具编排层 → 权限决策 → 真正调用工具 → 工具结果传回AI大模型(返回tool_result )
这里面会涉及到几个问题,工具是如何构建的?工具是如何被调用的?多工具场景如何处理?如果通过权限决策保证安全性?我们逐个展开。
AI 决策和代码执行的解耦设计
以FileWriteTool这个工具为例,它是Claude Code 里负责新建文件的那个工具。打开CC的源码,你可以看到,有这一段给AI写的提示词:
export function getWriteToolDescription(): string { return `Writes a file to the local filesystem.Usage:- This tool will overwrite the existing file if there is one at the provided path.${getPreReadInstruction()}- Prefer the Edit tool for modifying existing files — it only sends the diff. Only use this tool to create new files or for complete rewrites.- NEVER create documentation files (*.md) or README files unless explicitly requested by the User.- Only use emojis if the user explicitly requests it. Avoid writing emojis to files unless asked.`}// 译:将文件写入本地文件系统。// 使用规则:// - 如果目标是已有文件,必须先用 Read 工具读一遍,否则本工具会报错// - 优先用 Edit 工具修改已有文件,只有新建文件或完全重写时才用本工具// - 不准创建 .md 文档或 README 文件,除非用户明确要求// - 除非用户要求,不准在文件里加 emoji
AI 读完它,知道这个工具能做什么、什么时候该用、用的时候要注意什么。
源码中,每个工具都通过一个工厂函数 buildTool() 来组装,它规定了工具必须具备两个核心方法:
-
• prompt():生成发给 AI 的描述文字,用于让模型去理解。 -
• call():工具真正执行时运行的代码,完成实际任务。
这两者完全分离。 模型靠读 prompt() 的描述,来决定用不用这个工具,一旦决定调用,call() 里的逻辑才开始执行(路径检查、权限验证、内容写入),这些过程 AI 完全不参与,只是会把最终的结果传给AI。
所以理论上,在代码层,一个 CC 可用的 Tool,就是一段执行代码(call()),加上一段关于这个工具的描述(prompt())。你在创建skill、Command 时,底层就是这套逻辑。
这是 CC 工具系统的一个很底层的设计哲学。AI 的决策和代码的执行,是两个完全解耦的模块。这个在模型能力较弱的早期,是一定会产生很多幻觉问题的。这也就是为什么,直到去年,模型能力发展到一个可用水平了,我们才真正迎来了Agent时代。
提示词是工具被调用的关键
在 AI 调用工具的过程中,工具的选择,是完全由模型自己决定的,CC 不干预。
真正影响 AI 是否会用这个工具、如何用这个工具的,是那几百字的描述。
所以工具的描述写得好,比代码执行的好写得好更重要。
代码实现得再精妙,AI 不能按照你预期的方式理解,也没有用。也正因为此,CC团队给他们的这40个工具,写了非常详细的描述,这也是CC体验好的一大块基石。
如果你要写一个 Skill或者其他的tool,CC写提示词的方法是非常值得借鉴的,后面我们找机会单独出一篇如何借鉴 CC 来优化Agent提示词的方法。
CC 高效的工具编排
AI 在一轮输出里同时决定调用多个工具,是很常见的情况。这时系统不是随便按顺序执行的,而是会做一次工具的编排。
CC会根据每个工具上的一个字段:isConcurrencySafe(工具注册时维护),来判断到底是并行还是串行。
-
• true:这个工具可以和别的工具同时跑(一般是只读操作,比如搜索、读文件)。系统把它们打包,最多 10 个并发执行。 -
• false:有写入或副作用,必须一个一个排队来。
举个例子。你让CC “帮我看看这几个文件,然后改一改”。AI 会在一轮里同时决定调用 Grep 搜索 + Read 工具读 3 个文件,这被调用的 4 个工具的isConcurrencySafe=true,所以系统把它们一起并行跑。但接下来 AI 决定调用 3 次 Edit,Edit 有写入操作,isConcurrencySafe=false,系统把这 3 个排队,一个改完再改下一个,否则万一两个 Edit 同时写同一个文件,就冲突了。
这样做的好处,是在最大程度保证安全的同时,提升了很多效率。
工具权限和 /permission 使用技巧
确定好工具编排后,会进入权限环节。
用过 CC 的人都遇到过这个场景:你让它改一个文件,它却停下来问你”允许执行吗?”。
这背后就是工具的权限系统在工作。
CC 有 4 种权限模式:
-
• Default(默认):判断涉敏的均询问用户 -

-
• Plan Mode(计划模式):只允许读,不允许任何写入或执行——AI 只能思考,不能动手 -

-
• Accept Edits(自动接受编辑):文件编辑自动放行,但其他工具执行仍询问 -

-
• Bypass Permissions(跳过权限):跳过所有检查,直接执行
你在 CC 通过 shift+tab 切换的模式,就是在调整这道拦截的松紧程度。
在 Default 模式下,每次拦截的决策走一条优先级链:永久禁止规则 → 永久允许规则 → Hook 拦截 → 自动分类 → 弹窗询问用户。只要某一级做出了决定,后面就不再走了。

很多深度 CC 用户都会用/permissions。你可以通过这个命令,配置哪些工具无需请求批准,哪些工具永远不要使用。
这个规则设置,就是在给这条优先级链的前两级,预先写好答案,来更细致的管理权限和安全性。
回到Agent循环
工具执行完,结果会被打包成标准格式(tool_result block),返回给 AI。AI 再决定下一轮的动作,是继续调工具,还是直接回答用户。
这一轮一轮的动作,就形成了我们上一期讲的Agent主循环。
并最终让 AI 完成了从回答对话到完成任务的跨越,来到我们身边,真正成为了我们离不开的助手。
下一期,我们来详细拆解 CC 的内置工具,MCP、Skill、Task 这些 Tool 是怎么设计的?
下期见。
「Claude Code 源码精读」系列持续更新,关注我,带你理解最顶尖的 Agent 设计。
夜雨聆风