跳到正文
OpenRouter Blog·· 4 天前精选AI 评分62

OpenRouter 发布基于置信度阈值的模型升级路由指南

Confidence Thresholds for Model Escalation Routing

AI 导读

OpenRouter 发布指南,介绍用置信度阈值做模型升级路由:让模型通过结构化输出返回 0 到 1 的置信度分数,高分请求留在便宜模型,低分请求升级到更强模型。

推荐理由

OpenRouter 给出置信度升级路由的五步落地方法,含结构化输出取分、按自身流量定阈值和上线后重调。

正文 · AI 翻译

把每个请求都发给你最强的模型,能以最高价格获得不错的回答,因为你会为那些更便宜的模型本可正确回答的请求支付前沿模型的价格。固定路由规则,例如按关键词或任务类型选择模型,成本更低,但需要随着流量变化而重写。

基于置信度的升级介于两者之间。你让模型给自己的回答打分,然后根据该分数进行路由。得分高的回答留在便宜的模型上。得分低的回答则交给更强的模型。本指南用五个步骤来实现这一点。

简而言之

  • 基于置信度的升级根据模型为其自身回答报告的分数来路由每个请求,因此便宜的模型处理它有把握的请求,而更强的模型只会看到它没有把握的请求。
  • 用结构化输出强制给出分数。一个要求数值型置信度字段的 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 等数值约束列为不支持,因此描述形式才是跨提供商通用的做法。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 步:在代码中路由低置信度请求

阈值设定后,由你的代码做出升级决策。它读取置信度字段,当分数低于阈值时,将请求发送给更强的模型。我们不会替你做出这个决定。我们的模型回退会在模型返回错误时触发,而不是在模型返回有效答案但置信度分数较低时触发。有两种方式可以组织这一决策。

在同一函数中重试。将调用包装在一个函数中。将请求发送给廉价模型,读取置信度,如果低于阈值,则将相同的消息发送给更强的模型并返回该答案。升级策略集中在一处,因此当你更改阈值或升级目标时,只需更改一次,不会有任何调用点继续沿用旧决策。

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

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

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

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

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

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

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

常见错误

把自报分数当作校准过的概率。该方法依赖的是排序,而不是字面意义上的可能性。按分数对一批答案排序,错误答案会聚集在低端,但 0.9 并不意味着答案有 90% 的概率是正确的。请根据第 2 步中按分数区间统计错误率的练习来设定阈值,而不是根据原始数字。

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

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

结论

基于置信度的升级让请求在廉价模型自报高置信度时留在廉价模型上,只在它不自报高置信度时才为更强的模型付费,无需关键词或任务类型规则。这个循环很小。用结构化输出强制一个数值型置信度字段。根据你自己按分数区间统计的错误率来找到阈值,而不是随便挑一个数字。选择适合你想要追踪方式的路由模式,一个函数承载策略,或为第一遍单独记录日志。然后在上线后关注未升级答案的错误率,并随着模型和流量的变化进行调整。

常见问题

什么是置信度阈值?

置信度阈值是一个分数,低于它时你就把请求发送给更强的模型,而不是接受廉价模型的答案。高于这条线,答案就按原样发布。低于它,请求就升级。你根据自己错误率数据来设定这条线,而不是用一个默认数字。

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

置信度分数是模型在给出答案的同时报告的一个数字,通常在 0 到 1 之间,用来表示它有多确定。这是一种自我报告,而不是经过校准的概率,所以 0.9 并不意味着有 90% 的概率是正确的。你能够衡量并依赖的是它的排序。在你自己的请求批次上,在依据分数进行路由之前,先验证得分较低的答案比得分较高的答案出错更频繁。

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

用你自己的流量来衡量。让一批有代表性的请求通过轻量模型,记录每个置信度分数以及答案是否正确,并按分数区间对结果进行分组。把阈值设在错误率急剧上升的位置。这样轻量模型处理该线以上的每个请求,只有线以下低置信度的请求才会交给高级模型。先保守设置,然后在观察你所保留答案的错误率时再进行调整。

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

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

参考资料

来源:OpenRouter Blog · openrouter.ai