跳到正文
原文
OpenRouter:Blog(Announcements)·· 2026-10-01精选AI 评分61

OpenRouter 讲解模型分级路由的置信度阈值设置

Confidence Thresholds for Model Escalation Routing

文章要点
  • 1OpenRouter 给出五步指南,用模型自报的置信度分数在便宜与更强模型间自动分流请求
  • 2指南要求用结构化输出强制返回数值置信度字段,分数只可用作排序、不是校准概率
  • 3阈值用自家流量按分数段错误率定,示例以 0.7 切点把保留答案错误率从约 10% 降到约 4%
  • 4上线后需记录分数分布、升级率和未升级答案错误率,模型或流量变化时重新调校阈值
决策要点

把选模型的决策从固定规则变成用自家错误率数据测量和重调的阈值设置,降本与准确率可以显式权衡

  • 影响:多数请求可留在便宜模型上,只对低置信请求支付第二次调用成本;升级请求多一轮往返会拉高延迟;模型版本或流量构成变化会使阈值失效,需要持续监控重调
  • 参考:可考虑先取一批代表性流量跑便宜模型,按分数段统计错误率找出自己的切点;再按任务类型的出错代价分别设阈值;上线后记录分数分布、升级率和未升级答案错误率以便重调
  • 依据:方法与五步流程来自 OpenRouter 官方指南,文中 200 条请求的错误率表为其自设演算示例,非独立评测结果
正文 · AI 翻译

把每个请求都发给最强的模型能换来高质量的答案,但价格最高,因为那些更便宜的模型本来也能正确回答的请求,你却要按旗舰级费率付费。固定的路由规则,比如按关键词或任务类型选择模型,成本更低,但随着流量的变化需要重新改写。

基于置信度的升级路由介于两者之间。你让模型为自己的答案打分,然后根据该分数进行路由。高分的答案留在便宜的模型上,低分的答案则交给更强的模型。本指南将分五步完成这一设置。

Tl;dr

  • 基于置信度的升级路由根据模型对其自身答案报告的分数来路由每个请求,因此便宜的模型处理它有把握的请求,而更强的模型只看到它没有把握的那些。
  • 用结构化输出强制获得分数。要求包含数值型置信度字段的 JSON schema 能让你从每个模型得到同样的信号,而不是从自由文本中的模糊措辞去猜测。
  • 使用排名而非绝对数值。0.85 并不代表经过校准的 85% 正确概率。请在自己的流量上验证分数较低的答案是否比分数较高的答案更常出错,并据此排序进行路由。
  • 根据自己的数据设定阈值。让有代表性的流量经过便宜的模型,查看每个分数区间的错误率,并把分界点设在错误率攀升之处。
  • 把阈值当作需要定期复查的设置。记录分数分布、升级率和未升级答案的错误率,并在模型或流量变化时重新调优。

Flow diagram of confidence-based escalation. A request goes to the cheap model, which returns an answer and a confidence score. A decision node checks whether the confidence is at or above the threshold. If yes, the answer is returned. If no, the request goes to a stronger model for a second call, and that answer is returned.

置信度分数是什么、不是什么

这个分数是一种自我报告。模型生成它的方式与生成答案其余部分的方式相同,因此它带有同样的不确定性。两个相同的分数并不能保证有相同的正确几率。一个提示词上的 0.85 与另一个提示词或另一个模型上的 0.85 并不可互换,这个数字也不是经过校准的概率。

你能用的是排名——前提是你已经验证过它。把一批你自己的请求经过便宜的模型,对答案进行评分,然后按分数分组。如果较低分数区间的答案比较高区间的答案更常出错,那么即使绝对数值不可用,这种排序依然可以用于路由。你要找的不是等于 90% 正确率的那个分数,而是排名中能把可以直接上线的答案与需要再次调用的答案区分开来的那个点。第 2 步就是这项测量。

第 1 步:用结构化输出获得数值型置信度字段

不要从自由文本中读取不确定性。没有任何机制要求模型在不确定时于行文中使用模糊措辞,也不存在一套固定的模糊词表可供解析。

改为让模型在经过 schema 校验的响应中返回置信度字段,使用结构化输出。你传入一个类型为 json_schema 的 response_format,并要求同时返回答案和一个介于 0 与 1 之间的数值型置信度:

{
  "model": "openai/gpt-5.6-luna",
  "messages": [
    {
      "role": "user",
      "content": "..."
    }
  ],
  "provider": {
    "require_parameters": true
  },
  "response_format": {
    "type": "json_schema",
    "json_schema": {
      "name": "answer_with_confidence",
      "strict": true,
      "schema": {
        "type": "object",
        "properties": {
          "answer": {
            "type": "string"
          },
          "confidence": {
            "type": "number",
            "description": "How likely the answer is correct, from 0 (a guess) to 1 (certain)."
          }
        },
        "required": ["answer", "confidence"],
        "additionalProperties": false
      }
    }
  }
}

现在,无论由哪个模型回答,每个响应都带有路由代码可以直接读取的数值型置信度。决定哪些内容需要升级变成了数字之间的比较,而不是解析语言。

Schema 在字段的 description 中声明 0 到 1 的范围,而不是使用 minimum 和 maximum 关键字。Anthropic 的结构化输出文档将 minimum 和 maximum 等数值约束列为不支持,因此 description 这种写法才是跨提供商通用的做法。strict: true 会要求具备原生严格模式的提供商严格执行 schema。各提供商的执行力度不一,有些把 schema 当作强提示而非保证,因此在依据解析出的 JSON 做路由之前,请先对其进行校验。

在依赖它之前,先做两项检查。第一,结构化输出支持是按提供商端点设置的,而不是按模型设置的,同一个模型可能既由支持的提供商服务,也由不支持的提供商服务。在模型页面上筛选出至少有一个支持端点的模型,并在模型页面的 Providers 部分查看 structured_outputs 参数。第二,在你的提供商偏好设置中设置 require_parameters: true,这样我们只会把请求路由到支持其中所有参数的端点。如果没有这个标志,response_format 只是一个软性偏好。当模型有支持端点时,我们会路由到这些端点;但如果模型的所有端点都不支持,我们仍会发送请求,该参数将被忽略。

第 2 步:根据你自己的错误率设定初始阈值

阈值来自对你自身流量的测量,而不是从指南里照抄一个数字。用上面的 schema 对你的廉价模型运行一批有代表性的请求样本,记录置信度分数以及每个回答是否正确,然后在错误率开始攀升之处设定分界线。高于该线的请求由廉价模型解决。低于该线的请求升级到更强的模型。

起步时要偏保守。一开始过度升级、之后再放宽阈值会多花冤枉钱。升级不足则会发出自信满满的错误答案。

下面是一个完整的示例。假设你用廉价模型运行 200 个有代表性的请求,并按分数段对结果进行分组。下表只是一个算术上自洽的示意,并非目标。你自己的分布会有所不同。

分数段请求占比观测错误率
0.95 至 1.0041%1%
0.85 至 0.9427%4%
0.70 至 0.8418%11%
0.50 至 0.699%34%
低于 0.505%61%

错误率在 0.70 以下急剧攀升,因此 0.7 是候选分界线。0.7 的阈值会使其下两个分数段的请求(占 14%)升级,而让其余 86% 的请求由廉价模型解决。

在这个样本中,廉价模型的总体错误率略低于 10%。把最底部 14% 的请求升级后,你保留的答案的错误率降至约 4%,代价是大约每七个请求中有一个要多调用一次。在自己流量上运行这一步的目的,是找出你自己的分界线,而不是照搬 0.7。

第 3 步:从准确率、成本和延迟三方面调节阈值

阈值是在升级量与错误率之间做权衡。调高阈值,会有更多请求获得第二次调用,这能捕获更多错误,但成本更高、速度更慢。调低阈值,会有更多请求留在廉价模型上,这更快更便宜,但会让更多错误答案漏过去。阈值设在哪里,取决于一个错误答案会给你的产品带来多大代价。有三点因素影响这个选择。

准确率。更高的阈值会让更多处于边缘的答案进入第二次调用,因此出货的错误更少。在这个示例中,把截断值从 0.7 提高到 0.85,也会把 0.70 到 0.84 这一区间纳入升级范围,而该区间的错误率为 11%。升级比例从请求的 14% 上升到 32%,保留答案的错误率从约 4% 下降到约 2%。

成本。每次升级都是一次额外的模型调用,是在你已付费的廉价调用之上的额外开销。具体成本取决于你的廉价模型与升级目标之间的价格差距,以及升级的频率。在确定目标升级率之前,请查看当前的各模型定价。层级之间的差距以及价格本身都会随着新模型的发布而变化。

延迟。被升级的请求需要进行第二轮往返,因此更慢。如果很大一部分流量都被升级,这条慢路径可能会逼近延迟预算。当你的产品有严格的响应时间上限时,这个上限会先于成本或准确率,限制你能升级的请求比例。

Bar chart of escalation share and error rate on kept answers at five cutoffs, computed from the worked-example table. With no escalation, 0 percent of requests escalate and 9.6 percent of kept answers are wrong. At a cutoff of 0.50, 5 percent escalate and 6.9 percent of kept answers are wrong. At 0.70, 14 percent escalate and 4.0 percent are wrong. At 0.85, 32 percent escalate and 2.2 percent are wrong. At 0.95, 59 percent escalate and 1.0 percent are wrong.

该图表将每个候选截断值应用到示例表格上。提高截断值会降低你所保留答案的错误率,同时提高需要为第二次调用付费的流量占比。这三个因素并非独立变动。为了准确率而提高阈值,总会增加升级部分的成本和延迟,因此合适的阈值是你的错误容忍度、预算和响应时间限制三者交汇之处。

第 4 步:在你的代码中路由低置信度请求

阈值设定后,由你的代码来做升级决策。它读取 confidence 字段,当分数低于这条线时,就把请求发送给更强的模型。我们不会替你做这个调用。我们的模型回退只在模型返回错误时触发,而不是在它返回置信度分数较低的有效答案时触发。有两种方式来构建这个决策。

在同一个函数中重试。把调用封装在一个函数里。将请求发送给便宜的模型,读取置信度,如果低于阈值,就把同样的消息发送给更强的模型并返回该答案。升级策略集中在一处,因此当你更改阈值或升级目标时,只需修改一次,任何调用点都不会再沿用旧的决策。

运行单独的第一遍。把便宜模型的调用视为第一遍。记录它的答案和分数,然后仅在分数低于这条线时才调用更强的模型。这需要更多代码,但它会记录便宜模型的升级频率,以及其分数是否仍与真实错误相符,这正是你在第 5 步中重新调优所依据的数据。

模型 ID 是字符串,因此你可以通过配置而非代码来更改任一层级。在选择便宜模型和强力模型时,请浏览我们的模型目录,因为随着新模型的发布,每一层级的正确选择也会随之变化。

你可以在上述两种模式中任一种之下叠加错误故障转移。传入一个 models 数组,当列表中的第一个模型返回错误时,调用便可故障转移到列表中的下一个模型。默认情况下,任何错误都可以触发回退,包括提供商宕机、速率限制、被过滤模型的审核标记,以及上下文长度验证错误。我们按最终回答请求的模型计价,并在响应的 model 字段中返回该模型。这是一种与置信度升级相互独立的机制。它在出错时触发,而不是在有效的低置信度回答时触发,因此两者可以组合使用。回退让每次调用都保持有效,而你的阈值决定一个有效的回答何时需要更强的模型。

第 5 步:在生产环境中监控并重新调整

上线时合适的阈值可能会变得不再合适。从第一天起就记录三件事。

  • 分数分布,这样当模型或流量发生变化时,你可以重新执行第 2 步的校准。
  • 升级率随时间的变化。
  • 未升级回答的错误率,这个数字能告诉你分界线是否仍在发挥作用。

情况发生变化时重新调整。把廉价模型或升级目标换成新版本会改变分数分布。流量向更难或更简单请求的偏移会移动你的误差区间。成本压力可能促使你接受更高的错误率以换取更低的升级率。阈值是一个需要你随着这些变化不断调整的设置。

常见错误

把自报分数当作经过校准的概率。这种方法的作用在于排序,而不是字面意义上的似然。按分数对一批答案排序,错误的答案会集中在低端,但 0.9 并不意味着答案在 90% 的情况下是正确的。请根据第 2 步中按区间统计错误率的练习来设定阈值,而不是根据原始数字。

对所有任务类型使用同一个阈值。回答“你们的退款政策是什么”的支持机器人,与回答“我今天取消会被收费吗”的支持机器人,答错所付出的代价并不相同。单一的全局分界线会在简单情形下过度升级,或在有风险的情形下升级不足。在你了解任务类型的地方,为每种类型设定各自的阈值。

上线后不关注升级率。适合你校准批次的阈值,可能随着流量变化或底层模型更替而不再适合,而且不会有任何错误提示告诉你这一点。

结论

基于置信度的升级让请求在模型报告高置信度时留在廉价模型上,只有在它不报告高置信度时才为更强的模型付费,且无需关键词或任务类型规则。整个流程很精简。用结构化输出强制生成一个数值型置信度字段。根据你自己按分数区间统计的错误率来找到分界线,而不是随意挑一个数字。选择符合你跟踪方式的路由模式——用一个函数实现策略,或者为第一轮单独记录日志。然后在上线后观察未升级回答的错误率,并随着模型和流量的变化进行调整。

常见问题

什么是置信度阈值?

置信度阈值是一个分数界限,低于该界限时,你会把请求发送给更强的模型,而不是接受廉价模型的回答。高于界限时,答案按原样交付;低于界限时,请求被升级。这条界限应根据你自己的错误率数据来设定,而不是使用默认数字。

AI 中的置信度分数是什么?

置信分数是一个数字,通常介于 0 到 1 之间,模型在给出答案的同时报告它,以表明自己有多确定。这是一种自我报告,而不是经过校准的概率,因此 0.9 并不意味着有 90% 的概率是正确的。你能测量并依赖的是其排序关系。在一批你自己的请求上,先检查低分答案的出错频率是否高于高分答案,然后再依据分数进行路由。

设置置信阈值最可靠的方法是什么,从而让轻量级模型处理大多数请求,只在其置信度较低时才转交给高端模型?

用你自己的流量来衡量它。让轻量级模型运行一个有代表性的请求样本,记录每个置信分数以及答案是否正确,并按分数区间对结果进行分组。把阈值设在错误率急剧攀升的位置。这样,高于这条线的所有请求都由轻量级模型处理,只有低于这条线的低置信请求才会交给高端模型。先从保守的设置开始,然后一边观察你所保留答案的错误率,一边进行调整。

如何从小模型自动升级到前沿模型?

让小模型通过结构化输出返回一个数值型的置信字段,然后由你的代码根据它来路由。当分数低于你的阈值时,把同一个请求发送给前沿模型,既可以在同一个函数中内联完成,也可以作为显式的第二次调用。OpenRouter 的模型回退是一项单独的功能。它们会在提供商宕机或速率限制等错误发生时把调用切换到另一个模型,而不是在置信分数低的时候切换,因此请把这两种机制区分开来。

参考资料

来源:OpenRouter:Blog(Announcements) · openrouter.ai