返回博客列表

Agent 调错工具 vs 传错参数:OpenRouter 工具调用准确性测试指南翻译

2026-10-01T10:30:00+08:00
OpenRouter工具调用Tool CallingAgent评测EvalJSON Schema轨迹比较

Agent 调错工具 vs 传错参数:OpenRouter 工具调用准确性测试指南翻译

选错工具和选对工具传错参数,是两种不同的病——用同一种测试去查,等于两种都查不准。

昨天翻译了 OpenRouter 的 Agent 回归测试指南,今天这篇是它的姊妹篇:《How to Test Tool-Calling Accuracy in AI Agents》(9 月 30 日发布),聚焦工具调用准确性——Agent 评测里最核心、也最容易测错的一环。

文章开篇的区分就很见功力:Agent 用工具时会在两个地方失败——选错工具,或者选对工具却传错参数。这两种失败告诉你不同的事情:调了 lookup_order 而不是 refund_order,问题在工具选择;调了 refund_order 但 order_id 传错了,工具选对了、参数错了。混在一起测,诊断不出病因。

老规矩,忠实翻译全文结构,文末附我的解读。

本文提纲

  1. 核心摘要(Tl;dr)
  2. 两种失败模式:工具选择与参数正确性
  3. 方法一:无参考 LLM judge
  4. 方法二:确定性 schema 检查
  5. 方法三:轨迹比较
  6. 跨模型跑同一套 eval
  7. 四个常见错误
  8. 翻译后的几点解读

核心摘要

五条关键规则:

  • 工具选择和参数正确性分开测。Agent 可能选错工具、调了不必要的工具,或选对工具却传错参数。
  • 知道预期的工具或参数值时,用确定性检查;正确性依赖上下文或多个选择都可能合理时,用无参考 LLM judge。
  • 用 JSON Schema 抓畸形或结构非法的参数,参数值单独检查——schema 合法的值仍然可能是错的。
  • 调用序列本身是需求时,用轨迹比较。如果多条路径都能到达同一个有效结果,别要求精确序列。
  • 跨模型比较时,测试用例、评分规则、模型设置和路由配置对每个候选都保持一致。

两种失败模式:工具选择与参数正确性

先看工具决策本身,再检查模型产生的调用。

工具选择(Tool selection)

假设一个客服 agent 可用三个工具:lookup_order、issue_refund、search_docs。用户问退款政策是什么,search_docs 是合适的选择;用户要求退订单 ord_7281,agent 可能需要先查订单再退款。

no-tool case 至关重要:你的测试集还要包含模型已经拥有足够信息、不应该调用任何工具的 case。原因很实际:只检查响应里有没有 tool_calls 是不够的——一个调了不必要函数的模型照样会产生 tool call。

比对方式分两种:一个工具明显是预期答案时,在代码里把返回的工具名和预期比对;多个工具都可能合理解决问题时,精确匹配会错杀合法选择。

参数正确性(Argument correctness)

模型选好工具后,检查它生成的参数。这个检查分两部分:结构和值。

  • 结构校验抓:畸形 JSON、缺失必填字段、类型错误、非法枚举值、工具不接受的参数。
  • 但结构合法的调用仍可能值是错的:order_id 定义为字符串,那么传 ord_7282 完全满足 schema——可如果用户问的是 ord_7281,它就是错的。

这个"结构与值分开"的划分不是 OpenRouter 的独创——DeepEval 早就把 Tool Correctness 和 Argument Correctness 做成两个独立指标,Phoenix 也有独立的 tool selection evaluator。三大平台在这一点上高度一致。

方法一:无参考 LLM judge

无参考(reference-free)judge 不依赖固定预期答案来评分。适用场景:正确性取决于上下文,或者多个选择都可能合理——这种时候你根本没有一个可以精确匹配的"正确答案"。

工具选择上:给 judge 用户的请求、agent 可用的工具列表、模型的输出,让它判断所选工具是否合适。例子:一个研究 agent 同时有 web_search 和 search_internal_docs——可能没有唯一正确的选择,更好的工具取决于用户问了什么、对话里已有什么信息。

参数上同样:搜索 query、描述、日期范围可能完全符合 schema,却没能表达用户的意思。没有固定值可以断言时,judge 是唯一选择。

三个使用要点:

  • 无参考 judge 仍需要清晰的"什么算对"的指令。
  • 对比候选模型时,judge 的指令和 judge 模型本身要固定,并检查 judge 的一致率。
  • 如果相等检查、schema 校验器或业务规则能可靠回答同一个问题,用它们替代 judge——能用代码解决的事别花模型的钱。

方法二:确定性 schema 检查

不是每个参数错误都需要再调一次模型。工具 schema 能证明的失败,在代码里验证。

一个精妙的设计:你发给模型的那个工具 schema,正好可以用来验证它返回的参数。教程用 jsonschema 的 Draft7Validator 处理:

tools = [{
    "type": "function",
    "function": {
        "name": "lookup_order",
        "description": "Look up an order by its ID.",
        "parameters": {
            "type": "object",
            "properties": {
                "order_id": {"type": "string"},
                "include_items": {"type": "boolean"}
            },
            "required": ["order_id"],
            "additionalProperties": False
        }
    }
}]

它能抓住:缺 order_id、include_items 传了字符串、或者塞了一个未声明的字段(additionalProperties: False 时像 customer_email 这种会被拒绝)。

但要记住边界:schema 合法 ≠ 值正确。结构检查是必要条件,不是充分条件。

方法三:轨迹比较

工具选择和参数检查覆盖单次调用。多步 agent 还可能在调用序列上失败——当序列本身是需求的一部分时,用轨迹比较。

例子:退款工作流要求三个调用按序执行:lookup_order → verify_refund_eligibility → issue_refund。

但严格匹配只在顺序真的是需求时使用。教程给了两个参照:

  • LangSmith 的轨迹评估器支持 strict(严格序列)、unordered(无序)、subset(子集)、superset(超集)四种匹配模式——strict 强制唯一序列,其他模式接受不同排序或只要求包含特定调用。
  • τ²-bench(agent 基准)的做法更聪明:把录制的动作列表当作一条参考轨迹,回放它推导出一个目标数据库终态——任何能产生等价终态的工具调用序列都算通过。这从根本上回答了"多条路径到达同一结果"的判定问题:不比路径,比世界状态。

跨模型跑同一套 eval

测试用例和评分器定义好之后,同一套 harness 可以跑每个候选模型。OpenRouter 对支持的模型暴露统一的工具调用接口——换模型不需要重写 provider 集成。

教程给了完整可运行的 Python 示例(openai SDK + jsonschema),要点:

  • tool_choice: "auto" 显式设置——这是提供 tools 时的默认值,显式写出让 no-tool 测试更清晰。
  • 测试用例带 expected_calls:包括"已知订单"(期望调 lookup_order 且 order_id 为 ord_7281)和**"无需工具"**(expected_calls: [])。
  • 三个候选模型跑同一组 case:anthropic/claude-opus-5、openai/gpt-5.6-sol、moonshotai/kimi-k3。

四个常见错误

工具调用 eval 在测试用例或评分规则太窄时,会给出误导性结果。教程列了四个最常见的坑:

  1. 只测干净请求。要包含信息缺失的请求、相似工具的干扰、不应该调用任何工具的情况,以及模型应该反问而不是编造参数的 prompt。
  2. 只检查 tool_calls[0]。一个响应可能包含多个调用——评整个数组。
  3. 把合法 payload 当成正确 payload。schema 验证无法告诉你一个合法的值是不是对的客户、订单、日期或金额。
  4. 在模型之间改 eval。工具、prompt、judge、模型设置或路由策略在两次运行之间变了,你就不是在做同一个比较了——这是昨天那篇回归测试指南的核心规则,在这篇里再次强调。

翻译后的几点解读

"选错工具"和"传错参数"的分诊价值,怎么强调都不过分。 我见过太多团队的"工具调用准确率 87%"这种单一数字——它混着两种病:选错工具该查工具描述和命名(还记得我们 MCP 设计指南里说的 camelCase 命名和 use_case 描述吗),传错参数该查 schema 设计和上下文注入。混在一起,你连该改哪里都不知道。

"发出去的 schema 就是验收标准"是个漂亮的架构对称。不用维护第二套校验规则——发给模型什么 schema,就用什么 schema 验收它的返回。additionalProperties: False 加上这个对称性,幻觉字段无处遁形。但一定要记住教程划的边界:schema 管结构,值需要单独的业务校验。

τ²-bench 的"终态比较"是轨迹评估的正确进化方向。严格序列匹配会把等价路径判为失败(你的 agent 用了两次搜索找到了和参考轨迹一次搜索同样的结果——这算失败吗?)。比较"世界状态"而不是"动作序列",才是对 agent 能力的公平度量。LangSmith 的四档匹配模式是同一个思想的工程化。

no-tool case 是最容易被忽略的测试。只测"该调工具的请求"会漏掉一类真实事故:agent 在不该动手时动手了——用户只是问"已发货是什么意思",它调了 lookup_order。教程特意强调"检查响应里有没有 tool_calls 不够",因为多余的调用照样产生 tool_call 结构。

到这里,OpenRouter 这组教程三部曲(回归测试、工具调用准确性、黄金评测集构建)已经把"改了 prompt/换了模型怎么验证"的工程闭环讲完整了。加上本站之前拆过的 DeepEval 六指标、微软 ai-agent-evals、LangChain Jev 评测——Agent 评测这件事的工具和方法论,2026 年已经齐了。剩下的只是:你的 case 集建了没有。

参考链接

你的 Agent 上次传错参数是什么时候发现的——用户投诉,还是测试报警?评论区聊聊,觉得有用点个赞让更多做 Agent 的人看到。


作者: itech001 来源: 公众号:AI人工智能时代(the-ai-era) 网站: https://www.theaiera.top/ 关注每日最新AI新闻和技术博客,主页有更多的文章的AI 技术参考:https://www.theaiera.top

本文首发于 AI人工智能时代,转载请注明出处。

分享给朋友