跳到主要内容

提示缓存命中率:你的成本仪表盘缺失的生产指标

· 阅读需 11 分钟
Tian Pan
Software Engineer

当你的团队第一次启用提示缓存时,感觉就像凭空得到了钱。几小时之内,token成本下降了40–60%,延迟也随之缩短。工程师们欢欣鼓舞,然后继续前行。三个月后,有人注意到成本悄悄地爬回去了。从72%起步的缓存命中率现在只剩18%。没有人故意破坏它,没有人注意到。

这是生产LLM部署中最常见的轨迹:缓存只被启用一次,从不被监控,随着代码库的演进而悄然退化。缓存命中率是LLM技术栈中最具影响力的成本杠杆,但大多数团队把它当作一次性的设置任务,而非生产指标。

提示缓存的实际工作原理

当LLM处理请求时,它将提示中的每个token转换为一组中间表示——键值(KV)缓存。这个计算过程才是代价高昂的部分。提示缓存存储这些计算好的状态,使后续具有相同前缀的请求能够跳过计算,直接生成响应。

其经济效益是显著的。对于Anthropic的Claude API,缓存token的费用约为标准输入费率的10%——降低了90%。写入溢价比标准费率高25%,但盈亏平衡点仅需每次写入被读取1.4次。对于OpenAI,自动缓存在超过1,024个token的提示上生效,享有50%的折扣且无写入成本。AWS Bedrock与Anthropic相匹配,提供90%的读取折扣。

缓存条目的生命周期很短——通常为五分钟,最长可延至一小时。这意味着缓存对高请求频率的工作负载最有价值:聊天机器人、Agent循环、编码助手、文档分析流水线。低频批处理作业收益甚微。

缓存的机制也决定了它何时会失效:缓存键由提示前缀中每个token的精确哈希值计算得出,直到缓存控制边界为止。前缀中哪怕一个token不同,就会导致完全的缓存未命中。

杀死命中率的反模式

大多数缓存退化并非由刻意的改变引起,而是来自那些孤立来看似乎无害的模式。

系统提示中的动态时间戳。 这是最常见的故障模式。在系统提示中添加类似 Current time: {datetime.now().isoformat()} 的一行,会为每个请求创建唯一的前缀。缓存命中率:0%。这种模式出人意料地频繁出现——团队为了"上下文新鲜感"而添加它,却没有意识到这让每个缓存条目都失效了。修复方法是完全移除时间戳,或者将其附加到最后一条用户消息的末尾,这样它就不会接触到被缓存的前缀。

工具模式的重排序。 如果你的应用程序动态构建工具定义列表——从注册表中组装、按用户权限过滤或使用不保证键顺序的JSON库进行序列化——你可能会得到结构上完全相同但哈希值不同的模式。在一个20,000个token的Agent提示中,工具模式的重排序会使整个缓存计算失效。修复方法是稳定你的序列化:按字母顺序排列工具名称,固定键顺序,并将工具模式块视为只允许追加的配置对象。

用户特定数据注入到错误位置。 在系统提示的开头注入用户ID、账户等级或个性化上下文,会让每个用户的提示都变得唯一。这在意图上是正确的——你确实想要用户特定的行为——但在架构上位置错了。可缓存的前缀应该只包含在所有请求中完全相同的内容。用户特定的内容应放在提示末尾,在稳定前缀之后。一个团队报告说,将一个300个token的用户上下文块从系统提示内部移到用户轮次的开头,将他们的缓存命中率从23%提升到了71%。

空白符和格式规范化不一致。 如果你的提示模板层不一致地规范化空白符——有时折叠双换行,有时不折叠——语义上完全相同的请求会生成不同的token序列。这在提示经过多个转换阶段的代码库中尤为隐蔽:Jinja模板、Markdown渲染器、字符串消毒器。

缺乏缓存意识的提示演进。 修复一个拼写错误、重新排列一个要点、添加一个说明句——这些都是正常的工程活动,但每一次都会使整个缓存失效。这并不意味着你永远不应该更改提示;它意味着每次更改都应该触发一个缓存预热事件,你的监控应该预期到命中率会暂时下降,然后再恢复。

最优提示架构

结构原则很简单:静态内容在前,动态内容在后。 提示前缀越稳定,缓存命中率就越高。

针对高频工作负载,一个结构良好的提示看起来是这样的,从最静态到最动态排列:

  1. 核心系统指令和行为规则 — 最大的块;在各次部署之间应该是不可变的
  2. 工具和函数定义 — 只允许追加;永远不要重排序,永远不要修改现有条目
  3. 检索的上下文和参考文档 — 使用较长的TTL(一小时)单独缓存,因为文档内容变化缓慢
  4. 对话历史和之前的工具输出 — 使用较短的TTL(五分钟)缓存,因为它是特定于会话的
  5. 当前用户消息 — 永远不缓存;始终放在最后

最可靠地打破这一结构的模式是将系统提示视为个性化的渲染面。每一个被移到提示前面的用户特定token,都会为整个用户群破坏缓存。所需的纪律是将系统提示保持为策略文档,而不是用户状态的渲染目标。

缓存命中率作为生产指标

对于稳定提示的工作负载,70%以上的缓存命中率是可以实现的。行业案例研究表明,通过严格的提示架构,84%以上是可能的。在具有固定系统提示的工作负载上低于30%,表明存在结构性问题。

你想要追踪的指标是缓存token比率:每个请求和滚动聚合中,缓存读取token与总输入token的比率。大多数LLM API响应直接包含这个数据:

  • Anthropic Claude:使用块中的 cache_read_input_tokenscache_creation_input_tokens
  • OpenAI:响应使用对象中的 prompt_tokens_details.cached_tokens
  • AWS Bedrock:使用元数据中的类似token统计

在你的可观测性栈中需要呈现的派生指标:

  • 缓存命中率(%) — 主要告警指标
  • 每次查询成本(滚动平均) — 即使没有直接追踪命中率,也能捕获退化
  • 缓存token比率 — 揭示工作负载在结构上是否适合缓存
  • 缓存写入摊销 — 确认你超过了每次写入的盈亏平衡读取次数

高频工作负载上缓存命中率下降10%不会告警任何人。但它可能在几天内使你的token成本翻倍。这种不对称性就是问题所在:缓存故障是不可见的,直到账单来临。

构建预部署缓存回归检查

防止缓存退化最可靠的方法是在部署流水线中将缓存命中率作为一个门控,而不是部署后的仪表盘。

一个实用的CI检查是这样工作的。针对一组固定的代表性请求基准——从最近的生产流量中抽取50–100个提示——运行你的新提示版本,并测量第二次请求的缓存命中率(第一次用于预热缓存;第二次测试命中率)。与从当前生产版本捕获的基线进行比较。

门控条件:如果缓存命中率从基线下降超过五个百分点,或低于绝对阈值(例如,对于稳定提示工作负载低于60%),则阻止部署。这能捕获结构性回归(添加了时间戳)和部分回归(三个工具模式中的一个发生了变化)。

支持此模式的工具包括Promptfoo和LangSmith,它们都可以将缓存指标断言集成到各自的评估流水线中。如果你运行的是自定义评估工具,原始材料很简单:相同请求的两次传递,加上来自API响应的token统计。

CI检查还能捕获并行化陷阱:如果你的部署在第一个缓存写入完成之前触发了并行预热请求,你会在第二次传递中看到零缓存命中。修复方法是在引入任何并行性之前进行顺序预热调用。

在生产中监控缓存健康状况

缓存命中率需要在仪表盘上与延迟和错误率并列。需要告警的具体信号:

在24小时滚动窗口内下降超过10个百分点。 这几乎总是意味着一次提示更改使前缀失效了。调查很快:检查上次部署中系统提示和工具模式的差异。

具有固定系统提示的工作负载命中率低于30%。 这是一个结构性问题——动态元素嵌入在可缓存区域中。修复需要提示架构审查,而不仅仅是监控。

每次查询成本在没有流量变化的情况下增加。 如果每分钟请求数持平但成本上升,缓存退化是最可能的原因。这种模式在按请求数归一化的实时仪表盘上不太明显。

无需自定义工具即可呈现缓存指标的可观测性平台包括Helicone(基于代理,跨提供商均可使用)、Datadog LLM可观测性和LangFuse(开源)。三者都能捕获 cache_read_input_tokens 并将其与延迟和成本一起呈现。

恢复的样子

当发现缓存回归时,恢复有两个组成部分:修复根本原因和重新预热缓存。

根本原因修复通常是结构性的:从缓存前缀中移除动态元素,稳定序列化,或将用户特定内容移到提示末尾。每次修复都是一次提示更改和一次部署。

缓存预热经常被忽视。在改变了前缀哈希值的提示部署之后,每个用户的缓存都是冷的。如果你有频繁请求的用户,他们本来可以从对话历史缓存中受益,你需要在处理他们的下一个实际请求之前用预热请求来初始化缓存。对于批处理工作负载,在并行处理之前进行专门的预热传递,可以消除冷启动成本峰值。

处理这个问题最好的团队,用对待数据库查询延迟同样的运营纪律来对待缓存命中率:在部署时建立基线,偏差时告警,调查有明确的操作手册。处理得最差的团队在三个月后才发现问题,此时证明最初缓存工作合理性的成本节省已经完全消散。

维持节省所需的纪律

提示缓存不是一次性的优化,它是一个需要持续维护的架构约束。每个接触提示的工程师都在做出决策——无论是否知情——关于缓存失效。系统提示不仅仅是一个行为规范;它是一个缓存键。

保持70%以上命中率的团队有一些共同的习惯:他们将系统提示视为带有审查门控的版本化制品,他们在提示结构级别将配置(静态)与状态(动态)分离,他们在CI中运行缓存指标断言。这些都不是大的投入。维持纪律的成本很低;跳过它的成本是悄然回到全推理定价。

缓存命中率是为你的下一次模型升级、下一次延迟改进、下一次容量余量买单的指标。在你需要它之前就建立好可见性。

Let's stay in touch and Follow me for more thoughts and updates