Agent 模型分级升级路由:用置信度阈值把贵模型省下来

Agent 模型分级升级路由:用置信度阈值把贵模型省下来

原文:OpenRouter Blog - 《Confidence Thresholds for Model Escalation Routing》(https://openrouter.ai/blog/insights/confidence-thresholds-for-model-escalation-routing/)

把每个请求都发给最强的模型,答案质量最好,价格也最高------很多请求便宜模型本来就能答对,你却按前沿模型的价格付了钱。按关键词或任务类型写死路由能省钱,但流量一变、模型一升级,规则就得重写。

置信度升级路由是这两者之间的第三条路:让模型先给自己的答案打个分,再用这个分数决定要不要升级。分数高的留在便宜模型上,分数低的转给更强的模型。原文把它拆成五个步骤,这篇按开发者的落地顺序讲一遍,重点放在那个最容易搞错的地方------这个分数到底能当什么用。

一、先分清:置信度分数是什么,又不是什么

原文把这条边界划得很重:这个分数是模型的自述,它生成分数的方式和生成正文一样,因此带着同样的不确定性。

  • 两个相同的分数不保证相同的正确概率:同一个提示词上的 0.85,和另一个提示词、另一个模型给出的 0.85,不能互换;
  • 这个数字不是校准过的概率,0.85 不等于「85% 的概率答对」;
  • 真正能用的是排序。把一批自己的请求跑过便宜模型、人工判对错、按分数分组,如果低分组的错误率确实高于高分组,这个排序就可以拿来做路由;
  • 你要找的不是「等于 90% 正确的那个分数」,而是排序里的那条分界线:线以上的答案可以直接交付,线以下的需要第二次调用。

这条区分是整个方法的地基。把分数当概率用,阈值就失去意义;把它当排序用,它就变成可测量、可调参的工程对象。

二、用结构化输出把置信度变成数字

不要从自由文本里读不确定性。模型不确定时,它的措辞未必含糊,系统也没有一份固定的含糊词表供你解析,靠语言判断迟早翻车。

正确做法是让模型在 schema 约束的响应里返回置信度字段。请求里带上 response_format,类型为 json_schema,同时要求 answer 和一个 0 到 1 的数字 confidence:

json 复制代码
{
  "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
      }
    }
  }
}

上面这段请求体来自原文。里面有三个容易踩的细节:

  1. 0 到 1 的取值范围写在字段的 description 里,而不是用 minimum 和 maximum 关键字。原文解释了原因:Anthropic 的结构化输出文档把数值约束类关键字列为不支持,用 description 描述范围才是跨厂商都能用的写法;
  2. strict 只是向有原生严格模式的服务商请求严格校验。原文提醒,各家的执行力度不一样,有的只把它当强提示,所以路由之前必须自己校验解析出来的 JSON;
  3. 结构化输出能力挂在服务商端点上,不是挂在模型上:同一个模型可能有的端点支持、有的不支持。把 require_parameters 设为 true,请求才会只被送到支持全部参数(包括 response_format)的端点;不设这个标志,response_format 只是一个软偏好,遇上不支持的端点会被直接忽略。

做完这一步,每个响应都带上了代码能直接读取的分数,是否升级从「猜语义」变成了「比大小」。

三、阈值不能抄,要从自己的错误率里量出来

阈值来自你对自己流量的测量,不是从某篇指南里复制一个数字。做法是:拿一批有代表性的请求跑过便宜模型,记录置信度分数和这条答案是对是错,然后把切点放在错误率开始爬升的地方。线以上留在便宜模型,线以下升级。

原文给了一个演示样本(它自己说明这只是算术自洽的示例,不是目标值,你的分布一定不同):

分数区间 请求占比 实测错误率
0.95 到 1.00 41% 1%
0.85 到 0.94 27% 4%
0.70 到 0.84 18% 11%
0.50 到 0.69 9% 34%
低于 0.50 5% 61%

错误率在 0.70 以下陡增,所以 0.70 是候选切点:它升级掉下面两个分段,也就是 14% 的请求,剩下 86% 留在便宜模型上。这个样本里便宜模型的整体错误率接近 10%,把最低的 14% 升级之后,留下来的答案错误率降到约 4%,代价是大约每七个请求多一次调用。

原文的取舍建议很直白:先偏保守。一开始升级过多、之后再放宽阈值,只是多花钱;反过来升级不足,会把自信的错误答案发出去。

四、路由决策要写在你的代码里

原文特别点出一个边界:模型 fallback 只在模型返回错误时触发,不会因为模型返回了一个合法但置信度很低的答案而触发。换句话说,这个决定得你自己做。有两条结构性选择:

  • 在同一个函数里重试:请求先发给便宜模型,读出置信度,低于阈值就把同样的消息发给更强的模型并返回它的答案。升级策略集中在一处,改阈值或换升级目标只改一次,不会出现某个调用点还在用旧策略;
  • 跑一次独立的第一遍:把便宜模型的调用当成第一遍,把它的答案和分数记下来,只有分数低于线时才调更强的模型。代码多一些,但它记录下了便宜模型多久升级一次、它的分数是否仍然和真实错误对齐,这正是后面重新调阈值要用的数据。

下面是按第一种结构写的示意骨架。模型 ID 是字符串,所以两层模型都可以走配置,不必改代码:

python 复制代码
CHEAP_MODEL = "openai/gpt-5.6-luna"   # 便宜层,示例来自原文
STRONG_MODEL = "你的升级目标模型 slug"
THRESHOLD = 0.7                       # 由自己流量的分档错误率量出来

def answer_with_escalation(messages):
    # 第一遍:便宜模型 + 结构化置信度
    first = call_model(CHEAP_MODEL, messages)
    if first["confidence"] >= THRESHOLD:
        return first["answer"]
    # 低于阈值才升级:同样的 messages 交给更强的模型
    second = call_model(STRONG_MODEL, messages)
    return second["answer"]

上面这段是我按原文描述的两个结构补的示意代码,不是原文代码,call_model 的具体实现按你选的 SDK 补上即可。真正要照抄的是它的形状:阈值判断只出现一次,升级目标是一个可替换的标识。

五、上线之后盯三个数字

一个上线时合适的阈值,之后可能就不合适了。原文要求从第一天就记录三件事:

  • 分数分布,模型或流量变化后用它重跑第三节的校准;
  • 升级率随时间的变化;
  • 未升级答案的错误率,这个数字才说明切点还在不在干活。

需要重新调的信号也很明确:换了便宜模型或升级目标(分数分布会变)、流量整体变难或变易(错误率的分档会移动)、成本压力让你愿意用更高的错误率换更低的升级率。

六、三个常见错误

  1. 把自述分数当校准概率。方法成立在排序上,不在字面数值上:把一批答案按分数排序,错的确实挤在低端,但 0.9 不代表这条答案有 90% 的概率正确。阈值应该来自第三节的分档错误率,而不是那个原始数字;
  2. 所有任务共用一个阈值。客服机器人回答「退款政策是什么」和回答「我今天取消会不会被收费」,答错的代价完全不一样。一个全局阈值要么把简单场景升级过头,要么把高风险场景升级不足。知道任务类型的场景,就给每个类型自己的阈值;
  3. 上线后不看升级率。校准批次上合适的阈值,会随着流量漂移或底层模型更新而失配,而这个过程不会报任何错。

小结

置信度升级路由把请求留在便宜模型上,只有当模型自报低置信度时才为更强的模型付钱,而且不需要关键词表或任务类型规则。整条回路很小:用结构化输出逼出数字分数,用自己流量里按分档统计的错误率找切点,选一种跟踪方式(一个函数管策略,或者独立第一遍留下日志),上线后盯住未升级答案的错误率并按变化重调。

对写 Agent 的人来说,这个模式的性价比尤其高。一次 Agent 任务会打出几十次调用,其中大部分是读文件、选工具、拼参数这类窄调用;把它们的置信度接进路由,等于给整条链路加了一层自动的成本闸门,而不必给每种任务提前写好规则。

相关推荐
hsfxuebao1 小时前
Loop Engineering 保姆级教程 + 项目实战
人工智能·后端
晚安code1 小时前
大模型是什么?讲透 Token、上下文窗口、Temperature 和 MoE
人工智能·深度学习·机器学习
xianghongtao01161 小时前
麦肯锡2026技术趋势02_智能体AI_研究解读
大数据·人工智能
AI日报派送佬1 小时前
2026年10月2日AI行业日报|AI监管全面加码,算力基建革新,视觉推理技术突破
人工智能·ai智能体·大模型技术·ai日报·算力基建·ai科研·ai产业落地
数字化顾问1 小时前
(138页PPT)四大咨询矿业集团流程梳理与优化报告(附下载方式)
大数据·人工智能
Navigator_Z1 小时前
LeetCode //C - 1278. Palindrome Partitioning III
c语言·算法·leetcode
liuchangng1 小时前
Agent的state注入
人工智能·agent·jev·决策模型
Godspeed Zhao1 小时前
现代智能雷达技术18——算法(4)
算法
for_ever_love__1 小时前
机器学习入门——手写线性回归与梯度下降
人工智能·python·学习·机器学习·线性回归