LLM API 缓存实战:三层缓存把大模型调用成本打下来
为什么你的 LLM 账单越烧越高
接入大模型三个月,账单比想象中高出一大截。翻日志发现一个扎心的事实:大量请求是重复的。
- 定时任务每天早上用同一份模板汇总数据,prompt 一字不差,却每次全价调用;
- 用户提问"帮我解释下这段代码"和"这段代码什么意思",语义相同,模型却要重新推理一遍;
- 长 system prompt(几千 token 的角色设定 + 知识库)每次请求都重复计费。
LLM 按 token 计费,重复推理就是纯浪费。本文分享一套实战验证过的三层缓存方案,从上到下依次是:精确缓存 → 语义缓存 → 供应商 Prompt Cache,三层叠加通常能把成本降 50% 以上,顺带把响应延迟从秒级降到毫秒级。
第一层:精确缓存(Exact Match Cache)
最简单、命中率最低但零风险的一层:prompt 完全相同就直接返回缓存结果,压根不调模型。
适合场景:固定模板的批处理(日报生成、定时翻译、批量摘要)、A/B 测试的对照组、代码审查的固定规则。
|
|
注意:temperature 必须进缓存键。如果 prompt 相同但 temperature=1.0 时命中了 temperature=0 的缓存,就失去了随机性,生成的内容会异常雷同。
第二层:语义缓存(Semantic Cache)
精确缓存救不了开放式输入——用户提问千变万化,一个字不同就 miss。语义缓存的思路:先算 embedding,相似度超过阈值就返回缓存结果。
|
|
实战要点:
- 阈值要按业务调。0.95 以上近乎复读(“你好” vs “你好呀”),0.85 可能把"推荐餐厅"和"推荐咖啡店"混为一谈。先跑一批真实 query 画相似度分布再定。
- 缓存池要限容。用 Redis hash + 定时淘汰(LRU 或按 TTL),不然 embedding 存储和遍历开销会反噬成本。
- embedding 本身也花钱。embedding 模型便宜但非免费,高频短 query 场景要算清楚:省下的生成 token 钱 > embedding 开销才划算。
- 生产环境建议直接用现成方案,比如 GPTCache(开源,支持 Redis 后端 + 多种 embedding),别自己造轮子。
第三层:供应商 Prompt Cache(白嫖的缓存)
前面两层都是"应用层"缓存。还有一层是模型供应商内置的:Anthropic 的 Prompt Caching、OpenAI 的 Automatic Prompt Caching 等。它们对重复的前缀(长 system prompt、对话历史、few-shot 示例)自动缓存 KV 状态,命中部分按远低于正常价的缓存读取价计费,输入 token 成本可降 90%,延迟也能降低。
|
|
关键认知:前缀越长、复用得越频繁,命中收益越大。所以实践上要:
- 把静态内容放前面:system prompt、知识库上下文、few-shot 示例放 messages 开头,用户输入放最后。对话历史的顺序被打乱会破坏前缀缓存。
- 不要拼接随机内容:每次请求往 system prompt 里塞时间戳、随机 ID,等于主动摧毁缓存。
- 固定 model 版本:换模型版本(如 gpt-5.4 → gpt-5.5)缓存全部失效。
三层怎么组合:决策树
|
|
一个常见的坑:缓存了不该缓存的结果。写代码、算数这类"一次生成终身有效"的任务适合缓存;但"根据最新股价写分析"这类时效性强的任务,必须给缓存键加时间维度(比如把日期拼进缓存键),或者直接跳过缓存。缓存键里也应该带用户/租户维度,避免 A 用户拿到 B 用户的私有数据。
效果与取舍
| 层级 | 成本节省 | 延迟收益 | 实现成本 | 风险 |
|---|---|---|---|---|
| 精确缓存 | 高(命中场景) | 秒级→毫秒级 | 极低(几十行) | 几乎无 |
| 语义缓存 | 中高 | 秒级→毫秒级 | 中(embedding+相似度) | 误命中 |
| Prompt Cache | 中(输入侧) | 中 | 零(供应商内置) | 无 |
我的建议落地顺序:先开 Prompt Cache(一行代码不用改,白赚);再给固定模板类任务加精确缓存;最后给高频开放式 query 上语义缓存。三层都上齐后,同一套业务,token 账单能砍掉一半以上——这笔优化比换便宜模型更划算,而且不影响输出质量。