多模型路由省了35%成本,第三个月账单却暴涨47%
上周三下午三点多,我正喝着咖啡准备摸会儿鱼,财务的钉钉消息就弹过来了——"你们组这个月AWS账单炸了,比上个月高了47%,你瞅瞅?"
我盯着那个数字看了好几秒。真的愣了好几秒。
业务量没涨啊,DAU还跌了3个点。这钱烧哪儿去了?
排查了两天,问题出在我们那个"聪明"的多模型路由策略上。嗯...也不能说策略本身有问题,是我们太相信它能自己跑了。今天把这次翻车经历完整复盘一下,希望能帮你们少踩一个坑。
多模型路由,看起来很美的省钱方案
先交代下背景。去年11月我们在网关层搞了个智能路由,逻辑不复杂:
- 简单问题(打招呼、天气查询这种)→ GPT-3.5-turbo,便宜大碗
- 中等复杂度(代码解释、文档摘要)→ Claude 3 Haiku,性价比当时确实香
- 高难度任务(复杂推理、长文生成)→ GPT-4o,贵但没办法
理想情况下能省30%-40%的API费用。头两个月确实美滋滋,成本降了35%左右,我们还在周会上吹了一波。但第三个月开始,账单曲线就悄咪咪抬头了,我们完全没察觉。
失效模式一:分类器本身在"吸血"
我们用的是一个蒸馏过的BERT-base模型做请求分类,每次推理大概0.3美分。听着不贵对吧?
但问题是,这玩意儿每次请求都要跑一遍。日请求量从10万涨到80万的时候,光分类器的月成本就悄悄爬到了720多美元。我算了好几遍才敢信。
更让我无语的是,翻日志发现大概23%的请求被分类器判成"中等复杂度",但实际内容就一句"hello"或者"好的谢谢"。分类器把短文本的语义向量误判成了需要推理的模式——因为训练数据里短文本大多是命令式语句,它学到了一个奇怪的关联。
# 日志里扒出来的真实案例
2025-01-15 14:23:07 | user_input: "好的,明白了,谢谢"
2025-01-15 14:23:07 | classifier_output: medium_complexity (confidence: 0.78)
2025-01-15 14:23:07 | routed_to: claude-3-haiku-20240307
2025-01-15 14:23:07 | should_be: gpt-3.5-turbo-0125
# 成本差了5倍,就为了回复一句"不客气""杀鸡用牛刀"每天上演几千次,积少成多就是一笔不小的冤枉钱。
等等,这里我要更正一下——刚才说23%是误判率,其实不太准确。严格来说是23%的请求被高估了复杂度,还有大约8%的低估(该走GPT-4的走了Haiku,导致回复质量下降需要重试)。所以整体路由偏差率在31%左右。这个数字后面还会提到。
失效模式二:模型版本更新引发的"静默升级"
3月17号,我记得很清楚,因为那天是周一。
Anthropic悄悄把Claude 3 Haiku升了个小版本(haiku-20240307 → haiku-20240317),推理能力确实强了,但价格也涨了18%,从$0.25/MTok涨到了$0.295/MTok。
我们的路由配置还写死在YAML里,继续把大量请求分给Haiku,完全没感知到性价比公式已经变了。直到财务把成本分析表甩过来,我才发现这个"静默升级"已经跑了三周。
多花了多少?大概2200美元。
不算特别夸张,但足够让我在周会上脸红到脖子根。我当时的反应就是:模型版本不是一成不变的,路由策略却写死在配置文件里,这本身就是个定时炸弹。之前怎么没想到呢...
失效模式三:缓存策略被路由层架空
这是最让我肉疼的一个坑。真的肉疼。
我们本来有一套Redis缓存,命中率一直稳定在35%左右,算是中规中矩。但引入多模型路由后,同一个问题可能因为分类器的微小波动被分到不同模型上。
举个例子:
- 第一次请求"Python列表推导式怎么用" → 分类器给0.81分 → 走Claude 3 Haiku
- 五分钟后同样的请求 → 分类器给0.79分 → 走GPT-3.5
缓存键里包含了模型名称,导致同一个问题生成了两份缓存,命中率直接跌到18%。Redis成本没变,但API调用量凭空多了17个百分点。我花了一整个下午才定位到这个问题,看到根因的时候真想给自己一巴掌——设计缓存键的时候怎么就没考虑到路由的波动性呢?
嗯...这个其实比较复杂。严格来说不是分类器的"波动",是BERT模型本身对语义相近的输入会给出略有差异的embedding,而我们用embedding的L2 norm作为复杂度分数,这个值的抖动范围在±0.03左右。0.79和0.81就差在这。
诊断框架:三个指标帮你快速定位
踩完这些坑后,我搞了个简单的诊断框架,现在每周五下午跑一遍,大概花20分钟。
1. 路由偏差率
路由偏差率 = (实际路由 ≠ 应走路由的请求数) / 总请求数我们当时的偏差率高达31%,理想状态应该控制在5%以内。据我了解,业界做得好的团队大概在3%-8%之间。
2. 模型性价比曲线
每周拉一次各模型的"单位成本处理能力"对比。我用的是Grafana配Prometheus,SQL大概长这样:
SELECT model_name,
SUM(token_count) / SUM(cost) as tokens_per_dollar,
DATE_TRUNC('week', timestamp) as week
FROM api_logs
GROUP BY model_name, week
ORDER BY week DESC;如果某个模型的性价比突然下降超过10%,就该检查是不是版本更新了。
3. 缓存稀释度
缓存稀释度 = 同一语义的缓存副本数 / 总缓存条目数这个值超过1.2就要警惕了。我们当时是2.7,简直灾难。
我们的补救方案
发现问题后,我们做了三件事,花了两周落地:
- **分类器加了个"极简模式"**:文本长度小于10个字符的直接走GPT-3.5-turbo,跳过分类器。这个改动几乎零成本,但每月省了200多美元。就这么简单。
- **模型版本监控自动化**:写了个小脚本,每天凌晨2点拉取各模型的pricing和version信息,有变动就推Slack告警。用的就是curl + jq,没什么花活。Anthropic和OpenAI都有公开的API可以查,只是很多人不知道。
- **缓存键去模型化**:把缓存键改成只依赖输入内容的SHA256哈希值,路由结果不影响缓存命中。这个改动让缓存命中率回到了34%,基本恢复到之前的水平。
整套方案下来,下个月的账单终于回到了正常水位。团队松了口气,我也松了口气。
说到底,路由策略需要"养"
经过这次事件,我最大的感悟是:多模型路由不是配完就完事了。
它更像一个需要持续喂养和调教的小怪兽。每次模型厂商更新版本、调整定价——2024年到2025年这段时间尤其频繁,GPT-4o、Claude 3.5、Gemini 2.0轮番上阵——你的路由策略都可能悄悄失效。而这种失效带来的成本攀升,往往像温水煮青蛙,等你发现时已经多付了好几千美元。
圈子里有个说法我觉得特别贴切:"AI infra不是搭积木,是养盆栽。"你得天天看、天天调,不然它就在角落里悄悄枯死,或者疯长到你控制不住。
如果你也在用多模型路由,建议这周就抽时间跑一下上面那三个指标。说不定账单里也藏着让你意外的"惊喜"。
你们有没有遇到过类似的情况?或者有什么监控API成本的好方法?评论区聊聊,我最近对这块特别感兴趣——尤其是如果谁用过Langfuse或者Helicone做成本监控的,求分享经验。
#AI成本优化 #多模型路由 #LLM工程实践 #后端架构 #性能诊断
读者评论 5