数据来自一次真实的企业内部试点,已脱敏:不含客户名称、行业、内部结构与代码。
开头:一个看起来很像"提示词问题"的现象
团队带着两个失败用例来:用户说要"生成一份 HTML 报告"、"读取这个文件",模型什么工具都没调。
他们的第一判断是:是不是中文描述丢了语义?
三轮对照实验之后,这个假设被否掉了。真正的两个根因都不在"提示词写得好不好"这一层。
现象:不是选错,是一个都不选
基线套件:6 个工具 / 9 条用例(含 1 条负例)。选择准确率 78%。
两条失败长这样:
| 用例 | 期望工具 | 实际 |
|---|---|---|
| 生成一份 HTML 报告 | create_html_report | 不调用 |
| 读取这份文件 | file_read | 不调用 |
这类失败在只看准确率的评分卡上就是两个叉,但在线上它叫"助手装死"。
假设一:语言问题 —— 被证伪
把 6 个工具的描述从英文换成中文,套件、模型、用例、温度全不动:
| 变量 | 选择准确率 | 失败形态 |
|---|---|---|
| 英文描述(基线) | 78% | 同两组工具,不调用 |
| 中文描述 | 67% | 同两组工具,不调用 |
而且中文描述比英文更短——顺带排除了"描述变长导致信息稀释"。
结论:语言只是描述的一种变体,不是这组失败的主因。
这一步很关键。如果跳过控制变量,最可能的动作是去反复改写提示词,然后发现毫无改善。
根因一:required 参数,模型根本拿不到
文件类工具都有一个 required 的 session_id(UUID)。它不在用户输入里,描述里也没说从哪来。
模型面对"必须填、但永远填不对"的参数,最优策略就是不调用。它不是不懂,是在规避必错。
验证方式:只在用户输入里补上会话 ID,其他一律不改——
| 工具 | 补会话 ID 前 | 补会话 ID 后 |
|---|---|---|
file_read | 不调用 | ✅ 正确调用 |
file_saver | 不调用 | ✅ 正确调用 |
create_html_report | 不调用 | ❌ 误选邻居 |
一个"参数来源"上的修复,直接救回三分之二。
这条规则可以静态检查:required 参数如果既没有在 description 里说明来源,也不像用户会自然提供的内容(UUID、租户 ID、trace ID、环境标识),就应该报警——"模型可能拒绝调用"。
根因二:能力边界与邻居重叠
create_html_report 的描述是"根据文本文件生成报告"。补上会话 ID 后它仍然失败,但形态变了:从"不调用"变成误选 file_read。
原因很清楚:"读文件"和"根据文本文件生成报告"共享了核心动词和宾语。这不是"没写触发时机",是区分度不足。
修法不是再堆形容词,而是在描述里明确写出互斥边界:不适用于什么。
这里有个容易踩的坑:lint 里"两个工具描述相似度 0.50"这类告警只能发现"像",发现不了"该不该像"。真正该问的是——用户会不会混淆这两个工具? 会,就必须把边界写进描述。
方法:评测的价值在归因,不在分数
三轮实验,每轮只改一个变量(语言 / 参数来源 / 描述边界),套件与模型全程不动。
如果只跑两次、看到 78% 掉到 67%,最自然的结论是"中文不好用"。而这个结论是错的。
同一套件 + 单变量对照,才让"分数"变成"原因"。我们做评测工具的初衷也是这个:分数只是入口,归因才是产出。
一个常被忽略的缺失:负例
上面两个失败能暴露出来,靠的是套件里那条 expectedTool: null 的负例,以及一组语义相近的工具。
只测"选对了没有"的套件,会把"该调用却没调用"混进未命中里,淹在一堆分数中看不出形状。"该不该调用"必须单独成为一类用例,建议占全部用例 20% 以上。
顺手复现这套实验
# 1. 先看你的工具集是否有"不可推断的 required 参数"
mf lint --suite mf.suite.json
# 2. 看负例占比与疑似混淆对
mf coverage --suite mf.suite.json
# 3. 同一套件跑两个变体(例如中/英描述),只改一个变量
mf eval --suite mf.suite.json --models internal-ds --show-cases
工具仍然是 modelfunction-cli(命令 mf):本地运行、无遥测、Key 只走环境变量,--models-file 可以直接接内网 OpenAI 兼容网关。
结论
三条可带走的经验:
- "不调用"是一种失败模式,而且往往源自参数不可推断,不是模型笨;
- 相邻工具的区分度要写"不适用于",而不是堆形容词;
- 先做归因再谈分数——控制变量比调提示词便宜得多。
如果说这次试点有什么超出预期的收获,就是这句:评测工具真正的价值,不是给你一个分数,而是让"为什么"变成可以验证的问题。