
文章目录
-
- [1. 结论先行](#1. 结论先行)
- [2. 环境信息](#2. 环境信息)
- [3. 为什么路由的第一性原理是"价格升序遍历"](#3. 为什么路由的第一性原理是"价格升序遍历")
- [4. 核心代码:路由 + 降级 + 预算](#4. 核心代码:路由 + 降级 + 预算)
- [5. 运行结果:一个工作日的账单](#5. 运行结果:一个工作日的账单)
- [6. 可视化:三层架构与一天的账单](#6. 可视化:三层架构与一天的账单)
- [7. 预算闸:最后一道保险](#7. 预算闸:最后一道保险)
- [8. 踩坑与避坑](#8. 踩坑与避坑)
- [9. 总结](#9. 总结)
- 参考链接
1. 结论先行
"API 要涨了:留下、换模型还是上路由?"------这句话里最值钱的词是"路由"。用一整个工作日的 12 个任务实测一个成本感知路由器:同样的活,全用旗舰模型要 1200 个归一化成本单位,路由后只花 276,省 77% 。方法是朴素的三层结构:mini=8 / mid=30 / flagship=100,按价格升序找"最便宜的能胜任档位",复杂度标签由应用侧打------faq reply 落 mini、contract review 才配旗舰。
比省钱更重要的是中间发生的一次事故:旗舰模型过载(429/overloaded),路由器把一个 complex 任务降级到 mini 跑完 ------但打上了显式的 DEGRADED 标记。降级不是错误,是交易:用质量换可用性,必须留下记录。这篇把路由、降级、预算闸三件事一次讲完。
2. 环境信息
- Python 3.13,只用标准库(无任何 LLM SDK),零第三方依赖;matplotlib 出图
- 价格:归一化相对值(旗舰 = 100),不写死任何厂商单价------官方调价不影响结论,比例关系(3-12 倍价差)才是路由的套利空间
- 诚实边界:dry-run 模拟路由决策与过载事件,未打真实 API;复杂度标签在生产环境可由小模型自动打
3. 为什么路由的第一性原理是"价格升序遍历"
多数人的路由器写法是"if 复杂就旗舰 else 简单档"------这个方向反了。正确的原语是:按价格从小到大遍历档位,第一个"能胜任且预算内"的就是答案。这样写有三个好处:新加一档(比如 mini-mid 之间再来一档)不用改逻辑;能力矩阵变了(某档升级到能处理 complex)路由自动受益;漏掉哪个分支一眼就能看出来。
能力矩阵是业务判断:mini 只放简单任务(分类、抽取、格式化),mid 覆盖日常生成(摘要、邮件、问答),flagship 留给真正吃推理的(合同审查、代码迁移)。这张能力表是路由器里唯一的"业务假设",其他全是机械逻辑------调路由就是调这张表。
4. 核心代码:路由 + 降级 + 预算
python
TIERS = {
"mini": {"price": 8, "handles": {"simple"}},
"mid": {"price": 30, "handles": {"simple", "standard"}},
"flagship": {"price": 100, "handles": {"simple", "standard", "complex"}},
}
ORDER = ["mini", "mid", "flagship"] # cheapest -> priciest
def cheapest_capable(need, budget_left, exclude=frozenset()):
for tier in ORDER:
if tier in exclude:
continue
if need in TIERS[tier]["handles"] and TIERS[tier]["price"] <= budget_left:
return tier
return None
def route(task, budget_left, overloaded):
need = task["complexity"]
tier = cheapest_capable(need, budget_left, exclude=overloaded)
if tier is not None:
return {"tier": tier, "status": "routed",
"cost": TIERS[tier]["price"]}
# nothing capable & available fits: allow an explicit DEGRADED run
weak = cheapest_capable("simple", budget_left, exclude=overloaded)
if weak is not None:
return {"tier": weak, "status": "DEGRADED",
"cost": TIERS[weak]["price"]}
return {"tier": None, "status": "REJECTED", "cost": 0}
route 只有两个出口值得注意:routed(能力与预算都满足)和 DEGRADED ------后者是旗舰过载时的显式取舍:用 mini 跑 complex 任务,质量会掉,但流程不断。降级必须带标记 ,不然三周后排查"为什么这批输出质量不行"时,日志里查不到任何异常。这段路由骨架可直接抄进任何多模型项目,建议收藏备用。
5. 运行结果:一个工作日的账单
id task tier status cost
1 faq reply mini routed 8
2 meeting summary mid routed 30
3 contract review flagship routed 100
4 classify ticket mini routed 8
5 email draft mid routed 30
6 translate snippet mini routed 8
7 code migration mini DEGRADED 8
8 extract date mini routed 8
9 qa over doc mid routed 30
10 sentiment tag mini routed 8
11 report outline mid routed 30
12 format cleanup mini routed 8
total routed: 276 | all-flagship: 1200 | saved 77%
DEGRADED runs: 1 | REJECTED: 0
三个读数:任务 3 (合同审查)是全天唯一真正需要旗舰的活,100 单位花在了刀刃上;任务 7 (代码迁移)撞上旗舰过载,被降级到 mini------它跑完了,但结果质量需要抽查,这就是 DEGRADED 标记的用途;mini 承担了 6/12 的任务量却只花了 48 单位------日常工作流里大多数请求本来就轮不到旗舰。
6. 可视化:三层架构与一天的账单


第一张是架构:任务带着复杂度标签进路由器,按价格序分派到三层,预算闸在出口。第二张是逐任务成本:全部柱子都压在旗舰虚线(100)之下,红色那根是过载期的 DEGRADED。这两张图值得一起收藏------给老板解释"为什么接了路由器输出质量没降、账单降了 77%"时,一张架构一张账单就够了。
7. 预算闸:最后一道保险
路由解决"单次怎么选",预算闸解决"一天花多少":每次路由前检查 budget_left,不足时连 mini 都买不起就 REJECTED。进阶做法是软预算------余量低于 20% 时自动收紧路由(standard 也降级到 mini 跑),把"账单超支"变成"输出降级",让成本失控在发生前被看见。预算数字要和归一化价格同一量纲,别让一个用美元一个用抽象单位。硬预算拒绝、软预算降级,两者选哪个取决于业务:内部工具选软(可用性优先),对客系统选硬(成本优先)------先定这个,再写路由。
8. 踩坑与避坑
| 踩坑 | 后果 | 避开姿势 |
|---|---|---|
| 从旗舰往下找"第一个够格的" | 简单任务全被旗舰吃掉 | 价格升序遍历,取第一个能胜任的 |
| 过载降级不打标记 | 质量事故无从排查 | DEGRADED 显式状态,输出可追溯 |
| 复杂度标签让模型自己打 | 打标本身要花钱、还可能打错 | 应用侧规则打标;复杂场景用 mini 打标 |
| 价格表写死厂商数字 | 调价日全线失效 | 归一化指数,比例关系才传进路由 |
| 预算单位不统一 | 闸门形同虚设 | 预算与价格同一量纲,闸前先换算 |
这张表建议收藏------五条里四条来自真实路由器项目的返工记录。
9. 总结
涨价的正确回应不是焦虑,是架构:让每个任务去它该去的档位,让降级可见,让预算有闸。12 个任务的实测把"上路由"从一句口号变成可验证的账单------77% 的节省不靠压缩输出质量,靠的是承认一个事实:大多数请求根本不需要旗舰模型。
代码、价格矩阵、降级策略全部可复现,换成你自己的任务分布重跑一遍就有自己的数字------路由器的好处是每一条决策都有理由,账单和解耦一样清楚。这篇也收录进「CodingPlan·八月创作之星博客挑战赛」收官批次。
本文为原创技术实践;价格为归一化相对值(旗舰=100),比例关系参考主流厂商公开定价的量级;dry-run 未调用真实 API,不构成任何采购判断。
参考链接
- Anthropic 官方文档 - Errors(overloaded / 429 语义):https://docs.anthropic.com/en/api/errors
- Anthropic 官方文档 - Models overview(档位与定价结构):https://docs.anthropic.com/en/docs/about-claude/models
- OpenAI 官方文档 - Production best practices(多模型与降级):https://platform.openai.com/docs/guides/production-best-practices
