机制层的 function calling 评测
大多数 function calling eval 只报告一个数字:准确率。这个数字是模型做出的至少四种不同决策的复合结果,而它们失败的原因不同、修复的位置不同、需要的 oracle 也不同。只报告单一分数的 harness 告诉你出了问题,却不告诉你问题在哪。
四种决策,一个数字
- 工具选择(selection):可用函数中哪一个匹配当前意图。在 schema 重叠或描述含糊时失败。
- 参数填充(fill):把正确的值放进正确的槽位。在单位不匹配、别名、信息缺失时失败。
- 调用判断(judgment):立即调用、追问一个澄清问题,还是拒绝。在过度急切的调用(未确认就扣款)与调用不足(从不行动)时失败。
- 多步链式调用(chaining):状态跨调用携带,第二次调用依赖第一次的结果。在状态丢失、冗余调用、顺序错误时失败。
一个模型可以擅长选择与填参,在生产环境中的调用判断与链式调用上却毫无用处。benchmark 必须把它们分开,否则修复闭环是盲的。
确定性判定与 LLM 裁判
两类 oracle。
确定性检查把发出的调用与参考标准比对:结构用 AST 匹配,运行时行为用可执行评测,后置条件用状态比对。便宜、可复现、没有裁判方差。问题在于:oracle 把语义编码了进去,所以你只能测到你编码过的东西。
LLM 裁判给自由格式的行为打分,用在正确动作本身就是一次判断的场合,例如「agent 是否问对了澄清问题?」。灵活,但会漂移,而且有成本。永远不是第一选择;永远是残余类别。
最好的 harness 把两者分层:语义可检查的地方用确定性判定,只有逃出其范围的部分才交给 LLM 判断。
精读:BFCL
Berkeley Function Calling Leaderboard 是事实上的标准,到 2026 年年中,V4 已是一次 agentic 评测。BFCL 论文(ICML 2025)描述了核心:可扩展到数千个函数的基于 AST 的评测、专家精选加用户贡献的函数,以及对弃答的显式测试:在有状态的多步设置里,没有函数合适时模型应当拒绝调用。
版本史就是这个领域的历史。V1 引入了针对简单、并行与多重调用的 AST 评分。V2 加入了企业与社区贡献的函数。V3 加入了多轮、多步调用,模型与用户来回交流,包括提出澄清问题。V4 是一次整体性的 agentic 评测:网页搜索、记忆读写与格式敏感度,全部用 AST 或状态转移检查做确定性验证。
在这段历史里跨版本比较数字之前有一句提醒:V4 的 agentic 转向使 V1 到 V3 的分数比较失效,因为早期版本拿固定 schema 给单次调用打分,而 V4 给一个带网页搜索与记忆的完整循环打分,所以 V4 分数更低可能意味着更弱的 agent,而不是更弱的调用方。
它的类别清单已经把机制层编码在内:多个函数中选哪一个(selection)、参数正确性(fill)、miss-function 与 miss-parameter 这类弃答类别(judgment:没有任何匹配或必填参数缺失时,不要幻觉出一次调用),以及多轮基础用例(chains)。这个 benchmark 家族本质上就是一套失败模式分类,而 miss 类别之所以存在,是因为那些正是生产中要紧的失败。
精读:tau-bench
tau-bench 是一个面向真实世界领域中工具–agent–用户交互的 benchmark(Yao, Shinn, Razavi, Narasimhan, 2024)。零售与航空客服。一个模拟用户与持有领域专属 API 工具和政策准则的 agent 进行动态对话。
关键在于它的评分方式。它不给单次调用打分,而是把对话结束时的数据库状态与标注的目标状态做比对。预订是否发生、航班是否正确、是否在正确的政策之下?调用级准确率只是代理指标。状态相等才是 agent 是否完成任务的真值。
pass^k 指标度量重复试验下的可靠性,结论很直白:gpt-4o 在低于 50% 的任务上成功,零售域的 pass^8 低于 25%。一次通过的准确率高估了生产就绪度;agent 在不同运行中以不同方式失败。
tau-bench 说的正是:机制层的评测意味着评测整条链,而不是一个个链环。
精读:ToolSandbox
ToolSandbox(Lu et al.;Findings of NAACL 2025)在有状态、对话式、交互式的设置中评测工具使用:带工具间隐式依赖的有状态工具执行、用于 on-policy 评测的内置用户模拟器,以及对中间与最终里程碑的动态评测。
它的任务类别干净地映射到那四种决策。状态依赖:一个工具的输出改变下一次调用必须做什么(chaining)。规范化:用户说「那个蓝色的」,agent 必须把这个别名解析成确切的参数(fill)。信息不足:agent 必须识别出自己无法行动,转而提问(judgment)。
我从中拿走的设计点是里程碑,而不只是最终状态。最终状态检查告诉你 agent 失败了;中间里程碑告诉你它在链上的哪一环失败。这就是机制层。
给四种决策打分
一个 harness 带四个分项分数,每种决策一个:
selection which function, among N
fill argument correctness per call
judgment call / ask / refuse, plus timing
chain state consistency across calls
确定性 oracle 优先:fill 用 schema 校验,selection 用重叠测试,chains 用 tau-bench 式的状态 diff。LLM 判断只保留给残余部分,配上固定的评分细则和一份留出的人工样本,用来审计裁判本身。
设计笔记:一个零售域的 harness
我在 PiPlan.ai 设计过一个零售域的内部 function calling 评测 harness,带一套 12 类失败模式分类——仅为设计考量,无公开指标。
分类体系先于任何数据集,驱动它的是三条考量。
每个类别必须能指向一个修复位置:提示词、schema、工具路由、策略文件或工具实现。指向不了修复的类别只是装饰。
类别必须互斥,标注才便宜,计数才有意义。如果一个失败有可能同时落进两个类别,标注者就会分歧,分类体系的计数也随之失去意义。
零售是政策密集的领域:定价、库存、配送约束。要紧的失败很少是格式错误的 JSON,而是 JSON 正确但动作错误:确认前就扣款、执行政策禁止的折扣、用户同意前就占用库存。调用判断占主导,这正是分类体系的类别需要多于选择与填参的原因。
分类体系与判定策略是同一个设计。结构化字段用确定性检查,判断类失败用评分细则。按类别报告计数胜过一个准确率数字,因为一个数字无法告诉你该修哪一层。至于它在更大的 harness 图景中的位置,见agent 分类体系总览。
本文所链接的来源均已抓取并核验。