所属层级:第二层「Claude Code 如何运行」
建议前读:03. 启动与主循环
建议后读:08. 权限与安全控制 或 15. Agent 设计理念研究
Anthropic 在 Claude Code 里,为什么没有把工具调用做成“模型调用几个函数”这么简单?
Claude Code 的工具系统本质上不是函数注册表,而是一个受权限、上下文、持久化、UI 和恢复语义共同约束的执行协议。
这一章解释 Claude Code 的 tool 是什么、为什么它比 slash command 更底层,以及 Anthropic 为什么把工具调用设计成一条完整工作流,而不是普通的 function calling。
- 工具在 Claude Code 里承担的是“执行动作”的正式接口,不是辅助功能。
- 一次 tool call 同时绑定权限判定、上下文注入、进度反馈、结果结构化和 transcript 语义。
- Anthropic 设计的不是“模型随意调用工具”,而是“模型在制度内发起受控执行”。
- 这套设计比常见 agent 框架更重工程可恢复性,而不是只重首轮可用性。
如果只看产品表面,你会觉得 Claude Code 只是“让模型会 Bash、会读写文件、会搜网页”。但从工具层设计看,Anthropic 真正想做的是把模型的外部行动统一收编成一条工程化执行协议。
这条协议至少要解决五个问题:
- 模型可以做什么,边界在哪里。
- 每次执行前如何判断是否允许。
- 执行时如何拿到当前会话的上下文和系统状态。
- 执行结果如何被模型、UI 和 transcript 同时消费。
- 会话中断、恢复、切到后台后,这些工具结果如何仍然有语义。
所以这里的重点不是“接更多工具”,而是“让工具调用成为可治理的工作流”。
和很多“给模型注册几个 Python function”的 agent 框架相比,Claude Code 的工具系统明显更重这几件事:
- 它默认把工具调用视为高风险动作,而不是天然可信动作。
- 工具不是裸输入输出,还要经过 permission context、UI 进度、结果消息和日志持久化。
- 同一套工具要同时服务 REPL、SDK、后台任务、子代理和恢复链路。
- 工具的返回结果不只是给程序看,也要进入 transcript,成为后续推理材料。
这就是为什么 Claude Code 的工具层看起来更像“执行总线”,而不是“辅助库”。
- 工具类型与上下文:src/Tool.ts
- 工具注册表:src/tools.ts
- 子代理工具:src/tools/AgentTool/AgentTool.tsx
- 权限上下文类型:src/types/permissions.ts
flowchart TD
A["getAllBaseTools"] --> B["feature gate / 平台判断 / 用户类型"]
B --> C["当前会话可用 tools"]
C --> D["ToolUseContext"]
D --> E["ToolPermissionContext"]
D --> F["AppState / MCP / commands / file cache"]
E --> G["allow / ask / deny"]
F --> H["具体 tool call"]
G --> H
H --> I["结果 schema / progress / UI / transcript"]
一条简单判断规则:
- 用户输入
/review、/plugin、/tasks时,先进入命令层。 - 模型要执行
bash、读写文件、搜索、启动子代理、调用 MCP 时,进入工具层。
因此工具层比命令层更接近能力边界和安全边界。
src/tools.ts 的 getAllBaseTools() 是整个工具面的总入口。它集中列出了当前会话可能出现的工具,并在注册时就考虑:
- feature flag
- 平台能力
- 用户类型
- 是否启用 todo v2
- 是否启用内嵌搜索工具
这说明 Anthropic 把“哪些动作当前可执行”当成运行时决策,而不是静态编译结果。
从注册表可确认的核心工具包括:
AgentToolBashToolFileReadToolFileEditToolFileWriteToolNotebookEditToolGlobToolGrepToolWebFetchToolWebSearchToolTodoWriteToolAskUserQuestionToolSkillToolEnterPlanModeToolExitPlanModeV2ToolMCPToolListMcpResourcesToolReadMcpResourceToolLSPToolTaskCreateToolTaskGetToolTaskUpdateToolTaskListTool
这些工具加起来,构成了 Claude Code 对外行动的主要能力面。
src/Tool.ts 的 ToolUseContext 很能说明 Anthropic 的设计方向。每个 tool 调用时都能拿到:
- 命令列表
- 工具列表
- 主模型设置
- 思考配置
- MCP 客户端和资源
- AppState 读写函数
- 文件读取缓存
- 通知函数
- 消息追加函数
- OS 通知
- 系统 prompt 相关信息
- 当前消息列表
这说明工具不是孤立执行器,而是运行在完整会话容器里的执行节点。
同一个 src/Tool.ts 中还定义了 ToolPermissionContext。它包含:
- 当前
mode alwaysAllowRulesalwaysDenyRulesalwaysAskRules- 额外工作目录
- 是否可用 bypassPermissions
- plan mode 之前的权限模式快照
这意味着 Claude Code 不是“工具先执行,安全再兜底”,而是把权限环境内嵌进工具抽象本身。
从 Tool.ts 和各个工具实现可以确认,工具调用不仅有输入 schema,也有:
- 输出 schema
- progress 事件
- UI 表现方式
- transcript 中可复用的结果消息
这件事很关键。Anthropic 不是只让模型调用成功一次,而是要求工具结果能被后续模型推理、UI 渲染、会话恢复和任务系统同时理解。
src/tools/AgentTool/AgentTool.tsx 展示了工具系统的复杂度上限。它的输入不仅包括:
descriptionpromptsubagent_typemodelrun_in_background
还包括:
nameteam_namemodeisolationcwd
这表明工具层不只是执行单一动作,还可以派生新的工作单元、隔离环境和审批语义。
- 先看 src/tools.ts 了解总工具面。
- 再看 src/Tool.ts 理解统一抽象。
- 最后挑一两个代表性工具深挖,例如
BashTool、AgentTool、MCPTool。
- Claude Code 的 tool call 更像受控执行协议,而不是普通函数调用。
- 权限、上下文、UI、恢复和 transcript 都被设计进工具抽象。
- Anthropic 关心的不是“工具越多越好”,而是“工具调用越可治理越好”。
对 Claude Code 来说,tool system 是“动作能力总线”。命令系统更像用户导航层,而工具系统才是执行层、权限层、状态层和可扩展层的交汇点。