ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

深入 Claude Code 源码(三):工具系统——53 个工具背后的统一框架与 TaoToken 配置骨架

深入 Claude Code 源码(三):工具系统——53 个工具背后的统一框架与 TaoToken 配置骨架 1. 从 Tool.ts 到 buildTool53 个工具为什么能共用一套骨架Claude Code 的工具系统源码拆解到第三篇最值得反复看的是src/Tool.ts和buildTool()这两个文件。一个 AI Agent 能做什么本质上由它拥有哪些工具决定。Claude Code 内置了 53 个工具从读写文件、执行命令到搜索代码、管理子代理几乎覆盖了软件开发者日常工作的所有操作。但把这 53 个工具统一管理起来并不是简单堆放在一起——它们需要共同的接口规范、权限控制机制、进度反馈协议还要能以完全相同的方式嵌入 system prompt让模型一视同仁地调用任何一个。这篇聚焦工具系统的统一抽象层从Tool.ts的类型契约切入梳理buildTool()工厂函数如何保证所有工具经过同样的质检流程再交付一份可复制的settings.json与config.toml配置骨架并给出接入 TaoToken 统一 Key/API 通道后的验证动作帮你在本地复现整条工具调用链路。适合已经读过前两篇、想动手把配置跑通的读者。2. TaoToken 前置统一 Key 与 API 通道准备在复现工具调用链路之前需要先准备好模型侧的访问通道。Claude Code 的工具调用最终要落到 Anthropic 兼容的 API 上TaoToken 提供统一的 Key 和 API 入口省去在多个供应商之间切换配置的麻烦。你需要先拿到一个可用的 API Key。登录控制台后进入 API Keys 页面创建建议按项目维度建 Key方便后续做权限隔离和用量追踪。创建完成后把 Key 存到环境变量里不要硬编码进配置文件export TAOTOKEN_API_KEYsk-你的实际KeyAPI 基础地址使用https://taotoken.net/api这个地址不带任何查询参数直接作为 base_url 填入配置即可。如果你还没创建 Key可以先到控制台的 API Keys 页面操作想先验证模型对话是否正常可以走模型对话入口快速试一条请求。注意Key 只创建一次就够后续所有工具调用共用同一个通道。不要在每个工具里单独配 Key那样会破坏统一框架的意义。3. 可复制配置settings.json 与 config.toml 骨架Claude Code 的配置分两层settings.json管工具权限和会话行为config.toml管模型接入和 API 通道。下面这份骨架可以直接复制把 Key 换成你自己的即可。3.1 settings.json工具权限与执行框架{ permissions: { mode: acceptEdits, allow: [ Read, Glob, Grep, Bash(git status), Bash(git diff*), Bash(npm run lint), Bash(npm run test*) ], deny: [ Bash(rm -rf /*), Bash(curl * | bash), Bash(wget * | sh), Bash(chmod 777 *) ] }, tools: { maxResultSizeChars: 20000, progressThresholdMs: 2000 }, env: { TAOTOKEN_BASE_URL: https://taotoken.net/api } }这份配置对应了工具系统的三层权限防护allow列表是工具级canUseTool()的白名单deny列表拦截高危命令mode控制全局 PermissionMode。acceptEdits模式下文件编辑自动放行但 Bash 命令仍需按白名单确认。3.2 config.toml模型接入与 API 通道[model] provider anthropic base_url https://taotoken.net/api api_key_env TAOTOKEN_API_KEY model claude-sonnet-4-20250514 max_tokens 8192 [tools] enabled true mcp_servers [] [query] permission_mode acceptEdits track_denials trueapi_key_env指向环境变量名而不是 Key 本身这样配置文件可以安全地提交到版本库。track_denials true对应 QueryEngine 包装层的拒绝追踪所有被拦截的调用会汇总到permission_denials字段方便审计。3.3 工具注册的代码侧对应配置里的每一项都能在源码里找到对应。buildTool()工厂函数接收的ToolDef结构大致如下buildTool({ name: Bash, description: getSimplePrompt(), inputSchema: lazySchema(z.object({ command: z.string(), timeout: z.number().optional(), description: z.string().optional(), })), execute: async function* (input, context, setToolJSX) { yield { type: progress, message: 正在执行命令... }; const result await exec(input.command); return buildToolResult(result); }, canUseTool: bashToolHasPermission, maxResultSizeChars: 20000, });lazySchema()做了懒加载只有真正需要校验输入时才初始化 Zod schema减少启动内存开销。execute()返回AsyncGenerator执行过程中可以多次yield进度消息最终return一个ToolResultBlockParam。这个双层输出设计就是终端 UI 能实时显示「正在执行」「已读取 3 个文件」的原因。4. 验证请求复现工具调用链路配置写好后需要验证整条链路是否打通。分三步走。4.1 验证 API 通道先用一条最小请求确认 Key 和 base_url 可用curl -s https://taotoken.net/api/v1/messages \ -H x-api-key: $TAOTOKEN_API_KEY \ -H anthropic-version: 2023-06-01 \ -H content-type: application/json \ -d { model: claude-sonnet-4-20250514, max_tokens: 128, messages: [{role: user, content: 回复 OK 两个字母}] }返回体里能看到content数组和usage字段就说明通道正常。如果返回 401检查 Key 是否过期返回 404检查 base_url 是否漏了/v1。4.2 验证工具注册启动 Claude Code 后在会话里输入一条会触发工具调用的指令比如「列出当前目录下的 TypeScript 文件」。观察终端输出如果出现Glob或Bash(ls)的进度提示说明工具注册成功如果直接返回文本而没有工具调用检查settings.json的allow列表是否包含对应工具如果弹出确认框说明mode不是acceptEdits或者该命令不在白名单里4.3 验证权限拦截故意触发一条deny列表里的命令比如让 Claude 执行rm -rf /tmp/test。预期行为是被拦截并在permission_denials里留下记录。如果命令被执行了说明deny规则没生效检查通配符写法——Bash(rm -rf /*)里的*是通配符匹配任意后缀。提示验证阶段建议把mode设为default每条命令都手动确认确认无误后再切到acceptEdits。5. 本篇常见错排查配置跑不通时按下面几个方向排查。Key 无效或权限不足最常见的是环境变量没导出或者导出后没重启终端。echo $TAOTOKEN_API_KEY确认变量存在。如果 Key 是在控制台新建的注意复制时不要带空格。base_url 写错https://taotoken.net/api是基础地址实际请求路径是/v1/messages。有些客户端会自动拼接/v1有些不会需要看具体工具的文档。Claude Code 的config.toml里填基础地址即可它会自己拼路径。工具没被调用先确认tools.enabled true再确认allow列表里有对应工具。如果工具名写错比如写成bash而不是Bash匹配会失败。toolMatchesName()是大小写敏感的。结果被截断如果工具返回的内容超过maxResultSizeChars完整内容会写入磁盘临时文件发给模型的消息里只保留一条「结果已截断完整内容在 {path}」的提示。这是预期行为不是 bug。模型可以选择用Read工具去读那个文件。MCP 工具不生效mcp_servers为空时不会加载任何 MCP 工具。如果需要接入外部服务在mcp_servers里配置服务地址Claude Code 会枚举服务暴露的工具列表为每个工具动态创建MCPTool实例。从模型视角看MCP 工具和本地工具没有区别。进度提示不显示progressThresholdMs默认 2000ms短命令不会显示进度。如果想让所有命令都显示把这个值调小但会牺牲终端整洁度。6. 下一步把配置固化下来工具系统的统一框架理解清楚后配置骨架就可以固化成团队模板。建议把settings.json和config.toml放进项目根目录的.claude/文件夹随代码一起版本管理。Key 通过环境变量注入不写进文件。如果你需要长期跑编码任务或 Agent 工作流可以了解 Coding Plan它针对高频工具调用场景做了通道优化。接入文档里有更完整的参数说明和错误码对照表遇到本文没覆盖的报错可以去那里查。下一篇进入上下文管理看 context window 快满时 Claude Code 怎么应对。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进