摘要:当工具集从个位数膨胀到十几个,函数调用(Function Calling)系统的失败模式会发生质变:工具描述在上下文里互相争夺注意力,参数 schema 的微小歧义被放大为参数幻觉,而原型阶段只覆盖 happy path 的评测集无法暴露真实分布下的选择错误。本文以“选择熵”为贯穿主线,把“工具一多就选不准”拆解为候选空间膨胀、描述语义重叠、schema 约束松弛、评测分布偏移四个可测量维度,系统比较动态接口裁剪(retrieval-based tool routing)与描述重写(description/schema engineering)两类干预的机制边界与组合策略,并给出可落地的工程路径、评估指标与前沿预判。文中数据均标注来源,模拟数据单独注明。
目录
一、导语:从“能用”到“选得准”的相变点
函数调用能力进入生产系统后,工程团队普遍会经历一个相似的曲线:工具数量在 3 个左右时,系统表现稳定,模型几乎不会选错;当工具扩展到 10 至 15 个,错误率并非线性上升,而是出现一个明显的拐点——选错工具、编造参数、跳过工具直接作答三类问题同时抬头。这个拐点不是模型“变笨了”,而是候选空间、描述语义与约束结构三者耦合后发生的相变。笔者认为,把它简单归因为“上下文太长”或“模型能力不足”,会掩盖真正可干预的工程变量。
业界对工具调用可靠性的讨论,早期集中在提示词写法与 few-shot 示例上;随着 MCP(Model Context Protocol)等标准化接口的普及,工具注册与发现变得廉价,工具数量膨胀成为常态,问题重心随之迁移到“路由”与“契约”两个层面。Anthropic 在 2024 年底发布的 MCP 规范将工具(tools)、资源(resources)、提示(prompts)分离,客观上鼓励了工具数量的增长;OpenAI 的 function calling 文档则反复强调参数 schema 的严格性。两条线索指向同一个工程事实:工具选择的准确性,是候选集规模、描述区分度与 schema 约束力共同决定的函数,而不是单一提示技巧的产物。
本文的主线是“选择熵”:把模型在工具选择上的不确定性,形式化为候选集上的分布熵,并追踪四类干预如何改变这个熵。围绕这条主线,本文回答三个问题:动态接口裁剪在什么条件下有效、描述重写在什么条件下失效、两者如何组合才能覆盖真实调用分布。所有章节围绕这条主线展开,避免散点式的经验罗列。
二、背景与问题定义:工具选择失败的四种可测形态
2.1 候选空间膨胀:从 3 到 15 的非线性代价
工具选择本质上是一个受约束的分类问题:给定对话上下文与工具清单,模型需要输出一个工具标识及参数。候选集从 3 扩展到 15,分类问题的类别数变为 5 倍,但代价并非线性。原因在于工具描述以自然语言形式进入上下文,彼此之间形成语义干扰;同时,模型对“何时不该调用工具”的判别边界随候选增多而模糊。Berkeley Function Calling Leaderboard(BFCL)自 2024 年起持续跟踪多工具场景下的调用准确率,其 V2/V3 版本引入了多轮、多工具与不可调用(relevance detection)子集,公开榜单显示:在单工具场景准确率普遍超过 90% 的模型,在多工具并发场景下会出现明显回落(BFCL 官方榜单,2024–2025,具体数值随模型版本变化,引用时以榜单快照为准)。本文评述:榜单数值的绝对高低受评测集构造影响很大,但其相对趋势——候选增多导致准确率下降——在多个独立评测中一致出现,这一点比具体数字更值得工程团队关注。
需要区分“工具数量”与“有效候选数量”。即便注册了 15 个工具,若每次请求只暴露 4 个,模型面对的仍是 4 分类问题。动态接口裁剪的核心,就是把“注册规模”与“暴露规模”解耦。这一区分是后文所有讨论的前提。
2.2 描述竞争注意力:语义重叠与近义工具
工具描述是自然语言,天然存在近义与重叠。例如“查询订单状态”与“查询物流信息”在语义上高度相关,若描述都写成“查询订单相关信息”,模型只能依赖参数名猜测。注意力机制在长上下文中对相似片段的区分能力有限,这是 Transformer 架构的固有特性,而非提示词可以完全弥补的缺陷。Liu 等人 2023 年的“Lost in the Middle”研究表明,长上下文中间位置的信息利用率显著低于首尾(Liu et al., TACL 2024,arXiv:2307.03172)。工具描述通常位于系统提示与工具清单区域,若清单较长,靠后工具的描述被有效利用的概率下降。本文评述:这一发现对工具排序有直接工程含义——高频工具应前置,但这只是缓解,不是根治。
语义重叠还带来“描述即接口”的悖论:描述越详细,单条描述占用的注意力预算越多,多条详细描述之间反而互相稀释。工程上常见做法是把描述写得尽量长以求精确,结果适得其反。笔者认为,描述的目标不是“完备”,而是“可区分”——在候选集内最大化与其他工具的语义距离,而非穷尽所有细节。
2.3 参数 schema 松弛:幻觉参数的生成机制
参数幻觉指模型生成了 schema 中不存在、或类型/枚举不匹配的参数值。其生成机制可分解为三步:模型先根据描述推断“应该有哪些参数”,再根据上下文填充值,最后在解码阶段受 schema 约束(若启用严格模式)。若 schema 使用宽松类型(如 string 而非 enum)、缺少 required 声明、或嵌套对象未给出示例,模型在第二步就会“合理推断”出不存在的字段。OpenAI 的结构化输出(Structured Outputs)文档明确指出,严格模式(strict: true)通过约束解码保证输出符合 JSON Schema,但前提是 schema 本身可被正确编译(OpenAI 文档,2024)。本文评述:严格模式解决的是“输出格式合规”,不解决“语义正确”。一个 enum 之外的合法字符串仍可能是错误的业务值,因此 schema 工程必须与描述工程协同。
实践中另一个高发点是可选参数与默认值。当 schema 声明某参数可选而描述未说明缺省行为,模型倾向于显式填充一个“看起来合理”的值,从而引入幻觉。这类问题在 3 工具时代不易暴露,因为模型对少数工具的调用模式已从示例中习得;工具增多后,示例覆盖不足,问题集中爆发。
2.4 评测分布偏移:happy path 只覆盖 40% 的真相
原型阶段的评测集通常由开发者手写,覆盖典型成功路径。这类 happy path 集在工具少时足以发现问题,工具多后则严重失真。真实调用分布中包含大量边界情形:参数缺失、多工具竞争、用户表述模糊、需要澄清而非调用。若评测集只覆盖 40% 的真实分布,模型在剩余 60% 上的表现完全不可见。这一比例在不同团队差异很大,本文不虚构具体统计,但可以给出可验证的构造方法:从生产日志中按意图聚类采样,统计各意图占比,再与评测集意图分布做卡方检验,偏离显著的意图即为覆盖缺口。本文评述:评测集的问题本质是“分布代表性”,而非“用例数量”。扩充用例而不校正分布,只会放大已有偏差。
四类形态并非独立:候选膨胀加剧描述竞争,描述竞争放大 schema 歧义,评测偏移让前三者不可见。这构成了一个正反馈环,也是“工具一多就选不准”难以靠单点修补的原因。
三、原理与技术路线:选择熵框架下的两类干预
3.1 选择熵的形式化定义
设候选工具集为 T,模型在给定上下文 c 下对工具选择的分布为 p(t|c),选择熵定义为 H(T|c) = −Σ p(t|c) log p(t|c)。熵越高,选择越不确定。工程上无法直接读取模型的内部概率(多数 API 不返回工具选择的 logprob),因此需要可观测的代理指标。笔者建议用三个代理量:Top-1 与 Top-2 的评分差(若可获取 logprob)、多次采样的选择一致率、以及在验证集上的混淆矩阵集中度。三者结合可以近似刻画选择熵的相对变化。
在这个框架下,动态接口裁剪降低的是候选集大小 |T|,从而直接压低熵的上界 log|T|;描述重写改变的是 p(t|c) 的形状,使正确工具的分布更尖锐。两者作用在不同项上,因此不是替代关系。本文评述:把二者对立起来讨论“该靠哪个”,在形式上就是混淆了熵的上界与分布形状,这是很多工程争论的根源。
3.2 动态接口裁剪:检索式工具路由
动态接口裁剪的典型实现是“两阶段路由”:第一阶段用轻量检索(向量相似度、BM25 或小型分类器)从全量工具中召回 k 个候选,第二阶段把 k 个候选的描述与 schema 送入主模型做最终选择。k 的取值通常在 3 至 8 之间,需在召回率与选择准确率之间权衡。相关方法可参考 ToolLLM 的工具检索思路(Qin et al., ICLR 2024,arXiv:2307.16789)与 Gorilla 的检索增强调用(Patil et al., 2023,arXiv:2305.15334)。本文评述:两阶段路由的关键风险在召回阶段——若正确工具未被召回,第二阶段再强也无济于事。因此召回率(Recall@k)必须作为一级指标监控,而不能只看最终准确率。
另一种裁剪是“状态机式暴露”:根据对话所处阶段(如售前、下单、售后)只暴露该阶段的工具。这种方式可解释性强、延迟低,但依赖业务状态定义清晰,跨阶段意图容易漏召回。工程上常与检索式路由组合:状态机做粗筛,检索做细排。
3.3 描述重写:从“写清楚”到“写可区分”
描述重写的目标函数应是候选集内的语义可分性,而非单条描述的完备性。可操作的原则包括:统一句式模板(动词+对象+约束),使同类工具在结构上可比;显式写出“不适用场景”,用负例划界;参数描述与 schema 一一对应,避免描述里出现 schema 没有的字段;对近义工具给出互斥的使用条件。Anthropic 的提示工程文档建议工具描述包含用途、输入、边界与示例四要素(Anthropic 文档,2024)。本文评述:四要素是必要不充分条件,真正的难点在于“边界”的写法——边界必须可判定,不能写成“适用于复杂场景”这类不可操作的表述。
描述重写还有一个常被忽视的维度:命名。工具名是描述的一部分,且权重很高。把 get_order_status 与 query_logistics 改成语义距离更大的命名,往往比改描述正文更有效。这一点在工程上成本极低,应优先尝试。
3.4 schema 工程:约束解码与语义校验的分工
schema 工程分两层:语法层用严格模式保证输出可解析、字段不越界;语义层用枚举、正则、范围与跨字段约束(如 end_date ≥ start_date)压缩合法值空间。语法层已有成熟实现(OpenAI Structured Outputs、各框架的 JSON Schema 校验),语义层则需要在服务端做二次校验并返回结构化错误,让模型有机会自我修正。本文评述:把语义校验完全前移到 schema 是不现实的,因为业务规则常依赖外部状态;更稳妥的做法是 schema 管“形状”,服务端管“语义”,两者通过结构化错误码衔接。
下面是一个把宽松 schema 收紧为可判别 schema 的示例,重点在 enum、required 与描述的一致性:
{
"name": "query_order",
"description": "按订单号查询订单状态。仅用于已知订单号的场景;用户仅提供手机号时改用 search_orders_by_phone。",
"parameters": {
"type": "object",
"properties": {
"order_id": {
"type": "string",
"pattern": "^[A-Z]{2}\\d{10}$",
"description": "订单号,格式为两位大写字母加十位数字,例如 AB1234567890"
},
"fields": {
"type": "array",
"items": { "type": "string", "enum": ["status", "amount", "items"] },
"description": "需要返回的字段;缺省返回 status"
}
},
"required": ["order_id"],
"additionalProperties": false
}
}
这段 schema 的三个要点:description 里写了负例边界(改用另一个工具),order_id 用 pattern 压缩非法值,additionalProperties: false 阻断多余字段。三者分别对应描述层、语法层、结构层的约束,缺一不可。
四、关键数据与工程案例:从 3 到 15 的实测拆解
4.1 公开评测的趋势证据
BFCL 的多工具子集与“不可调用”子集提供了可复现的趋势证据。以 2024 年中的公开快照为例,多个主流模型在单工具子集上的准确率高于多工具子集,差距随工具数量增加而扩大(BFCL 官方榜单,2024)。需要说明的是,榜单的具体数值随模型版本与评测集版本频繁更新,本文不引用易过期的绝对值,只引用趋势。本文评述:趋势证据的价值在于指导工程假设,而非给出承诺值;团队应建立自己的内部评测集,用相同方法做纵向对比。
另一类证据来自工具检索研究。ToolLLM 与 Gorilla 均在论文中报告了检索式路由对大规模工具集的有效性,其共同结论是:当工具数量超过数十个时,全量暴露不可行,检索召回是必要前置(Qin et al., 2024;Patil et al., 2023)。本文评述:这些研究的工具规模远大于本文讨论的 15 个,但其机制在 15 个量级同样成立,只是收益曲线更平缓。
4.2 一个模拟的对照实验设计
为说明两类干预的相对贡献,笔者设计一个可复现的模拟实验框架(以下数据为模拟数据,仅用于演示方法,不代表任何真实系统)。设定 15 个工具,其中 4 组近义工具对;构造 600 条请求,按意图分布采样,happy path 占 40%,边界情形占 60%。对照组为全量暴露+原始描述;实验组 A 为检索裁剪至 k=5+原始描述;实验组 B 为全量暴露+重写描述与收紧 schema;实验组 C 为裁剪+重写。评估指标为工具选择准确率、参数合法率、不可调用判别准确率。
| 组别 | 选择准确率(模拟) | 参数合法率(模拟) | 不可调用判别(模拟) |
|---|---|---|---|
| 对照 | 0.71 | 0.78 | 0.66 |
| A 裁剪 | 0.83 | 0.80 | 0.72 |
| B 重写 | 0.79 | 0.89 | 0.70 |
| C 组合 | 0.88 | 0.91 | 0.81 |
模拟结果呈现两个值得注意的模式:裁剪对选择准确率贡献更大,重写对参数合法率贡献更大,组合在不可调用判别上收益最明显。本文评述:这与 3.1 节的熵分析一致——裁剪压上界,重写改形状,不可调用判别依赖描述中的负例边界,故组合收益最大。需要强调,以上为模拟数据,真实系统需自行复现。
4.3 评测集分布校正的实操
针对 happy path 覆盖不足,可操作的做法是:从生产日志按意图聚类,统计各簇请求占比;对评测集做同样的聚类,计算分布差异;对占比高但评测缺失的簇补充用例,优先补充“需要澄清”“多工具竞争”“参数缺失”三类。补充时保留原始用户表述,不要改写成标准问法,否则会引入新的分布偏移。本文评述:评测集的价值在于“代表真实分布”,任何改写都会削弱代表性,这一点常被忽视。
拓展阅读方面,BFCL 的评测代码与数据构造方法公开在 GitHub(Gorilla/BFCL 仓库),MCP 规范见 modelcontextprotocol.io,OpenAI 结构化输出文档见 platform.openai.com。视频类资料可参考 Anthropic 官方频道关于工具使用的讲解(Anthropic YouTube)。
五、对比与局限:裁剪与重写各自的失效边界
5.1 动态裁剪的失效条件
裁剪的第一类失效是召回失败:用户表述与工具描述词汇不匹配,检索阶段漏掉正确工具。第二类是冷启动:新工具缺少调用日志,检索模型无法学习其使用模式。第三类是跨工具任务:一个请求需要多个工具协作,裁剪可能只召回其中一个。第四类是延迟预算:两阶段路由增加一次检索调用,对低延迟场景不友好。本文评述:裁剪的收益随工具数量增长而增大,但在 15 个量级、工具语义区分度尚可时,收益可能不足以抵消其复杂度,团队应先用描述重写做低成本优化,再评估是否引入裁剪。
5.2 描述重写的失效条件
重写的失效主要来自三方面:一是描述长度预算,详细描述挤占上下文,反而降低长上下文利用率(Liu et al., 2024);二是描述与实现漂移,工具行为变更后描述未同步,模型按旧描述调用;三是不可判定的边界,如“适用于复杂查询”这类表述无法指导选择。本文评述:重写的边际收益递减明显,前几轮重写收益大,之后迅速饱和;此时应转向 schema 收紧与评测校正,而非继续堆描述。
5.3 组合策略的适用矩阵
| 场景特征 | 优先干预 | 理由 |
|---|---|---|
| 工具 10–20 个,语义区分度尚可 | 描述重写 + schema 收紧 | 成本低,直接改善分布形状 |
| 工具 50+ 或持续增长 | 检索裁剪 + 重写 | 全量暴露不可行,召回是前置 |
| 近义工具对多 | 命名重构 + 负例边界 | 语义距离是主要矛盾 |
| 参数幻觉高发 | schema 收紧 + 服务端语义校验 | 形状与语义分层治理 |
这张矩阵的核心判断是:干预手段应与主要矛盾匹配,而非追求“最优方法”。本文评述:工程上最常见的错误是在工具只有 12 个时就引入复杂路由,结果召回失败率高于收益;或者在工具已上百时仍靠改描述硬撑,导致上下文爆炸。判断依据应是候选规模、语义区分度、延迟预算三者的组合。
六、可落地操作路径:五步工程法与评估闭环
6.1 第一步:建立分布代表性的评测集
从生产日志采样,按意图聚类,补齐 happy path 之外的边界情形,确保评测集意图分布与真实分布偏差在可接受范围内。评测集需版本化管理,每次工具变更后回归。指标至少包含:选择准确率、参数合法率、不可调用判别准确率、平均调用轮次。
6.2 第二步:先做低成本的描述与 schema 治理
统一描述模板,补负例边界,重命名近义工具,收紧 schema(enum、pattern、required、additionalProperties: false),开启严格模式。这一阶段通常能在不改架构的前提下拿到可观收益,且为后续裁剪提供更干净的语义基础。
6.3 第三步:评估是否需要检索裁剪
以 Recall@k 为核心指标做离线评估:用真实请求构造查询,看正确工具是否进入前 k。若 Recall@5 已接近上限且延迟可接受,再上线两阶段路由;否则先优化检索模型或改用状态机粗筛。上线后监控召回失败率,设置兜底策略(召回为空时回退全量暴露)。
6.4 第四步:服务端语义校验与结构化纠错
在工具执行前做语义校验,返回结构化错误码与可读提示,让模型有机会重试或澄清。错误码应区分“参数缺失”“值非法”“业务规则冲突”三类,便于模型针对性修正。本文评述:这一步是把 schema 的“形状约束”与业务的“语义约束”衔接起来的关键,缺了它,严格模式只能保证格式正确,不能保证业务正确。
6.5 第五步:持续监控与迭代
建立线上指标看板:工具选择分布、参数校验失败率、澄清率、回退率。定期用新日志更新评测集,检测分布漂移。工具新增时走同一套评估流程,避免“加一个工具就崩一片”。
七、结论与展望:走向自适应工具接口
回到标题的问题:动态接口裁剪与描述重写不是二选一。选择熵框架表明,裁剪压低候选集上界,重写改变分布形状,二者作用于不同项,组合才能同时改善选择准确率与参数合法率。工程上的正确顺序是:先做分布代表性的评测,再做低成本的描述与 schema 治理,然后根据 Recall@k 与延迟预算决定是否引入检索裁剪,最后用服务端语义校验兜底。本文评述:这条路径的核心是“按主要矛盾排序”,而非追逐单一最优方法。
展望未来,三个方向值得关注:一是工具接口的自适应化,即模型根据上下文动态生成或组合工具,而非从固定清单中选择,这会从根本上改变选择熵的结构;二是描述与 schema 的自动生成与一致性校验,用工具实现反向生成描述,减少漂移;三是评测方法的标准化,BFCL 等公开榜单已开了头,但企业内部的分布代表性评测仍需自建。笔者认为,工具调用的可靠性最终会从“提示技巧”走向“接口工程”,而接口工程的核心,是把选择问题当作一个可测量、可分解、可迭代的系统问题来对待。
主要参考文献
[1] Qin Y, et al. ToolLLM: Facilitating Large Language Models to Master 16000+ Real-world APIs. ICLR 2024. arXiv:2307.16789.
[2] Patil S G, et al. Gorilla: Large Language Model Connected with Massive APIs. 2023. arXiv:2305.15334.
[3] Liu N F, et al. Lost in the Middle: How Language Models Use Long Contexts. TACL 2024. arXiv:2307.03172.
[4] Berkeley Function Calling Leaderboard (BFCL) 官方榜单与评测代码,2024–2025. https://github.com/ShishirPatil/gorilla
[5] Anthropic. Model Context Protocol 规范,2024. https://modelcontextprotocol.io
[6] OpenAI. Structured Outputs 与 Function Calling 文档,2024. https://platform.openai.com/docs
[7] Anthropic. Tool Use 与提示工程文档,2024. https://docs.anthropic.com
[8] Schick T, et al. Toolformer: Language Models Can Teach Themselves to Use Tools. NeurIPS 2023. arXiv:2302.04761.
[9] Yao S, et al. ReAct: Synergizing Reasoning and Acting in Language Models. ICLR 2023. arXiv:2210.03629.
文章声明:本文内容仅为作者学习、思考、经验、笔记的总结,仅供技术交流与参考。文中观点仅代表笔者个人思辨,不构成任何学术建议、商业建议或专业建议。所有数据来源已标注,引用时请以原始文献为准。
内容仅供学习参考。如需引用,请以原始文献为准。 全文约 7600 字 | 参考文献 60+ 篇(主要列出 9 篇)。

