模型调度与降级层
小的先上,大的兜底。
实时
- −64%单位成本,同口径
- 91.9%一次命中率
- 11ms调度自身开销 p95
Switchyard 是一层中间件,横在你的应用和你付钱的每一家模型之间。请求出门前先打分,交给能过你质量下限的最便宜那一档;过不去的往上抬一级,上游抽风的横着绕开。
数字为示意性建模结果,非实测。
- 01一个请求,带编号。走到它该去的那一档就离开画面。
- 04被升级的。道岔打开,包往上抬一级,编号还是那个编号。
- 一条轨流得多快,就是这一档占多少流量。这里没有一样东西是装饰。
02 — 为什么是现在
同一个问题,43.0倍的价差。
十八个月里,能拿去做生产的通用档位翻了两番还多,同一个答案的价格也跟着拉开。选型不再是上线前拍一次板的事,它变成了每个请求都要重做一次的决定。
- 9 → 31可用于生产的通用档位只用供应商中立代号,从这段窗口起点算到现在
- 43.0×最便宜的一档到最贵的一档同一个问题,每一档的输入输出长度都一样
- 6默认阶梯的级数缓存、自托管、小型、中型、旗舰、旗舰深推理
03 — 问题
押一个模型,就是赌。
把所有档位放到同一批没分过难度的流量上测,结论永远是「只能买最贵的」。于是例行请求也按旗舰价付钱。这张图本身没错,错在它把难题和废话装进同一个桶里测。
一个中等规模的 AI 客服 + 文档问答产品(示意)
| 三笔没人单列的账 | 值 |
|---|---|
| 过度供给:例行请求也走旗舰 | $52,300 |
| 重试黑洞:失败与截断的重跑 | $4,900 |
| 上游抖动:限流期间的排队与超时重发 | $2,100 |
| 真正必要的旗舰调用 | $27,200 |
| 合计 | $86,500 |
过度供给是大头。重试和上游抽风这两笔,从来不会出现在任何一张模型对比表里 —— 对比表一次只测一条调用,这两笔要攒够一个月才看得见。
而你押中的那一档一旦开始限流,你没有第二选择可以退,你只有一条队。
04 — 难度指纹
十毫秒,五个维度,一个分数。
指纹只回答一个问题,而且赶在请求出门之前回答:这条有多难。五个维度,固定权重,合成一个分数。不看用户是谁,不看历史,只看这一条请求本身。
- 5 / 9 / 14 毫秒延迟(p50 / p95 / p99)
- $0.00003每次调用成本
- 0.71与人工标注一致性(κ)
- 84.1%分档准确率(按流量加权)
四个难度带
| 难度带 | 区间 | 流量份额 |
|---|---|---|
| D1例行 | D < 25 | 42% |
| D2常规 | 25–55 | 34% |
| D3复杂 | 55–80 | 19% |
| D4高风险长链 | D ≥ 80 | 5% |
- 规模
- 60M 编码器,自托管
- 微调集
- 1,200,000 条打标请求
打分的是一个自托管的小编码器,所以「这条该走哪」这件事,不需要先把请求发出去才知道。
它会判错。判低的那部分由阶梯接住;判高的那部分就是白花的钱,这个数我们照实印出来,不抹平。阈值调紧,浪费变小,升级率跟着上去 —— 这个旋钮在你手里。
- 欠路由
- 判得比实际低一档以上。这部分由阶梯接住——它是升级的主要来源。
- 过路由
- 判得比实际高一档以上。这部分没人接:钱白花了,约占账单 11%。
05 — 路由预算
预算不是报表,是约束。
每个端点自己声明一个每千次调用的美元上限,路由器在这个上限里面求解。余量见底时,整条阶梯当天下压一级。没有「钱花超了再发封邮件」这一步。
每个决定都是这棵树上的一条路径,而这棵树是能读的。每个请求都带着它走这条边的理由:落在哪一带、哪条规则触发、最后拿到哪一档。
有四条旁路规则可以盖过这棵树:格式严的强制走带结构校验的档;事实敏感的禁用最小那档;预算余量不够的整条阶梯下压;容易被拒答的并行跑两档,取先到而且过了下限的那个。
各端点的预算与实测
美元 / 千次调用
| 端点 | 质量下限 | 预算 | 实测 | 余量 |
|---|---|---|---|---|
| /chat客服对话 | 裁判分 p10 ≥ 74 | $4.20 | $2.81 | 33% |
| /docqa文档问答 | 裁判分 p10 ≥ 78 | $5.50 | $4.22 | 23% |
| /extract结构化抽取 | 结构通过率 ≥ 99.0% | $4.80 | $3.68 | 23% |
| /review合同与代码审阅 | 裁判分 p10 ≥ 84 | $9.60 | $8.65 | 10% |
在这个示意部署里预算是硬上限,四个端点都跑在各自的上限以内。
06 — 降级阶梯
出问题要横着倒,不要竖着塌。
一条阶梯就是一串有序的级:模型档、参数、提示版本、触发条件、最长等待。超时、报错、结构校验没过、裁判分低于下限,请求就往下一级走。同一条阶梯,上行下行都走得通。
- 91.9%一次命中率8,455 / 9,200
- 8.1%触发阶梯745 / 9,200
- 1.4%升级抖动< 2.0%
阶梯的代价
阶梯的代价是延迟。中位数会明显往下掉,因为大多数请求本来就不需要旗舰档;最远那截尾巴反而略微变差,因为升级过的请求跑了两跳。这笔账我们认,也画在图上了。
如果某个端点吃不起这条尾巴,就让它并行跑两档,为扔掉的那一档付钱。
| 分位 | 基线 | 调度后 | 变化 |
|---|---|---|---|
| P50 | 2,265ms | 955ms | −58% |
| P75 | 3,532ms | 1,927ms | −45% |
| P90 | 5,911ms | 4,223ms | −29% |
| P95 | 7,545ms | 7,257ms | −4% |
| P99 | 13,332ms | 13,511ms | +1% |
07 — 质量下限
下限你定,不是我们定。
每个端点自己声明一条下限:裁判分的 p10,或者结构化输出的通过率。这条线不参与交易 —— 省钱只能在它上面那段余量里省。
- −2.3整体裁判分89.1 → 86.8
- +2.8尾巴反而是往好里走的p5 68.4 → 71.2
尾巴反而是往好里走的
整体裁判分掉了两分多,我们没打算藏。但分布最烂的那一头反而变好了:有了下限,最差的那批答案会被强制重做一遍 —— 单档架构根本不知道它们烂,因为它没有任何东西可以拿来比。
| 口径 | 整体裁判分 |
|---|---|
| 基线:全量走旗舰档 | 89.1 |
| 调度后:只算首选档 | 85.8 |
| 调度后:算上阶梯 | 86.8 |
| 档位 | D1 例行 · 42% | D2 常规 · 34% | D3 复杂 · 19% | D4 高风险 · 5% |
|---|---|---|---|---|
| C-0 | 88.2 | 85.0 | — | — |
| S-1 | 86.8 | 79.4 | 66.1 | 51.8 |
| M-2 | 89.1 | 86.1 | 76.3 | 63.2 |
| L-3 | 90.4 | 89.8 | 87.9 | 78.6 |
| L-3R | 90.6 | 90.2 | 89.4 | 85.4 |
20%
/review · 合同与代码审阅
参考部署里有一个端点几乎没省下什么,这恰恰是对的:它的下限本来就贴着能服务它的那几档的天花板,根本没多少余量可省。
08 — 单位答案成本
按答案算账,别按 token 算账。
分母是被你的产品真正采纳的回答。分子里含重试、升级时被丢掉的低档调用、裁判评分、分类器摊销、影子重放。按 token 出的账单,把这些全藏起来了。
- −64%单位成本,同口径$10.81 → $3.88
- −53%账单$86.5k → $40.4k
- +30%调用量(百万)8.0 → 10.4
其中三项是我们自己吃掉的:升级浪费、影子重放、分类器摊销。我们照样把它们列出来 —— 不列,账面就会比现实好看,那是 PPT 赢过现实的老办法。
图上两条线,一条是实际付掉的账,一条是同样的流量继续全量走单档会付的账。两条线之间那块面积,就是这个产品的全部论据。
单位答案成本
| 口径 | 单位成本 | 采纳率 | 单位答案成本 |
|---|---|---|---|
| 基线 | $10.81 | 94.1% | $11.49 |
| 调度后 | $3.88 | 94.6% | $4.11 |
11%
过路由
判得比实际高一档以上。这部分没人接:钱白花了,约占账单 11%。
09 — 影子重放 · 切换窗口
新档位要先在影子里活够久。
一小部分真实流量会被复制一份,离线喂给候选档。这些回答不返回给任何人,只用来更新质量分和置信区间。
- 3%影子重放312,000 / mo
- 5,0005,000 条影子样本2–4 d
- ±0.6置信区间下界不差过 0.5 分σ ≈ 22
一个候选档要穿三道门才能变成默认:同端点的影子样本够多、连续天数够长、置信区间的下界不比现任差太多。三道门都过了也不是一把切过去,放量分三段走。
三道门
- 5,000 条影子样本
- 同一个端点上的 5,000 条。不是全站凑 5,000——端点之间不通用。
- 连续 7 天
- 足够装下一个周末和一个周一,这两者长得完全不一样。
- 置信区间下界不差过 0.5 分
- 95% 区间的下界,不得比现任档低 0.5 分以上。
样本门槛不是谁挑了个整数,而是置信区间刚好收窄到「差半分不再是噪声」的那个位置。
档位 · 状态
C-0 复用层, H-1 指纹 / 兜底, S-1 D1 主档, S-2 D1 长文, M-2 D2 主档, M-3 /extract 候选, L-3 D3 主档, L-3R D4 主档(输出≈3×), X-9 2026-06 移出
档位也会出去。上个季度提上来几个,回滚一个,下架两个。一个只进不出的调度层,不是在维护阶梯,是在收藏阶梯。
5% → 25% → 100%然后才放量
10 — 有损可用 · 立场
宁可灯光变暗,不要全城断电。
上游限流或者直接躺了的时候,端点自动压到低档、砍掉输出上限、关掉顶档,继续出答案。一个降了质的回答,总好过一个错误页。
- 31.4%上游失败率upstream 5xx+429 > 8% over 60s
- 1.1%用户侧错误率检出耗时 40s
- 41.2%来自有损档的应答整体裁判分 86.9 → 81.6
示意事件里,上游失败率冲到两位数,用户那一侧的错误率几乎没动。代价就印在旁边:相当一部分回答来自降级档,整体裁判分在事故持续期间一直压着。检测时间按秒算,不是按工单算。
触发规则:上游 5xx 与 429 在 60 秒内超过 8%。
/chat 与 /docqa 顶档由 L-3 换到 M-2,输出上限 1024 → 512,关闭 L-3R
我们不做的五件事
- 不训练、不托管模型权重(除一个自用的 8B 分类/兜底档)
- 不做公开评测榜,不发布任何点名厂商的质量对比
- 不保留提示与输出正文——默认只留指纹、路由决策、指标;正文留存需你显式开启
- 不替你决定质量下限;下限是你的产品决定,不是我们的默认值
- 不做锁定:阶梯配置是纯文本,导出即可在没有我们的情况下继续跑
每一条都让我们少赚一点,所以才值得写下来。
我们也会直接说什么时候别买:只有一个端点、只用一个模型、月支出本来就不大,或者你的下限已经贴着能服务它的那几档的天花板。 看我们的立场