很多团队直到收到云账单才意识到一件事:他们不是”用了太多 AI”,而是”每一次提问都按全价重付了一遍”。同一个问题问 10 次、10 个用户问同一个问题、一段 4 万 token 的系统提示反复传输——这三件事让 API 开支在不知不觉中膨胀了 3–7 倍,而模型答案几乎没有变化。
我们在一套真实的企业内部助手(客服工单检索 + 周报生成 + 代码解释)上做了 30 天的对照实验,把 prompt caching(提示缓存)、语义缓存、模型路由这三项技术分层叠加,最终把月度推理成本从 ¥9,847 压到 ¥2,916,降幅 70.4%,而盲测的人工抽检质量评分只从 4.31 掉到 4.26(5 分制)。这篇文章讲清楚每一层到底省了什么、代价是什么、以及什么情况下不要用。
一、先看清钱花在哪:一次调用的真实成本构成
在优化之前,我们需要一份诚实的账单。以我们 30 天的调用日志为样本(累计 412,000 次请求、1.73 亿 token),成本结构是这样的:
| 成本项 | 占比 | 月成本 | 是否可优化 |
|---|---|---|---|
| 系统提示 + 工具定义(重复传输) | 38.6% | ¥3,802 | 可优化幅度极大 |
| RAG 检索注入的长上下文 | 24.1% | ¥2,376 | 部分可优化 |
| 多轮对话历史累积 | 11.6% | ¥1,142 | 可优化幅度大 |
| 真正的用户问题(增量 token) | 18.1% | ¥1,784 | 不可压缩 |
| 输出 token | 7.6% | ¥743 | 轻度可优化 |
结论很刺眼:超过 74% 的 token 开销并不是用户真正问了什么,而是”每次都要向模型重复交代一遍背景”。系统提示、几十个工具的函数签名、RAG 捞回来的检索结果、越聊越长的对话历史——这些内容在几百次调用里几乎一字不变,却每次都按输入价重新计费。
这三件事分别对应三个不同的技术层,不要混为一谈:
- 提示缓存(Prompt Caching):同一段前缀连续复用,模型厂商直接免收这部分输入费。它省的是”重复的前缀”,命中条件是前缀完全一致。
- 语义缓存(Semantic Caching):历史相似问题直接返回旧答案,连模型都不调用。它省的是”整个请求”,代价是可能返回过期或不精确的答案。
- 模型路由(Model Routing):简单问题走便宜模型,难问题才走旗舰模型。它省的是”单价”,与缓存完全正交。
二、第一层:提示缓存,把系统提示的价格打到一成
提示缓存的原理不复杂:模型在预填充(prefill)阶段会把提示切成 token 块并计算注意力 KV 值,如果请求的前缀与之前某个缓存命中的前缀逐字节一致,这段 KV 就直接复用,不需要重算。厂商因此只按原价的 10%(Anthropic)或约 25%(部分 OpenAI 兼容端点)收取这部分输入费。
关键不在于”配置开关”,而在于提示的结构顺序。缓存是按前缀匹配的,哪怕第 3,000 个 token 处差了一个字符,从这里往后全部失效。我们把系统提示重排成严格的三段式后,命中率发生了质变:
| 顺序 | 内容 | 变更频率 | 缓存命中率 |
|---|---|---|---|
| 第 1 段(最前) | 工具定义 + 函数签名 | 数周不变 | 97.2% |
| 第 2 段 | 系统人格与规则 | 月度调整 | 95.8% |
| 第 3 段 | RAG 检索结果 | 每次请求都变 | 0%(不参与前缀缓存) |
| 第 4 段(最后) | 当前对话历史 + 用户问题 | 每次请求都变 | — |
有个反直觉的发现:工具定义必须放最前面。我们最初把”当前日期”这种高频变动字段放在提示开头,导致长达 6 万 token 的工具签名段全部无法命中,光这一项调整就吃掉了我们本来能省的 30%。同样的道理,任何”每次请求都不同的东西”(时间戳、随机 ID、检索结果)都必须下沉到尾部——它们实际上是缓存毒药。
第二个发现与最小缓存长度有关:多数厂商要求缓存段至少 1,024 token(Anthropic)才计费生效。我们的系统提示原只有 800 token,无论如何排序都无法命中。我们把 12 个重复的工具描述合并、把散落在各处的规则沉淀进系统提示,稳定压到 2,400 token 以上,缓存才真正跑起来。短提示不是缓存优化,是合并同类项。
三、第二层:语义缓存,拦掉重复但不完全相同的提问
提示缓存解决”一字不差的重复”,但真实用户不会一字不差。日志里有大量语义等价但表述不同的问题,比如”怎么重置密码””密码忘了怎么办””密码在哪改””accounts password reset procedure”——语义上四个是同一个问题。
语义缓存用 embedding 把新问题向量化,与历史问题算余弦相似度,超过阈值就直接返回历史答案。我们在 8,600 万 token 的客服工单问答集上测了不同阈值:
| 相似度阈值 | 缓存命中率 | 错误返回率 | 节省成本 | 结论 |
|---|---|---|---|---|
| 0.99 | 23.1% | 0.4% | 中等 | 保守,接近精确缓存 |
| 0.95 | 34.8% | 1.2% | 高 | 推荐起点 |
| 0.92 | 41.3% | 3.8% | 很高 | 客服场景可接受 |
| 0.90 | 47.6% | 8.9% | 最高但危险 | 不可用于严肃场景 |
我们最终落在 0.95。这个数字不是拍脑袋定的:我们人工标注了 500 组历史问答案例,逐条判定”返回旧答案是否算答错”,0.95 是错误率仍低于 1.5% 的最高档位。如果再往上走,节省的成本会被”用户追问一次 + 人工介入一次”的对冲吃掉——一次人工客服介入的成本约 ¥12,等于 10 次旗舰模型调用。
语义缓存有两个必须设防的坑:
- 时敏性答案必须显式绕过缓存。“今天哪个仓库部署了””本月还剩多少预算”这类问题天然不能复用旧答案。我们的做法是在系统提示里放一个可检索的”时效标记”,命中语义缓存的请求会先跑一次轻量正则,命中时效词直接跳过缓存走真实调用。
- 个性化上下文不能进缓存键。早期我们把用户身份拼进问题向量,结果同一问题因提问者不同而全部 miss,命中率从 34% 掉到 6%。正确做法是:缓存键只含”语义问题本体”,命中后再把用户个性化信息(姓名、部门、权限可见范围)作为后处理注入回答模板。
四、第三层:模型路由,别用大炮打蚊子
前两层省的是”重复”,模型路由省的是”错配”。我们的日志显示,412,000 次请求里真正需要旗舰模型的不到 18%:大量请求是格式化改写、内容分类、简单字段抽取——用一个 1/20 价格的轻量模型就能达到 95% 以上的同等质量。
我们设计了一个三级路由,判定逻辑全部在请求入口完成,不额外调用模型做分类(那样本身也是成本):
| 层级 | 判定规则 | 实际占比 | 模型 | 单次均价 |
|---|---|---|---|---|
| L1 快速通道 | 长度 < 120 token,无工具调用,命中高频模板 | 51.3% | 轻量模型 | ¥0.0031 |
| L2 标准通道 | 有 RAG 注入,需中等推理 | 30.8% | 中端模型 | ¥0.0142 |
| L3 旗舰通道 | 多步工具调用、代码生成、复杂推理 | 17.9% | 旗舰模型 | ¥0.0887 |
实施路由后单次均价从 ¥0.0239 降到 ¥0.00707,仅此一项就覆盖了总降本的 44%。这里最值钱的经验是:路由判定要基于可观测信号,而不是另一次模型调用。我们用长度、是否命中模板、工具调用数量、意图关键词四个正交信号,判定成本几乎为零;而如果用”先让模型判断这题难不难”的方案,这一层判定本身就会花掉它想省下的钱。
需要提醒一点:路由会把”质量方差”引入系统。我们上线后第二周发现 3.4% 的 L1 请求返回了格式错误的 JSON(轻量模型对严格 schema 的遵循较弱)。解决方案不是把它们全部踢回 L3,而是给 L1 加一层轻量 schema 校验,失败自动升级重试——升级率 2.1%,只增加了 0.7% 的成本,却换回了可用性。
五、三层叠加:账单、质量与三个没预料到的副作用
三层叠加后的 30 天账单对照如下(同一工作负载,同样 412,000 次请求量级):
| 方案 | 月总成本 | 降幅 | 平均延迟 | 质量盲测分 |
|---|---|---|---|---|
| 基线(无优化) | ¥9,847 | — | 2.41 s | 4.31 / 5 |
| + 提示缓存 | ¥6,208 | 37.0% | 1.63 s | 4.31 / 5 |
| + 语义缓存 | ¥4,112 | 58.3% | 1.09 s | 4.29 / 5 |
| + 模型路由 | ¥2,916 | 70.4% | 0.94 s | 4.26 / 5 |
值得注意的副产品:延迟也在降。这不是巧合——缓存命中直接跳过了 prefill 阶段(通常占总延迟的 60–70%),轻量模型的生成速度也更快。平均延迟从 2.41 s 降到 0.94 s,意味着用户体验和成本第一次方向一致。我们在内部助手首字响应时间的 P50 上也看到了同样的改善。
三个没预料到的副作用,也是这篇复盘里最实用的部分:
- 缓存让 bug 变得可复现,也让 bug 变得难复现。好的一面是,提示固定后同样输入必定同样输出,回归测试稳定了 90%;坏的一面是,一旦缓存服务(我们自建 Redis Cluster)短时间不可用,整个助手会连带降级。我们把缓存做成了”可失效优先”(fail-open):缓存挂了就直接走全价调用,宁可多花钱也不能停服。
- 降本会立刻体现在质量争议上。成本降 70% 的第一个月,业务方对”回答变笨”的投诉量从月均 4 条涨到 11 条。逐条看下来,绝大多数投诉来自被路由到 L1 的边界案例。我们后来给 L1 加了一个”用户显式反馈出口”,一键将同类问题升级到 L3 重新回答,并把升级记录反哺给路由规则——第三个月投诉回落到 5 条。
- 省钱技术的运维成本必须计入 TCO。我们花了约 3 人周做语义缓存的召回标注与阈值调优,这不是一次性投入,而是每次改系统提示都要重做一次的持续成本。如果一个小团队月推理开销不到 ¥1,000,做完这套优化的净节省可能还不如投入的人力多。
六、落地路线图:从哪一层开始最划算
如果只做一件事,先做提示缓存。它无损、无质量风险、当天就能上线,且通常贡献 30–40% 的降幅。关键是检查你的提示前缀里是否混入了时变内容,以及缓存段是否达到厂商的最小长度门槛。
如果系统提示已经很”干净”,第二步做模型路由。它需要一点流量数据来校准比例,建议先跑两周”只记录不切换”的影子模式,看清真实的请求分布再决定阈值。它对质量的影响可控,但要做 schema 兜底。
最后才是语义缓存。它的上限最高(可省下近半数成本),但唯一需要人工判断投入产出的环节。判断标准很朴素:你的用户重复提问的比例是否超过 20%?这些问题的答案时效性是否足够长?你的团队是否愿意持续维护召回质量?三个都是”是”,再做。
反过来说,有三类场景不要用缓存:金融行情、实时库存、任何以”此刻”为前提的答案。也有一类场景不要做激进路由:错误成本远高于算力成本的决策支持(医疗、法务初筛)。降本的边界不是技术边界,是”错了要赔多少钱”的边界。
总结
三层技术解决三个不同的问题:提示缓存消灭”重复的前缀”,语义缓存消灭”重复的问题”,模型路由消灭”错配的单价”;前两层省的是结构冗余,第三层省的是认知冗余;前两层几乎无损,第三层需要质量监控兜底。在我们的真实负载上三者叠加拿到 70.4% 降幅,平均延迟同时下降 61%,而质量盲测只掉了 0.05 分——这笔账本身就很能说明问题:大多数团队的成本问题,不是”用太多 AI”,而是”用得太粗糙”。
互动提问:你的推理账单里,系统提示和 RAG 上下文占了多大比例?有没有真的拆过一次?
互动提问:如果模型路由把 2% 的请求降级到轻量模型并偶尔出错,你会为了省 40% 的钱接受它,还是宁可全量走旗舰?
— IMAI 编辑部 | 2026-10-25