当前位置: 首页
AI教程
AI Agent工具按需加载原理解决上下文窗口溢出

AI Agent工具按需加载原理解决上下文窗口溢出

热心网友 时间:2026-07-07
转载

当AI Agent接入的工具数量多到占满上下文窗口时,一个现实且棘手的问题也随之出现了:我们该如何按需加载模型真正需要的工具?本文将深入拆解这个被称为“tool search”的机制,覆盖其实现原理、匹配算法、缓存影响,并结合x-code-cli的源码进行探讨。

Tool 与 MCP Tool

大语言模型本身无法执行操作

大语言模型(LLM)本质上是一个纯粹的文本生成器。它接收文本输入,输出文本应答,无法主动调用外部服务或执行系统操作。

那么,AI Agent究竟是如何做到读取文件、编写代码、甚至执行命令的?关键在于模型可以通过“工具调用”来“遥控”这些操作。打个比方,模型输出一条指令——“我要调用readFile工具,参数是package.json”——客户端这边(也就是实现了MCP协议的AI Agent应用,如x-code-cli、Claude Code、Cursor等工具)就会解析这条指令,实际去读取文件,然后将读到的内容回传给模型。模型拿到文件内容后,继续推理,决定下一步做什么。

这些可供模型调用的操作——读文件、执行命令、搜索代码、查数据库、联网搜索——统称为Tool(工具)。每个工具由三个部分组成:一个名字(name)、一段自然语言描述(description,用于告知模型该工具的用途)、以及一份JSON Schema(inputSchema,定义了工具接受的参数)。以x-code-cli的readFile工具为例:

{"name": "readFile","description": "Read the contents of a file at the specified path.","inputSchema": {"type": "object","properties": {"path": {"type": "string","description": "The absolute path of the file to read"},"offset": {"type": "number","description": "Line number to start reading from (1-based)"},"limit": {"type": "number","description": "Maximum number of lines to read"}},"required": ["path"]}}

这三部分会被序列化后,嵌入每次API请求的tools数组中。模型依靠description判断何时使用该工具,依靠inputSchema生成合法参数。一个工具的定义越复杂(参数多、描述长),其占用的token就越多。

下面是x-code-cli中Agent Loop的执行流程:

sequenceDiagramautonumberactor U as 用户participant C as 客户端(x-code-cli)participant LLM as LLM APIU->>C: "帮我把 utils.ts 里的 foo 函数重命名为 bar"C->>LLM: 用户消息 + 工具列表(readFile, edit, shell, grep...)LLM-->>C: tool_call: readFile({path: "src/utils.ts"})Note over C: 客户端执行 readFile,读取文件内容C->>LLM: tool_result: "export function foo() { ... }"LLM-->>C: tool_call: edit({path: "src/utils.ts", old: "foo", new: "bar"})Note over C: 客户端执行 edit,替换字符串C->>LLM: tool_result: "文件已修改"LLM-->>C: 文本回复: "已将 foo 重命名为 bar"C->>U: 展示回复

在整个过程中,模型自主决定调用什么工具、传递什么参数。客户端只负责执行和传递结果。这个循环可能执行一次,也可能执行多次,完全取决于任务的复杂度。

工具数量的增长趋势

内置工具

一个Agent产品刚上线时,内置工具的数量可能不多。但随着产品迭代,工具会逐渐增多。联网搜索、网页抓取、子Agent委派、待办管理、后台任务管理等功能会相继加入。Claude Code、Codex、Cursor等主流AI Agent产品都经历了这个增长过程。一个成熟的AI Agent产品拥有几十个内置工具,是非常普遍的情况。

MCP 工具

MCP(Model Context Protocol,模型上下文协议)是一套用于Agent接入外部服务的开放协议。例如,接入GitHub MCP server,Agent就能创建issue、合并PR;接入一个数据库MCP server,Agent就能执行SQL查询。

各个MCP Server会通过tools/list接口,向客户端注册自身对外开放的全部工具。该接口采用全量返回模式——客户端在与某一服务端建立连接后,可以一次性获取该服务端完整的工具定义清单。

sequenceDiagramparticipant C as MCP 客户端(AI Agent)participant S1 as MCP Server A(交易所)participant S2 as MCP Server B(数据库)C->>S1: 建立连接C->>S1: tools/listS1-->>C: 返回 400 个工具定义C->>S2: 建立连接C->>S2: tools/listS2-->>C: 返回 15 个工具定义Note over C: 客户端拿到所有 server 的完整工具列表
共 415 个工具,全部放进后续的 LLM 请求

MCP tool和内置tool在结构上没有本质区别,都是“名字+描述+JSON Schema”。区别仅在于提供方:内置工具由产品代码静态定义,MCP工具则由外部server动态注册。

一个MCP server提供的工具数量往往远超内置工具。以加密货币交易所的MCP server为例,它覆盖现货交易、合约交易、资产划转、行情查询、余额查询等操作,总计可达400个工具。如果用户再接入其他MCP server,工具总数很容易超过400个。

工具数量增多带来的挑战

要让大模型调用这些工具,所有工具定义必须随请求一起发送给模型。关键在于,大语言模型本身是无状态的——每次发起推理请求时,都需要重新携带完整的工具列表。

一个中等复杂度的工具定义大约占用150–300 token(名字占几个token、描述占一两行、JSON Schema中的属性名和类型描述占用大头)。400个工具 × 平均160 token ≈ 64,000 token。用户尚未开始提问,仅工具定义就占据了64k token。

具体来看x-code-cli中调用LLM时的请求结构。以下是packages/core/src/agent/loop.tsrunTurn函数的核心代码(简化后):

result = streamText({model, // LLM 模型实例system: cached.system, // System Prompt(系统提示),约 2-5k tokenmessages: cached.messages,// Messages(对话历史 + 用户消息)tools: cached.tools, // Tools(工具定义)← 全量注入时 64k tokenmaxRetries: 3,abortSignal: options.abortSignal,maxOutputTokens: getMaxOutputTokens(options.modelId),providerOptions: mergedProviderOptions,})

一次API请求的输入由systemtoolsmessages三个字段组成。token的分布大致如下:

一次 API 请求的 Token 构成:┌────────────────────────────────────┐│ system(系统提示)│约 2-5k token├────────────────────────────────────┤│ tools(工具定义) │← 全量注入时:64k token(400 个工具)├────────────────────────────────────┤│ messages(对话历史 + 用户消息)│根据对话长度变化└────────────────────────────────────┘如果模型的上下文窗口是 128k,工具列表占掉了将近一半

关于费用,需要补充一点:主流LLM API都支持前缀缓存(prefix caching)。system + tools这些每轮不变的前缀部分,首次请求按全价计费,后续请求命中缓存后按折扣价计费(通常是原价的10%–50%)。因此,并非每轮都需要支付全价。

但即便是64k token的工具列表命中了缓存,它仍在持续产生开销——它占用了上下文窗口的物理空间,延迟了首字生成时间(TTFT),并压缩了留给对话历史和用户消息的空间。工具列表越大,可用于实际对话的窗口就越小。

这就引出了本文的核心主题——tool search。

Tool Search 机制详解

Tool search是一个用于“按需加载工具定义”的内置工具。默认情况下,所有工具的完整定义(名字、描述和JSON Schema)都会嵌入每次请求的tools数组。tool search改变了这一策略:仅在系统提示中放置一份工具名字清单,不放完整定义。当模型判断需要调用某个工具时,先通过内置的toolSearch工具加载该工具的完整schema,然后在下一轮再执行调用。

模型仍然知道有哪些工具可用——系统提示中列出了所有工具的名字。但每个工具的完整定义(描述和JSON Schema)不会预先放入请求,而是等模型实际要调用时再加载。这样一来,上下文占用从全量64k降至仅加载工具名字清单所需的3-5k,再加上按需加载的几个工具的schema。

延迟加载(Deferred)机制

Deferred直译为“延迟”。在tool search的语境下,deferred工具就是那些被延迟加载的工具——它们的完整定义(描述和JSON Schema)不随请求发送,只在模型通过toolSearch主动请求时才会加载。与之对应的是直接加载的工具(directly loaded),即每轮请求都携带完整schema的核心工具。

下面来看按需加载具体是如何实现的,主要包含以下几个步骤:

第一步:客户端照常从MCP server全量获取工具。tools/list接口仍是全量返回。客户端启动时从每个MCP server拉取所有工具的完整定义——名字、描述、JSON Schema——全部存储在本地内存中。这一步与没有tool search时完全一致。

第二步:仅将工具名称告知模型。完整的工具schema不放入请求的tools数组。工具名称按server分组,写在系统提示的## Deferred Tools段中。模型每轮都能看到这份名称清单,知道有哪些工具可用,但看不到每个工具接受什么参数。

以下是x-code-cli实际生成的## Deferred Tools段(截取部分):

## Deferred ToolsThe tools below are a vailable but NOT loaded — only their names are listed,with no schema. To use one, first call `toolSearch` (keyword search, or`select:` to load specific tools by name); its schema is thenadded to your tool set and it becomes directly callable on your next step.Core tools (readFile, writeFile, edit, shell, grep, glob, listDir, task)are always loaded — never search for those.### Built-in- webSearch, webFetch, todoWrite, activateSkill### Server: gate-mcp- mcp__gate__cex_spot_get_ticker, mcp__gate__cex_spot_create_order,mcp__gate__cex_spot_get_balance, mcp__gate__cex_futures_get_ticker,... (共 400 个工具)### Server: github- mcp__github__create_issue, mcp__github__list_pull_requests,mcp__github__merge_pull_request, ...

可以看到,这段文字包含两部分信息:一是使用说明(告诉如何通过toolSearch加载工具),二是按来源分组的工具名称清单。模型每轮都能看到这份清单,但看不到任何工具的参数定义。

第三步:为模型提供一个内置的toolSearch工具。当模型需要调用某个deferred工具时,它先调用toolSearch,传入关键词或工具名。客户端在内存中的工具目录上进行匹配,将命中的工具加入下一轮请求的tools数组。模型在下一轮就能像调用任何普通工具一样调用它。

sequenceDiagramparticipant S as MCP Serverparticipant C as 客户端(MCP 客户端)participant LLM as LLMNote over S,C: 启动时C->>S: tools/listS-->>C: 400 个工具的完整定义Note over C: 全部存在内存里Note over C,LLM: 用户提问:"帮我查一下 BTC/USDT 的最新价格"C->>LLM: 核心工具 schema + toolSearch schema + deferred 名字清单Note over LLM: 看到名单里有 cex_spot_get_ticker,
但没有它的 schema,无法直接调用LLM-->>C: toolSearch({query: "select:mcp__gate__cex_spot_get_ticker"})Note over C: 在内存目录里匹配,把这个工具加入 activated 集合C->>LLM: 核心工具 + toolSearch + cex_spot_get_ticker(刚激活的 schema)LLM-->>C: cex_spot_get_ticker({currency_pair: "BTC_USDT"})

需要强调的是:deferred是客户端的行为。MCP协议的tools/list依旧全量返回,协议本身不具备按需发现的能力。deferred机制完全是客户端在拿到全量工具列表后,自行决定哪些放入请求、哪些延迟加载——这是客户端的策略,而非协议的功能。

模型仅看到名称,如何找到正确工具?

如果仅提供工具名称,而不附带对应的Schema,模型确实无法明确工具的入参结构。为了解决这个问题,系统设计了多层校验保障机制。

工具名称自身已具备充足的语义描述能力。mcp__github__create_issuecex_spot_get_ticker这类名称,模型一看就能理解其功能。MCP工具名通常遵循server__actionserver__resource__verb的命名规范,名称本身就是一层语义索引。如果工具名全是tool_001tool_002,这套方案就无法生效了。

名称清单放置在模型可见的位置。系统提示的## Deferred Tools段按server分组列出了所有deferred工具名称。模型并非盲目搜索——它看到了完整清单,只是未看到每个工具的参数定义。

客户端完成toolSearch的匹配运算。toolSearch支持两种调用方式:关键词搜索和精确匹配。

方式一:关键词搜索。当模型不确定工具的确切名称时使用。客户端拿query参数与每个工具的预处理文本进行关键词匹配,按得分排序,返回前几个匹配结果。

用一个例子来说明。假设deferred目录中包含以下几个工具:

工具目录(每个工具在注册时预处理好搜索文本):工具名搜索文本(名字拆词 + 描述 + schema 属性名)─────────────────────────────────────────────────────────────────────────mcp__gate__cex_spot_get_ticker gate cex spot get ticker 获取现货行情 currency_pairmcp__gate__cex_spot_create_order gate cex spot create order 创建现货订单 currency_pair side amount pricemcp__gate__cex_spot_cancel_order gate cex spot cancel order 取消现货订单 order_idmcp__github__create_issuegithub create issue 创建 issue title body labels

模型传入toolSearch({query: "spot ticker"})后,客户端对每个工具进行打分:

query = "spot ticker"mcp__gate__cex_spot_get_ticker:"spot" → 名字拆词里有 "spot" → +10"ticker" → 名字拆词里有 "ticker" → +10总分 = 20 ✓mcp__gate__cex_spot_create_order:"spot" → 名字拆词里有 "spot" → +10"ticker" → 名字拆词里没有,搜索文本里也没有 → +0总分 = 10mcp__gate__cex_spot_cancel_order:"spot" → 名字拆词里有 "spot" → +10"ticker" → 名字拆词里没有,搜索文本里也没有 → +0总分 = 10mcp__github__create_issue:"spot" → 都没有 → +0"ticker" → 都没有 → +0总分 = 0结果(按分数降序):1. mcp__gate__cex_spot_get_ticker (20)← 返回2. mcp__gate__cex_spot_create_order (10)← 返回3. mcp__gate__cex_spot_cancel_order (10)← 返回4. mcp__github__create_issue(0) ← 过滤掉

Codex的搜索逻辑类似,也是为每个工具预先生成搜索文本,但打分采用BM25算法(信息检索领域的经典排序算法,搜索引擎常用它来排序搜索结果)。核心思路一致:用query的关键词去匹配工具的搜索文本,按相关度排序。

这两种方式都不需要使用embedding,也无需调用模型,执行的都是字符串匹配——同样的query、同样的工具集,得到的结果完全一致。

此外,关键词搜索可能会同时命中多个工具。toolSearch按打分排序,取前N个(x-code-cli默认取5个),所有命中的工具都会被激活——加入activated集合,在下一轮全部出现在tools数组中。模型拿到这几个工具的schema后,自行判断使用哪一个,客户端不进行限制。

举个例子:用户说“帮我下一个限价单买BTC”,模型调用toolSearch({query: "spot order"}),可能会同时命中cex_spot_create_ordercex_spot_get_tickercex_spot_cancel_order等多个工具。多激活几个工具的代价是每个工具多占一份schema的token,但这比全量注入400个工具要好得多。而且激活是持久的——一旦激活,后续轮次无需重复搜索同一个工具,可以直接使用。

方式二:select:精确匹配。模型直接传递select:工具名,客户端按名称精确查找,无需打分。

模型如何知道确切的工具名?因为系统提示的## Deferred Tools段中列出了所有deferred工具的完整名称。模型每轮都能看到这份清单,只要它在清单中找到了目标工具名,就可以直接使用select:加载。

何时使用哪种方式?这个逻辑写在toolSearch工具自身的description中,模型在调用前会读到这段说明:

Pass `query` as either:- keywords describing the capability you need(e.g. "search the web", "github create issue")→ returns the best-matching deferred tools, or- "select:," to load specific tools by theirEXACT name from the Deferred Tools list(prefer this when you already know the name).

工具描述直接告诉模型:如果已经知道名称,优先使用select:;不确定名称时,用关键词描述能力。实际使用中,模型大多数情况会走select:路径,因为它能直接从清单中看到工具名。关键词搜索是模型对工具名不确定时的备选路径——例如当工具名较长或有多个相似工具时,模型可能使用"spot order"这样的关键词让客户端协助筛选。

两种调用方式对比:关键词搜索(不确定工具名时用):toolSearch({query: "spot ticker"})→ 客户端对所有工具做关键词打分,返回得分最高的几个精确匹配(已知工具名时用,推荐方式):toolSearch({query: "select:mcp__gate__cex_spot_get_ticker"})→ 客户端直接按名字查找,找到就返回,不打分

关键词搜索是一层保底机制。模型大多数情况下能直接从清单中找到目标工具名,走select:精确匹配。只有当模型不确定具体使用哪个工具时,才会退而使用关键词搜索让客户端协助筛选。

哪些工具应被Defer,哪些应直接加载

并非所有工具都需要defer。一些核心工具会直接加载,而一些偶尔才用的工具才会被defer。

直接加载的工具(每轮请求都携带完整schema):

这类工具是Agent的基础操作能力,用户随便问个问题都可能用到:

工具功能为何必须直接加载
readFile读取文件几乎所有编码任务都需要先读取文件
edit编辑文件编写代码的核心操作
writeFile写入文件创建新文件
shell执行命令运行测试、安装依赖、git操作
grep搜索代码定位代码位置
glob查找文件查找文件路径
task子Agent委派子任务
toolSearch工具搜索加载deferred工具的唯一入口

延迟加载(defer)的工具:

  • 非核心内置工具:webSearch(联网搜索)、webFetch(网页抓取)、todoWrite(待办清单)。这些工具并非每个任务都会被用到,因此需要时再加载。
  • 所有MCP工具:MCP工具由外部server提供,面向特定场景(交易、GitHub操作、数据库查询等),不存在“每个任务都会用到”的MCP工具。

用一个具体例子来说明分类过程。假设Agent注册了以下工具:

分类示例:readFile→ 核心内置工具,每个任务都用→ 直接加载edit→ 核心内置工具,每个任务都用→ 直接加载shell → 核心内置工具,每个任务都用→ 直接加载toolSearch→ 加载入口,必须直接可用 → 直接加载webSearch → 非核心内置,偶尔才用 → deferwebFetch→ 非核心内置,偶尔才用 → defermcp__gate__cex_spot_get_ticker→ MCP 工具→ defermcp__gate__cex_spot_create_order→ MCP 工具→ defermcp__github__create_issue → MCP 工具→ defer...(其余 MCP 工具全部 defer

以下是判断逻辑的流程图:

完整循环:搜索 → 激活 → 调用

来看一个具体的示例——以“查询BTC价格”来演示实际的调用过程:

sequenceDiagramautonumberactor U as 用户participant C as 客户端participant LLM as LLMU->>C: "帮我查一下 BTC 的现货价格"C->>LLM: 用户消息 + 核心工具 + toolSearch + deferred 名字清单Note over LLM: 看到名单里有 cex_spot_get_tickerLLM-->>C: toolSearch({query: "select:mcp__gate__cex_spot_get_ticker"})Note over C: 精确匹配命中,加入 activated 集合C-->>LLM: tool_result: "Loaded 1 tool(s) — now callable directly on your next step"Note over C: 下一轮请求的 tools 数组追加 cex_spot_get_ticker 的完整 schemaC->>LLM: 核心工具 + toolSearch + cex_spot_get_ticker(已激活)LLM-->>C: cex_spot_get_ticker({currency_pair: "BTC_USDT"})Note over C: 执行 MCP 工具调用,拿到价格C->>LLM: 工具执行结果LLM-->>C: "BTC 现货价格是 63,521.30 USDT"C->>U: 展示回复

注意步骤3和步骤5之间:模型在第一轮调用了toolSearch工具,但不能在同一轮里调用cex_spot_get_ticker——因为这个工具在第一轮的tools数组中尚不存在。必须等客户端将其schema加入后,下一轮模型才能调用。

这就是deferred方案的代价:首次使用某个deferred工具时,至少需要2轮API调用——先搜索,下一轮才能调用。

整个流程中State的变化

从启动到多轮对话,各个state字段的变化过程如下:

阶段state 变化
启动catalog = 从所有 MCP server 拿到的 400 个 deferred 工具的完整定义
activated = 空集合
systemPromptCache = 系统提示,包含 ## Deferred Tools 名字清单
baseTools = [readFile, edit, shell, grep, ..., toolSearch]
第 1 轮请求tools = composeTurnTools(baseTools, activated) = baseTools(activated 为空)
用户:“查 BTC 价格”发给 LLM:system + tools(9 个核心工具)+ messages
第 1 轮响应LLM 返回:toolSearch({query: "select:mcp__gate__cex_spot_get_ticker"})
handleToolSearch() 在 catalog 里精确匹配命中
activated = { "mcp__gate__cex_spot_get_ticker" }
返回 tool_result 给模型:Loaded 1 tool(s) — now callable directly on your next step:
- mcp__gate__cex_spot_get_ticker: 获取现货行情
第 2 轮请求tools = [...baseTools, cex_spot_get_ticker 的完整 schema](尾部多了一个工具)
messages 里追加了上一轮的 tool_call + tool_result
发给 LLM:system + tools(10 个工具)+ messages,前缀缓存 miss 一次
第 2 轮响应LLM 返回:cex_spot_get_ticker({currency_pair: "BTC_USDT"})
客户端执行 MCP 工具调用,拿到价格。activated 不变
第 3 轮tools 同第 2 轮(activated 没变,前缀稳定,缓存命中)
LLM 返回文本回复
后续轮次activated 持久保留,不用再搜 cex_spot_get_ticker
如果激活新工具 → activated 增长 → tools 追加 → 再 miss 一次

几个关键点:

  • catalogsystemPromptCache在启动时固定,整个session中不变。
  • activated只增不减。
  • tools数组每轮动态合成 = baseTools + activated对应的schema。
  • 前缀缓存仅在activated增长的那一轮miss,之后保持稳定。

工程实现细节

前面讲解的是tool search的核心流程。本节主要探讨实现过程中遇到的几个问题及其解决方案。

阈值判断:何时应启用defer。当工具数量较少时,全量注入更简单,也无需多一轮往返。x-code-cli使用DEFERRAL_THRESHOLD_PERCENT进行判断:将所有候选deferred工具的schema序列化后估算token量,如果不超过模型上下文窗口的10%,则跳过defer,退回全量加载模式。

模型兼容性。Tool search依赖模型主动调用toolSearch。如果模型不支持或不配合,deferred工具将永远不会被加载。各家的处理方式有所不同:

  • Codex的做法最为精确:在models.json中按具体模型版本配置supports_search_tool布尔字段。只有明确标记为支持的模型才启用tool search,未知模型默认关闭。
  • Claude Code判断的是API能力而非模型智能:使用modelSupportsToolReference()检查模型是否支持tool_reference协议块。默认排除列表只有['haiku'],但可通过远程配置动态更新,无需发布新版本。
  • x-code-cli目前使用粗粒度的字符串匹配:WEAK_MODEL_PATTERNS = ['haiku', 'nano', 'glm-4v'],模型名包含这些子串则退回全量注入。该方案的缺点是无法区分同一系列的不同版本——例如Claude 3 Haiku和Claude 3.5 Haiku能力差异很大,但都会被一刀切地禁用。

系统提示的字节稳定性。LLM API的前缀缓存依赖于请求前缀的不变性。system + tools组成的前缀在后续请求中保持一致,就能命中缓存,按折扣价计费。这就要求系统提示中的deferred名单不能在运行过程中动态修改。x-code-cli的做法是在启动时生成systemPromptCache并冻结,在整个session中不再改动。

这带来一个副作用:工具激活后,系统提示中的名单仍然标注该工具为deferred状态,但tools数组中已包含其完整schema。模型看到的系统提示和实际的工具列表之间存在不一致:系统提示说工具未加载,但工具实际上已在列表中。

在实际使用中,这种不一致很少引发问题。强模型(如Sonnet、GPT-4o等级)在收到第一次toolSearch的tool_result后,会记住工具已加载,后续直接调用而不会重复搜索。重复搜索仅在极端情况下出现——例如对话轮次非常多,早期的tool_result被压缩,模型再次看到系统提示中写着“未加载”时,才可能再次搜索。x-code-cli增加了一层防御:如果搜索的工具已在activated集合中,返回Already loaded — call xxx directly now.,避免模型陷入搜索循环。这是防御性代码,并非常规路径。

Claude Code和Codex从架构上避免了这种不一致。Claude Code依靠Anthropic API的tool_reference机制,激活的工具由服务端展开schema,客户端不修改tools数组。Codex依靠OpenAI Responses API的tool_search_output历史项,同样由服务端处理。两者都无需在系统提示中维护一份可能过时的状态。x-code-cli由于需要跨多个provider,无法依赖单一API的服务端能力,只能走客户端重注入——但从实际效果看,强模型下这种不一致几乎不会触发重复搜索。

子Agent不开启defer。子Agent的工具集由白名单控制,大多数子Agent只有几个内置工具。例如explore子Agent仅包含readFileglobgreplistDirshell五个工具,plan子Agent更少,只有四个只读工具。工具数量如此少,添加tool search没有意义。唯一的例外是general-purpose子Agent——它继承了父session的MCP工具,工具数量可能很多,但即便如此,子Agent目前也走全量注入,因为子Agent的生命周期短、轮次少,defer带来的节省不明显。

总结

回顾一下tool search的完整流程:启动时从MCP server全量获取工具定义,根据使用频率分为直接加载和deferred两类。直接加载的工具,其完整schema放入每轮请求的tools数组;deferred工具仅在系统提示中列出名称。当模型需要某个deferred工具时,调用toolSearch加载其schema,下一轮即可正常调用。

几个主流AI Agent CLI的实现对比:

全量注入?动态机制匹配算法
Claude CodeToolSearch 工具关键词打分 + select:
Codextool_search 工具BM25 全文检索
Gemini CLI
x-code-clitoolSearch 工具关键词打分 + select:

Claude Code、Codex、x-code-cli三家的思路几乎一致,区别在于激活后的schema如何对模型可用——Claude Code和Codex依靠各自API的服务端能力,x-code-cli依靠客户端重注入(直接将schema加入tools数组)。Gemini CLI目前没有内置tool search功能。

参考资料

  • Claude Code 源码
  • Codex 源码
  • x-code-cli 源码
  • MCP 协议规范
来源:https://juejin.cn/post/7659034306872623156

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
科研人员必读:多肽、蛋白质、重组蛋白区别及定制指南

科研人员必读:多肽、蛋白质、重组蛋白区别及定制指南

Section 01 多肽 VS 蛋白质 VS 重组蛋白 多肽、蛋白质和重组蛋白,本质上是同宗同源的东西——都是氨基酸串起来的生物大分子。三者的核心区别,说到底无非是三个维度:分子大小、折叠形态,以及生产方式。 接下来是一张清晰的对比图,帮你快速建立直觉: ![对比图1](https:

时间:2026-07-07 17:55
知识图谱与本体语义建模的核心区别解析

知识图谱与本体语义建模的核心区别解析

谈到人工智能如何“理解”知识,有两个概念常被放在一起讨论:知识图谱与本体语义建模。不少人以为它们是同一事物,或者认为后者是前者的进化版。实际上,两者的分工完全不同——打个比方,一个是“记事的本子”,另一个是“写本子之前先定好的规矩”。 1 本体语义建模:先绘制一张“通用分类蓝图” 设想一下,你要整

时间:2026-07-07 17:55
强烈推荐工作搭子WorkBuddy

强烈推荐工作搭子WorkBuddy

一次偶然的机会,从朋友那里了解到WorkBuddy这个工具。说实话,在AI产品扎堆的今天,能遇到一个下载即用的助手,确实值得推荐给每一个被日常琐事缠身的人。 安装过程没什么难度,双击安装包默认安装即可。需要留意的是,如果在Windows7上折腾了半天没反应,别慌——这工具在高版本Windows下运行

时间:2026-07-07 17:55
跨境电商系统自动化测试与CI/CD流水线构建指南

跨境电商系统自动化测试与CI/CD流水线构建指南

技术方向:自动化测试与DevOps实践关键词:日本代购、一站式日淘、雅虎代拍系统、煤炉自动代拍 一、测试分层策略详解 不少人刚开始就想直接搞E2E测试,觉得跑通完整流程才够“真实”。然而,测试金字塔这么多年仍不过时,原因很简单——不同层级的测试各有分工,缺少任何一层都会不稳。来看看这张金字塔图: ┌

时间:2026-07-07 17:54
中小企业AI营销矩阵工具推荐:赛诺贝斯智域蒲公英

中小企业AI营销矩阵工具推荐:赛诺贝斯智域蒲公英

天天刷着别人的爆款内容,自己却“有心无力”——这才是2026年绝大多数中小企业运营社交媒体的真实写照。说白了,社交媒体如今早已不是“要不要做”的选择题,而是“怎么做才能真正见效”的生存考验。现实情况是,团队人力就那么几个,预算也紧巴巴,却要同时运营抖音、小红书、知乎、头条、百家号等多个阵地……文案、

时间:2026-07-07 17:54
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 日榜
  • 周榜
  • 月榜