尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Claude Code 工具延迟加载机制拆解:defer_loading 与 ToolSearchTool 配置骨架

发布时间:2026/9/29 21:06:19

资讯中心
01
ARTICLE

Claude Code 工具延迟加载机制拆解:defer_loading 与 ToolSearchTool 配置骨架

Claude Code 工具延迟加载机制拆解:defer_loading 与 ToolSearchTool 配置骨架
1. 当 MCP 工具堆到 60 个我的 Claude Code 开始变慢如果你正在用 Claude Code 接 MCP并且配置了 Slack、GitHub、Jira、Notion、Linear 这类服务器大概率会遇到一个很具体的现象明明只是让它改一行代码它却先愣几秒然后回复变慢、上下文占用飙升。我试过把 MCP 服务器一个个关掉对比发现工具数量从 60 个降到 10 个之后首 token 延迟肉眼可见地下降。原因不复杂。每次调用 Claude API工具列表是作为tools参数整体传进去的每个工具都带着名称、描述和完整的input_schema。内置工具Bash、Read、Edit 等每个 schema 大约 70–150 tokenMCP 工具的 schema 通常更臃肿因为外部服务器往往把参数描述写得很长。五个 MCP 服务器、每个 10–15 个工具合计 50–75 个工具光 schema 就能吃掉一大块 200K 上下文窗口。更关键的是一次对话里真正被用到的工具可能只有一两个。你让 Claude 发一条 Slack 消息GitHub、Jira、Notion、Linear 的全部工具定义都白白占着位置。这就是 Claude Code 引入defer_loading工具延迟加载和ToolSearchTool的背景让模型先知道有哪些工具但不一次性把参数细节全塞进去等真正要用时再按需加载。这篇面向的是已经配了多个 MCP 服务器、感觉响应变慢的开发者。我会先讲清楚defer_loading与ToolSearchTool的协作流程再给出一份settings.json里可复制的配置骨架最后演示一次工具检索与按需加载的验证动作让你能自己复现这套机制。需要先说明一个容易混淆的点schema 是给 API 用的不只是给模型看的。Claude API 的tools参数会改变模型输出格式——传入工具后模型返回的是结构化的tool_use块包含工具名和 JSON 格式参数API 侧还会根据 schema 做输入校验类型错误、缺必填字段、enum 越界都会在 API 层被拦截。所以延迟加载不是少给模型看东西这么简单它是在 API 层控制 schema 的可见性。2. defer_loading 与 ToolSearchTool 的协作流程拆解要理解延迟加载得先看工具是怎么传给大模型的。每次请求工具数组会经过转换取出名称、描述、input_schema组装成 API 需要的格式。一个典型的工具对象长这样{ name: Bash, description: Executes a given bash command and returns its output., input_schema: { type: object, properties: { command: { type: string, description: The command to execute } }, required: [command] } }延迟加载的判定发生在工具组装阶段。每个工具都会经过一个类似isDeferredTool(tool)的判定函数规则可以概括为四条MCP 工具默认被延迟isMcp true直接返回 true带alwaysLoad: true的 MCP 工具跳过延迟适合高频工具ToolSearchTool自身永远不延迟因为它是模型发现其他工具的唯一入口内置工具默认不延迟除非显式标记shouldDefer。判定结果会通过willDefer()传入toolToAPISchema()在工具的 API schema 上加上defer_loading: true标记。带这个标记的工具模型只能看到名称和描述看不到完整参数 schema。被延迟的工具不会从工具池移除但发送给 API 时只携带名称。模型在 system prompt 里看到的是一个available-deferred-tools区域每个工具一行available-deferred-tools mcp__slack__send_message — send a message to a Slack channel or user mcp__slack__list_channels — list available Slack channels mcp__github__create_issue — create a new GitHub issue mcp__jira__search_issues — search for Jira issues using JQL /available-deferred-tools模型知道这些工具存在、大概做什么但不知道需要什么参数因此无法直接调用——它必须先通过ToolSearchTool获取完整 schema。ToolSearchTool支持两种查询方式精确查询select:Read,Edit,Grep按名称直接获取关键词搜索notebook jupyter匹配工具描述返回最相关的工具。搜索结果以tool_reference块返回每个匹配工具带完整 JSONSchema{ type: tool_reference, tool: { name: mcp__slack__send_message, description: send a message to a Slack channel or user, input_schema: { type: object, properties: { channel: { type: string, description: Channel ID or name }, text: { type: string, description: Message text } }, required: [channel, text] } } }API 层会自动把tool_reference展开为完整工具定义展开后工具就像从未被延迟过一样可以正常调用。完整链路是工具组装 → 判定是否延迟 → 延迟工具只发名称 → 模型看到available-deferred-tools→ 模型调用ToolSearchTool→ 返回tool_reference→ API 展开 → 模型正常调用目标工具。这里还藏着一个隐性收益prompt cache。模型的 prompt cache 以前缀匹配为基础如果工具列表在两次请求间变化比如 MCP 服务器重连后工具数量变了prompt 就变缓存失效token 重新计算成本和延迟都上升。而defer_loading的工具不参与 KV Cache 的 key 计算API 侧会把它们从 prompt 中剥离所以即使 MCP 工具集合在会话中不断变化已有缓存依然有效。延迟行为也不是一刀切。Claude Code 提供三种ToolSearchMode策略tst默认始终延迟 MCP 工具和shouldDefer工具适合 MCP 工具较多的场景tst-auto仅当延迟工具的 token 超过上下文窗口 10% 时才启用工具较少时自动内联省去 ToolSearch 的额外 round tripstandard完全不延迟所有 schema 内联发送适用于模型不支持defer_loading或工具数量很少的情况。defer_loading是 API 级别特性需要模型侧配合Claude Code 在构建请求前会检查当前模型是否支持不支持的模型只能内联发送。3. settings.json 启用延迟加载的可复制配置骨架理解了机制接下来是能直接抄的配置。Claude Code 的延迟加载相关开关主要落在settings.json里路径通常是用户级~/.claude/settings.json或项目级.claude/settings.json。下面这份骨架把 MCP 服务器、工具搜索模式和延迟策略都串起来了你可以按需删减。{ mcpServers: { slack: { command: npx, args: [-y, modelcontextprotocol/server-slack], env: { SLACK_BOT_TOKEN: xoxb-your-token } }, github: { command: npx, args: [-y, modelcontextprotocol/server-github], env: { GITHUB_PERSONAL_ACCESS_TOKEN: ghp_your_token } }, jira: { command: npx, args: [-y, mcp-server-jira], env: { JIRA_URL: https://your-domain.atlassian.net, JIRA_API_TOKEN: your_jira_token } } }, toolSearch: { mode: tst, autoThreshold: 0.1 }, deferLoading: { enabled: true, alwaysLoadTools: [ mcp__slack__send_message ] } }几个字段要重点解释。toolSearch.mode对应前面说的三种策略填tst、tst-auto或standardautoThreshold只在tst-auto下生效默认 0.1 表示延迟工具 token 超过上下文窗口 10% 才切换。deferLoading.enabled是总开关。alwaysLoadTools里列出的工具会跳过延迟适合你高频使用的工具——比如你几乎每次都要发 Slack 消息就把它放进来避免每次都走一次 ToolSearch。如果你更习惯用 TOML 管理配置等价的片段如下字段语义一致[toolSearch] mode tst autoThreshold 0.1 [deferLoading] enabled true alwaysLoadTools [mcp__slack__send_message]MCP 工具侧还有一个_meta标记可以控制单个工具是否延迟。在 MCP 服务器返回的工具定义里加上_meta: { anthropic/alwaysLoad: true }这个工具就会被标记为alwaysLoad在判定时跳过延迟。这适合服务器作者为高频工具做优化普通用户用settings.json的alwaysLoadTools就够了。配置时有个坑要提醒alwaysLoadTools里的名称必须和实际工具名完全一致MCP 工具的命名规则是mcp__serverName__toolNameserverName 是你在mcpServers里定义的键名。写错一个字符这个工具就不会被豁免仍然走延迟加载。另外deferLoading.enabled为 true 但模型不支持defer_loading时Claude Code 会回退到内联发送不会报错但你也享受不到延迟收益——所以升级模型后记得确认一下。4. 验证一次工具检索与按需加载配置写完怎么确认延迟加载真的生效了最直接的办法是观察一次完整的工具检索动作。启动 Claude Code 后先问一个需要用到 MCP 工具的问题比如帮我在 Slack 的 #general 频道发一条 hello。如果延迟加载生效模型不会直接调用mcp__slack__send_message而是先调用ToolSearchTool。你可以在 Claude Code 的输出里看到类似这样的检索请求ToolSearch: select:mcp__slack__send_message或者用关键词搜索ToolSearch: slack send message返回结果是一个tool_reference块包含该工具的完整 schema。API 层展开后模型才拿到channel和text两个参数的定义然后发起真正的工具调用{ name: mcp__slack__send_message, input: { channel: #general, text: hello } }如果你想更精确地验证可以打开 Claude Code 的调试日志观察请求体里tools数组的差异。延迟生效时mcp__slack__send_message这个工具对象只带name和description并带defer_loading: true没有input_schema而ToolSearchTool自身是完整内联的。展开后tool_reference会被替换成完整定义。还有一个验证点是缓存。连续发两次相同前缀的请求第二次的 prompt cache 命中率应该更高因为延迟工具不参与 KV Cache 的 key 计算工具集合的微小变化不会导致缓存整体失效。你可以在 API 响应里看cache_read_input_tokens和cache_creation_input_tokens两个字段命中缓存时前者会明显上升。实测下来把 60 个 MCP 工具从全量内联切到tst模式后system prompt 里的工具部分 token 占用能降一个数量级首 token 延迟也有改善。但要注意延迟加载不是免费的——每次用到延迟工具都要多一次 ToolSearch 的 round trip。所以工具数量少的时候比如 10 个以内standard模式反而更快tst-auto就是为这种不确定场景准备的让 Claude Code 自己判断。5. 常见报错排查401、local proxy failed 与 reading choices配置延迟加载的过程中最容易撞上的其实不是延迟机制本身的错而是 MCP 连接和鉴权问题。下面按真实报错逐条排查。401 Unauthorized通常出现在 MCP 服务器启动阶段说明 token 无效或过期。检查settings.json里对应服务器的env字段Slack 的SLACK_BOT_TOKEN必须以xoxb-开头GitHub 的GITHUB_PERSONAL_ACCESS_TOKEN要确认 scope 包含所需权限。如果 token 刚轮换过重启 Claude Code 让 MCP 服务器重新读取环境变量。local proxy failed一般和网络层有关常见于 MCP 服务器通过npx启动时下载依赖失败或者本地端口被占用。先确认npx -y modelcontextprotocol/server-slack能在终端单独跑起来如果卡在下载检查 npm registry 配置如果提示端口占用换一个端口或关掉冲突进程。这个报错和延迟加载无关但会直接导致工具列表为空延迟自然也无从谈起。reading choices这类报错通常出现在 API 响应解析阶段提示返回结构不符合预期。如果你在自建代理层或中间件里处理 Claude API 响应要确认tool_reference块被正确展开——有些中间件不认识这个新块类型会把它当普通文本透传导致模型拿不到完整 schema。排查方法是打印原始响应确认tool_reference是否被展开成完整工具定义。OAuth相关报错多见于需要 OAuth 授权的 MCP 服务器。这类服务器首次连接会要求浏览器授权如果 Claude Code 运行在无头环境授权流程会卡住。解决办法是先在本地终端完成一次授权把生成的 token 写进env再让 Claude Code 使用。还有一个隐蔽问题配置了deferLoading.enabled: true但模型不支持defer_loading此时不会报错只是静默回退到内联。如果你发现工具 schema 仍然全量出现在请求里先确认当前模型是否在支持列表内再检查toolSearch.mode是否被其他配置覆盖。排查时建议按连接 → 鉴权 → 工具列表 → 延迟标记 → 展开的顺序逐层确认。连接和鉴权问题会让工具列表为空延迟标记问题会让 schema 全量内联展开问题会让模型拿到工具名却调不动。每一层都有对应的日志可看别一上来就怀疑延迟机制本身。6. 把延迟加载接进你的日常编码流如果你已经配好多个 MCP 服务器建议先把toolSearch.mode设成tst-auto让它根据工具数量自动切换省去手动调参。等观察一段时间、确认哪些工具高频后再把它们加进alwaysLoadTools减少 ToolSearch 的 round trip。需要拿 API Key 或查看接入细节的可以从这里进API Keys 页面 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 接入文档在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。想先验证模型对defer_loading的支持情况可以直接在模型对话里试 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。如果你长期用 Claude Code 跑 Agent 任务Coding Plan 更适合 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewrite 。最后留一个实用技巧延迟加载的收益和工具数量强相关工具少时别硬开。我一般会在项目.claude/settings.json里按项目单独配toolSearch.mode前端项目只挂 GitHub 和 Slack 就用standard后端项目挂一堆 MCP 才切tst。这样每个项目的上下文开销都可控也不会因为一个全局配置影响所有场景。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。