1. 一个反直觉的数字背后:AI 成本结构正在被重写
第一次看到“56% 的 Token 只花了 14% 的钱”这个说法,我的反应是:这要么是统计口径有问题,要么就是某个特定场景下的极端个例。但仔细拆开来看,这个数字其实指向了一个正在发生的结构性变化——AI 应用的竞争重心,正在从“用哪个模型”转向“怎么调度模型”。
先把概念说清楚。Token 是大模型处理文本的基本单位,你可以粗略理解成“字”或“词片段”。你每次调用 AI,不管是让它写一段代码、翻译一句话,还是做一个多轮对话,背后都是在消耗 Token。而“路由”这个词,在 AI 语境里,指的是在请求到达模型之前,先判断这个请求该交给哪个模型处理——是交给最贵最强的旗舰模型,还是交给便宜够用的小模型,或者干脆用规则引擎直接处理掉。
这个标题想表达的核心意思是:在一个设计良好的 AI 系统里,真正需要动用“大模型”的请求可能只占一小部分,大部分请求可以用更轻量的方式解决。于是出现了这样一个结果——超过一半的 Token 消耗发生在低成本路径上,而它们只贡献了总成本的很小一部分。
这件事为什么值得聊?因为它直接关系到每一个在做 AI 应用的人的钱包。我见过太多团队,一上来就全量接旗舰模型,结果月底账单出来直接傻眼。也见过一些团队,花了两周时间做路由层,成本直接砍掉一半以上,效果几乎没有下降。这个差距,就是“模型思维”和“路由思维”的差距。
这篇文章适合谁看?如果你正在做 AI 应用开发、AI Agent 搭建、或者任何需要调用大模型 API 的产品,不管你是刚入门还是已经踩过一些坑,这篇内容应该都能给你一些可以直接抄作业的思路。如果你只是对 AI 成本结构好奇,那也可以当做一个行业观察来看。
2. 为什么“路由”突然变得比“模型”更重要
2.1 模型能力的差距在缩小,但价格的差距没有
过去两年,大模型领域有一个非常明显的趋势:第一梯队的模型能力差距在缩小,但价格差距依然巨大。旗舰模型每百万 Token 可能收几十块甚至上百块,而一些中等规模的模型可能只要几块钱,小模型更是便宜到可以忽略不计。
这就带来一个很现实的问题:如果你的任务只是“判断用户这句话是正面还是负面情绪”,你真的需要动用最强的旗舰模型吗?显然不需要。一个经过微调的小模型,或者甚至一个基于规则的分类器,就能做到 95% 以上的准确率,而成本只有旗舰模型的几十分之一。
但问题在于,很多团队在技术选型的时候,习惯性地“用最好的”。这本身没错,但“最好的”不等于“最合适的”。路由的核心价值,就是让合适的请求找到合适的模型。
2.2 一个请求的“难度”分布是极度不均匀的
我做过一个统计,在一个典型的 AI 客服场景里,用户请求的难度分布大概是这样的:
| 请求类型 | 占比 | 适合的处理方式 | 相对成本 |
|---|---|---|---|
| 简单问候、固定问答 | 约 40% | 规则匹配或缓存 | 接近零 |
| 常见问题、标准流程 | 约 30% | 小模型或微调模型 | 低 |
| 需要一定推理的咨询 | 约 20% | 中等模型 | 中 |
| 复杂问题、多轮推理 | 约 10% | 旗舰模型 | 高 |
你看,真正需要旗舰模型的请求只有 10% 左右。但如果你不做路由,所有请求都走旗舰模型,那你的成本就是“用 100% 的旗舰价格处理 100% 的请求”。而做了路由之后,你只用旗舰价格处理那 10% 的请求,剩下的 90% 用更便宜的方式解决。
这就是“56% 的 Token 只花了 14% 的钱”的底层逻辑——不是 Token 变少了,而是 Token 的“单价”被路由策略重新分配了。
2.3 路由不是简单的 if-else,而是一套决策系统
很多人听到“路由”,第一反应是“不就是写几个 if-else 判断一下吗”。如果你只是做最简单的规则路由,那确实不难。但真正有价值的路由系统,需要考虑的东西远不止这些。
一个完整的路由决策,至少需要回答以下几个问题:
- 这个请求的意图是什么?是问答、创作、代码生成,还是工具调用?
- 这个请求的难度有多大?是需要简单检索,还是需要多步推理?
- 这个请求对延迟敏感吗?用户是在实时对话,还是在后台批处理?
- 这个请求对准确性要求有多高?是随便聊聊,还是涉及关键决策?
- 当前各个模型的负载和可用性如何?有没有模型在限流或故障?
这些问题,有些可以用规则回答,有些需要用小模型来分类,有些甚至需要用统计模型来预测。路由本质上是一个“元决策”问题——它不直接解决问题,而是决定“谁来解决问题”。
3. 拆解一个可落地的 AI 路由系统:从规则到模型
3.1 第一层:规则路由,处理最确定的那部分
规则路由是最简单、最可靠、成本最低的一层。它的核心思想是:对于那些有明确模式、不需要理解语义的请求,直接用规则处理掉。
比如:
- 用户输入“你好”“在吗”“谢谢”这类寒暄,直接返回预设回复,不调用任何模型。
- 用户输入的内容命中某个 FAQ 的精确匹配或模糊匹配,直接返回缓存答案。
- 用户请求的是固定格式的输出(比如“把这段文字翻译成英文”),可以直接走专门的翻译模型,而不是通用旗舰模型。
这一层的实现非常简单,用正则表达式、关键词匹配、或者简单的字符串相似度算法就能搞定。但它的收益非常大——在很多场景下,这一层能拦截掉 30% 到 50% 的请求。
注意:规则路由的关键不是“规则多”,而是“规则准”。我见过一些团队写了一堆规则,结果误判率很高,反而把简单问题复杂化了。规则路由的原则是:宁可漏过,不可错杀。不确定的请求,交给下一层处理。
3.2 第二层:小模型分类器,判断请求的“难度等级”
规则处理不了的请求,进入第二层。这一层的任务是:用一个轻量级模型,判断这个请求应该交给哪个级别的模型处理。
这个分类器不需要很复杂。你可以用一个几百兆的小模型,甚至可以用一个基于 embedding 的相似度匹配方案。它的输出不是最终答案,而是一个“路由标签”——比如“简单”“中等”“复杂”。
我自己的做法是,用一个开源的小模型(比如 1B 到 3B 参数级别的),在少量标注数据上做微调,让它学会区分请求的难度。标注数据不需要很多,几百到几千条就够用了。关键是标注标准要清晰——什么是“简单”,什么是“复杂”,要有明确的定义。
这个分类器的准确率不需要追求 99%,80% 到 90% 就够了。因为即使分类错了,后面的模型也能兜底。而且分类错误的成本很低——把一个简单请求分给大模型,只是多花了一点钱;把一个复杂请求分给小模型,大不了重新路由一次。
3.3 第三层:模型路由,把请求分发给最合适的模型
有了难度标签之后,就可以做模型分发了。这里有几个策略可以选择:
策略一:按难度分级
这是最直观的策略。简单请求走小模型,中等请求走中等模型,复杂请求走旗舰模型。每个级别对应一个模型池,池子里可以有多个模型做负载均衡。
策略二:按成本预算动态调整
如果你的预算是固定的,可以设置一个“成本水位线”。当本月成本消耗过快时,自动把更多请求路由到便宜模型;当成本充裕时,可以适当放宽到更好的模型。
策略三:按延迟要求分级
实时对话场景对延迟敏感,可以优先路由到响应快的模型;后台批处理场景对延迟不敏感,可以路由到更便宜但稍慢的模型。
策略四:按置信度回退
先让小模型尝试回答,如果小模型的输出置信度低于某个阈值,再自动升级到大模型重新处理。这种策略在保证效果的同时,能最大化地利用小模型的低成本优势。
这几种策略可以组合使用。我自己的系统里,用的是“难度分级 + 置信度回退”的组合——先按难度路由,小模型回答后如果置信度不够,再自动升级。
3.4 第四层:缓存与复用,让重复请求不再花钱
路由系统还有一个容易被忽视的收益点:缓存。很多请求其实是重复的,或者高度相似的。如果每次都要重新调用模型,那就是在重复花钱。
缓存的粒度可以很细:
- 精确缓存:完全相同的请求,直接返回缓存结果。
- 语义缓存:语义相似的请求,返回最接近的缓存结果。
- 片段缓存:对于长文本处理,可以缓存中间结果,避免重复计算。
语义缓存是这里面最有技术含量的。你需要把请求转换成 embedding,然后在向量数据库里做相似度检索。如果相似度超过某个阈值,就直接返回缓存结果。这个阈值需要根据场景调——太高了命中率低,太低了可能返回不准确的结果。
我实测下来,在一个客服场景里,语义缓存能额外拦截 15% 到 20% 的请求,而且用户几乎感知不到差别。
4. 实操:从零搭建一个最小可用的路由系统
4.1 技术选型与架构设计
先说技术选型。路由系统本身不需要很重的技术栈,核心就是几个组件:
| 组件 | 作用 | 推荐方案 |
|---|---|---|
| 规则引擎 | 处理确定性请求 | 正则 + 关键词匹配,自己写就行 |
| 分类器 | 判断请求难度 | 小模型微调,或 embedding + 相似度 |
| 向量数据库 | 语义缓存 | 轻量级方案即可,不必上重型集群 |
| 路由决策 | 综合决策 | 规则 + 打分函数,自己实现 |
| 监控告警 | 观察路由效果 | 日志 + 简单看板 |
架构上,我建议把路由层做成一个独立的服务,放在业务逻辑和模型调用之间。这样业务代码不需要关心路由细节,只需要把请求发给路由服务,路由服务返回结果。
这样做的好处是:路由策略可以独立迭代,不影响业务代码。你今天用规则路由,明天想换成模型路由,只需要改路由服务,业务代码一行不用动。
4.2 关键参数的计算与选择
路由系统里有一个核心参数:难度阈值。也就是说,什么样的请求算“简单”,什么样的算“复杂”。
这个阈值不能拍脑袋定,需要用数据来算。我的做法是:
- 先收集一批真实请求,人工标注它们的难度等级。
- 用分类器对这批请求做预测,得到每个请求的“难度分数”。
- 画出难度分数的分布图,找到自然的分界点。
- 根据成本预算和效果要求,微调分界点。
举个例子,假设难度分数是 0 到 1 之间的连续值。你发现 0 到 0.3 的请求用小模型处理,准确率能达到 95%;0.3 到 0.7 的请求用中等模型,准确率 93%;0.7 以上的请求用旗舰模型,准确率 96%。那你的阈值就可以设在 0.3 和 0.7。
但这里有一个权衡:阈值设得越低,越多请求走小模型,成本越低,但效果可能下降;阈值设得越高,越多请求走大模型,效果更好,但成本上升。你需要根据业务场景来定——如果是客服场景,效果下降一点可能可以接受;如果是医疗或法律场景,那就要保守一些。
4.3 一个具体的路由决策流程
下面是我自己系统里的路由决策流程,用伪代码表示:
def route_request(request): # 第一层:规则匹配 if match_faq(request): return cached_answer(request) if is_greeting(request): return greeting_response() # 第二层:语义缓存 cache_result = semantic_cache_lookup(request) if cache_result and cache_result.similarity > 0.92: return cache_result.answer # 第三层:难度分类 difficulty = classifier.predict(request) # 第四层:模型路由 if difficulty < 0.3: model = "small-model" elif difficulty < 0.7: model = "medium-model" else: model = "flagship-model" # 第五层:调用模型 response = call_model(model, request) # 第六层:置信度回退 if response.confidence < 0.6 and model != "flagship-model": response = call_model("flagship-model", request) # 第七层:写入缓存 semantic_cache_store(request, response) return response这个流程看起来简单,但每一步都有讲究。比如语义缓存的相似度阈值,我设的是 0.92,这是经过多次调整后找到的平衡点。太低会返回不准确的结果,太高则命中率太低。
再比如置信度回退的阈值,我设的是 0.6。这个值也需要根据场景调——如果你的场景对错误容忍度低,可以设高一点,比如 0.8;如果对成本更敏感,可以设低一点,比如 0.4。
4.4 监控与迭代:路由系统不是一次性的
路由系统上线之后,最重要的事情是监控。你需要知道:
- 每个层级的拦截率是多少?
- 分类器的准确率如何?
- 缓存命中率是多少?
- 回退率是多少?
- 整体成本下降了多少?
- 用户满意度有没有变化?
这些指标需要做成看板,每天看。如果发现某个指标异常,就要及时调整。
我自己的经验是,路由系统上线后的第一个月,需要频繁调整参数。之后进入稳定期,可能每周只需要看一次。但永远不要觉得路由系统可以“一劳永逸”——用户的请求模式在变,模型的价格和能力也在变,路由策略必须跟着变。
5. 常见问题与排查技巧实录
5.1 分类器误判怎么办
分类器误判是路由系统最常见的问题。表现是:简单请求被分到了复杂模型,或者复杂请求被分到了简单模型。
排查思路:
- 先看误判的分布。是某一类请求集中误判,还是随机误判?
- 如果是集中误判,说明分类器的训练数据里这类样本太少,需要补充。
- 如果是随机误判,可能是分类器的特征不够,需要增加特征或换更好的分类器。
我的经验是,分类器的准确率不需要追求极致,但误判的代价要可控。也就是说,即使分类错了,系统也要能兜底。比如简单请求分到了大模型,只是多花钱,不影响效果;复杂请求分到了小模型,可以通过置信度回退来补救。
5.2 缓存命中率低怎么办
缓存命中率低,通常有几个原因:
- 相似度阈值设得太高。可以适当降低阈值,但要注意观察返回结果的准确性。
- 缓存的数据量太少。需要积累更多的请求-响应对。
- 请求的多样性太高。如果用户请求非常分散,缓存的效果自然有限。
我自己的做法是,先设一个相对宽松的阈值(比如 0.88),然后观察一段时间。如果发现返回结果不准确的比例上升,再调高阈值。这是一个动态平衡的过程。
5.3 模型调用失败或超时怎么办
路由系统需要处理模型调用失败的情况。常见的失败包括:限流、超时、服务不可用。
处理策略:
- 重试:对于超时或临时性错误,可以重试一次。但要注意重试的次数和间隔,避免雪崩。
- 降级:如果旗舰模型不可用,可以降级到中等模型,并在响应中标注“降级处理”。
- 熔断:如果某个模型连续失败,可以暂时把它从路由池里移除,等恢复后再加回来。
这些策略需要在路由层实现,而不是在业务层。业务层只需要知道“请求成功了”或“请求失败了”,不需要关心背后的模型切换。
5.4 成本下降但效果也下降了怎么办
这是最需要警惕的情况。成本下降是好事,但如果效果下降太多,就得不偿失了。
排查思路:
- 先看效果下降发生在哪些请求上。是简单请求还是复杂请求?
- 如果是简单请求,说明小模型的能力不够,需要换一个更好的小模型,或者调整阈值。
- 如果是复杂请求,说明分类器把复杂请求误判成了简单请求,需要调整分类器。
我的原则是:成本优化不能以牺牲核心体验为代价。如果某个场景的效果下降超过了可接受范围,宁可多花点钱,也要保证效果。
5.5 常见问题速查表
| 问题 | 可能原因 | 排查方法 | 解决思路 |
|---|---|---|---|
| 分类器误判率高 | 训练数据不足或特征不够 | 看误判分布 | 补充数据或换分类器 |
| 缓存命中率低 | 阈值太高或数据太少 | 看命中率趋势 | 调阈值或积累数据 |
| 模型调用失败 | 限流、超时、服务不可用 | 看错误日志 | 重试、降级、熔断 |
| 成本下降但效果下降 | 阈值太激进或小模型能力不足 | 看效果下降的请求类型 | 调阈值或换模型 |
| 路由延迟高 | 分类器或缓存查询慢 | 看各层耗时 | 优化分类器或缓存方案 |
6. 路由之外:AI 成本优化的其他思路
6.1 Prompt 优化:让每次调用都更高效
路由解决的是“谁来处理”的问题,而 Prompt 优化解决的是“怎么处理更高效”的问题。一个精简、清晰的 Prompt,能显著减少 Token 消耗。
比如,很多人写 Prompt 喜欢堆砌大量背景信息,但其实很多信息对当前任务并不必要。把 Prompt 当成代码来优化——去掉冗余,保留核心,能省不少 Token。
6.2 流式输出与增量处理
对于长文本生成任务,流式输出不仅能提升用户体验,还能在用户提前终止时节省 Token。如果用户看到一半就不想看了,你可以直接停止生成,剩下的 Token 就不用花了。
6.3 批处理与异步化
对于不要求实时响应的任务,可以攒一批请求一起处理。很多模型对批处理有折扣,而且批处理能更好地利用模型的计算资源。
6.4 模型微调:让小模型干大模型的活
如果你有足够的标注数据,可以考虑微调一个小模型,让它在特定任务上达到接近大模型的效果。这样你就可以把更多请求路由到微调后的小模型上,成本会进一步下降。
微调的成本主要在数据标注和训练上,但一旦完成,推理成本会大幅降低。对于高频、固定的任务场景,微调是非常划算的。
7. 我踩过的坑和一点个人体会
做路由系统这两年,踩过的坑不少。最大的一个坑是:一开始太追求“完美路由”,结果系统复杂到没人能维护。
我最初的设计里,有七层路由决策,每层都有复杂的规则和模型。结果上线之后,出了问题根本不知道是哪一层的问题,排查成本极高。后来我砍掉了三层,只保留最核心的四层,系统反而更稳定了。
第二个坑是:忽视了冷启动问题。路由系统需要数据来训练分类器和积累缓存,但系统刚上线时没有数据。我的做法是,先用规则路由跑一段时间,积累数据,再逐步引入分类器和缓存。不要一上来就上全套,那样很容易翻车。
第三个坑是:没有做好降级预案。有一次旗舰模型服务出现波动,所有复杂请求都失败了,但我的路由系统没有降级策略,导致整个服务不可用。后来我加了降级逻辑,旗舰模型不可用时自动切到中等模型,虽然效果差一点,但至少服务是可用的。
一点个人体会:路由系统的价值不在于技术有多先进,而在于对业务的理解有多深。你需要知道你的用户在想什么,你的业务能容忍什么样的效果波动,你的成本结构是什么样的。这些问题的答案,决定了你的路由策略应该怎么设计。
最后分享一个小技巧:从最简单的规则路由开始,不要一上来就搞模型路由。规则路由虽然简单,但能解决 30% 到 50% 的问题,而且几乎没有维护成本。等你把规则路由跑顺了,再逐步引入更复杂的策略。这样每一步都有明确的收益,也更容易说服团队和老板。
这个方向后续还可以这样扩展:把路由决策和 A/B 测试结合起来,用数据驱动的方式持续优化路由策略。比如,你可以把 10% 的流量随机路由到不同的模型组合上,观察效果和成本的差异,然后逐步把更多流量导向更优的策略。这样路由系统就不是一个静态的规则集,而是一个持续进化的系统。