ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Claude-Code源码解读:Tools篇——从配置骨架到工具调用链的持续拆解

Claude-Code源码解读:Tools篇——从配置骨架到工具调用链的持续拆解 1. 从一次工具调用失败说起Claude-Code Tools 模块到底在做什么如果你正在读 Claude-Code 的源码大概率会卡在 Tools 这一层明明settings.json里写了工具会话里却调不出来或者工具能调但参数校验直接报错日志里只有一行tool_use_error。我最初接触这套代码时最困惑的不是模型怎么选工具而是工具从哪来、谁注册的、参数在哪校验、执行结果怎么回灌给模型。这几个问题串起来就是 Tools 模块的完整调用链。Claude-Code 的 Tools 模块可以拆成四层工具声明层每个工具自己的 schema 和 handler、注册层把工具挂到会话可用的工具表里、调度层模型返回tool_use后找到对应 handler 并校验参数、执行层真正跑逻辑并把tool_result塞回对话。默认可见的工具包括 Read、Edit、Write、Bash、Glob、Grep、WebSearch、WebFetch、TodoWrite、Agent、Skill、EnterPlanMode、ExitPlanMode、AskUserQuestion 等这些在普通会话里基本都能看到。但有一类工具是条件启用的需要功能开关或环境变量满足后才出现在工具列表里还有一类是 MCP 工具名称格式固定为mcp__{服务器名}__{工具名}取决于你在~/.claude.json或项目配置里连了哪些 MCP 服务器。另外还有个简单模式CLAUDE_CODE_SIMPLE只保留 Bash、Read、Edit协调模式下可能额外带上 Agent、TaskStop、SendMessage。这篇面向想深入理解工具注册、参数校验与执行流程的开发者交付可复制的settings.json与config.toml骨架并给出逐层验证调用链的调试动作。适合已经能跑起 Claude-Code、想改工具行为或排查工具不生效的人。下面按「配置骨架 → 注册验证 → 调用链拆解 → 排障」的顺序走每一步都能在本地复现。2. TaoToken 前置把模型接入和工具链调试分开调试 Tools 模块时最怕把「模型没返回 tool_use」和「工具注册失败」混在一起排查。我的做法是先把模型接入层固定下来让它稳定可用再单独盯工具链。TaoToken 在这里的角色就是提供兼容 Anthropic 接口的模型访问入口你不需要改 Claude-Code 的工具代码只要把 base_url 和 key 配对就能把注意力全放在 Tools 上。接入信息很直接官网是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 根地址是 https://taotoken.net/api 注意 API 地址不带 UTM 参数。控制台在 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite API Keys 管理在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。如果你只是想先验证模型能不能正常返回工具调用用模型对话页 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 手动发一条带工具描述的消息最快。长期跑编码或 Agent 场景再考虑 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 。接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite ClaudeCodeAnthropic 相关说明在 https://taotoken.net/claudecode-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecode-anthropicutm_campaignrewrite 。注意工具链调试阶段建议先用一个最小工具集比如只留 Read 和 Bash确认模型能稳定返回tool_use之后再逐步加工具。否则工具一多报错来源就难定位。3. 可复制的配置骨架settings.json 与 config.tomlClaude-Code 的配置分两层一层是会话级/项目级的settings.json控制工具可见性和权限另一层是config.toml控制模型接入和运行时行为。下面这份骨架可以直接抄改掉 key 和路径就能跑。3.1 settings.json 骨架{ permissions: { allow: [ Read, Glob, Grep, Bash(git status), Bash(git diff:*) ], deny: [ Bash(rm:*), Bash(curl:*) ] }, tools: { enabled: [ Read, Edit, Write, Bash, Glob, Grep, TodoWrite ], disabled: [ WebSearch, WebFetch ] }, env: { CLAUDE_CODE_SIMPLE: 0 } }这里有几个点值得说清楚。permissions.allow和permissions.deny是权限层决定工具能不能被执行tools.enabled和tools.disabled是可见性层决定工具会不会出现在模型看到的工具列表里。两层是独立的一个工具可以「可见但被 deny」模型会尝试调用然后被拦也可以「不可见」模型根本不知道它存在。调试时优先看可见性再看权限顺序反了会白折腾。CLAUDE_CODE_SIMPLE设为0是关闭简单模式。如果你把它设成1工具列表会被砍到只剩 Bash、Read、Edit协调模式下可能多出 Agent、TaskStop、SendMessage。这个开关在排查「为什么我的工具不见了」时是第一个要检查的。3.2 config.toml 骨架[model] provider anthropic-compatible base_url https://taotoken.net/api api_key sk-你的key model claude-sonnet-4-20250514 [runtime] max_tokens 8192 temperature 0.2 tool_choice auto [tools] mcp_config ~/.claude.json project_mcp_config .claude/mcp.jsonbase_url填https://taotoken.net/api不要带 UTM。tool_choice设成auto让模型自己决定是否调工具调试阶段可以临时设成any强制模型必须调一个工具用来验证工具注册是否生效。mcp_config指向 MCP 服务器配置MCP 工具的名称会按mcp__{服务器名}__{工具名}生成服务器名来自这份配置里的 key。3.3 MCP 配置片段{ mcpServers: { filesystem: { command: npx, args: [-y, modelcontextprotocol/server-filesystem, /tmp/workspace] } } }连上之后工具列表里会出现mcp__filesystem__read_file这类名字。如果没出现先确认服务器进程能不能起来再看 Claude-Code 有没有把这份配置读进去。4. 逐层验证工具调用链从注册到执行配置写完不代表工具就能用。下面这套验证动作是我反复用的按顺序做能定位到具体是哪一层断了。4.1 验证工具注册工具列表里有没有它最直接的办法是让模型「列出你当前可用的工具」。发一条消息请列出你当前可用的所有工具名称只输出名称不要解释。如果返回的列表里没有你配置的工具问题在注册层。检查顺序settings.json的tools.enabled有没有写对工具名大小写敏感CLAUDE_CODE_SIMPLE是不是被设成了1条件启用工具的功能开关或环境变量有没有满足。MCP 工具还要额外确认服务器配置路径对不对。4.2 验证参数校验故意传错参数工具注册成功但调用报错多半是参数校验层。以 Read 为例故意传一个不存在的字段{ tool: Read, input: { file_path: /tmp/workspace/test.txt, wrong_field: x } }如果返回的是tool_use_error且提示字段不合法说明校验层在工作。如果直接抛异常或静默失败说明这个工具的 schema 定义有问题需要去看源码里该工具的 input schema。Claude-Code 的工具 schema 一般用 JSON Schema 描述required字段缺失、类型不匹配都会在这一层被拦。4.3 验证执行层看 tool_result 回灌参数校验通过后handler 会真正执行。执行结果以tool_result的形式回灌到对话里。你可以用一个必然成功的工具验证这条链路# 在会话里让模型执行 请用 Bash 工具执行 echo tool-chain-ok然后告诉我输出。如果模型返回的tool_result里包含tool-chain-ok说明执行层和回灌都正常。如果模型说「我调用了但没看到结果」去看日志里tool_result有没有被正确拼进下一轮请求。这一步出问题通常是消息拼接逻辑或tool_use_id对不上。4.4 验证 MCP 工具的动态性MCP 工具是动态的服务器连上才有断开就没了。验证方法先在mcp.json里加一个服务器重启会话让模型列工具确认mcp__{服务器名}__{工具名}出现然后把服务器配置删掉重启确认工具消失。这个来回能帮你确认 MCP 工具的注册是运行时动态生成的而不是写死在代码里的。5. 本篇常见错排查5.1 工具不出现先查CLAUDE_CODE_SIMPLE再查tools.enabled拼写最后查条件启用工具的环境变量。MCP 工具额外查服务器进程和配置路径。这三步能覆盖九成「工具不见了」的情况。5.2 工具出现但调用被拒这是权限层的问题看permissions.deny有没有命中。注意 deny 的匹配是模式匹配Bash(rm:*)会拦掉所有以rm开头的命令。调试时可以先临时清空 deny确认是权限问题后再逐条加回来。5.3 参数校验报错但看不出原因把该工具的 schema 打印出来对照。Claude-Code 的工具 schema 通常在工具定义文件里找到input_schema字段看required和properties。常见坑是字段名用了下划线还是驼峰、类型是 string 还是 array。5.4 tool_result 没回灌检查tool_use_id是否一致。模型返回的tool_use带一个 id你回灌的tool_result必须带同一个 id否则消息拼接会断。这个在自定义工具或改调度层时最容易踩。5.5 MCP 工具名对不上名称格式是mcp__{服务器名}__{工具名}服务器名来自配置里的 key不是 command。如果你配置里写的是filesystem工具名就是mcp__filesystem__xxx。改 key 之后工具名会变记得同步更新任何硬编码引用。6. 继续跟进源码更新与接入入口Tools 模块的调用链拆到这里注册、校验、执行、回灌四层都能单独验证了。源码更新时优先看工具 schema 有没有变、注册逻辑有没有加新的条件开关、MCP 工具名的生成规则有没有调整。这三处是变动最频繁的地方。如果你在排障或接入阶段卡住先去 API Keys 页 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 确认 key 可用再对照接入文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 检查 base_url 和参数。想先手动验证模型能不能正常返回工具调用用模型对话页 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 发一条带工具描述的消息最快。长期跑编码或 Agent 场景Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 更合适。ClaudeCodeAnthropic 的专项说明在 https://taotoken.net/claudecode-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaudecode-anthropicutm_campaignrewrite 控制台入口在 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite 。
返回列表