开发者发现 Claude 的 Prompt 缓存可能会发生静默失败,在返回零个缓存 Token 的同时,仍按高级费率计费。对一个 WhatsApp 处理程序进行为期一周的日志运行显示,完全没有缓存读取记录,但 API 却按缓存功能计费——(而原本通过缓存)每月费用可从 1,890 美元降至 406 美元。

为什么这个问题很重要

Prompt 缓存旨在通过重用 Prompt 的静态部分(即“前缀”)来降低成本并加快响应速度。当它正常工作时,高流量应用每月可以节省数百美元。当它失效时,开发者会为从未实际使用的功能付费,且这种静默失败不会提供任何错误或警告来提示问题。

故障是如何表现的

API 接受一个 cache-control 标志和一个前缀,然后报告从缓存中读取了多少个 Token。在观察到的案例中,每个请求返回的缓存读取计数均为零。调用成功了,没有抛出异常,但账单却反映了高级缓存成本。除非你显式记录读取计数,否则这种失败是不可见的。

导致缓存失效的常见原因

  • 前缀过短 – 每个 Claude 模型都为可缓存前缀定义了最小 Token 长度。Haiku 4.5 至少需要 4,096 个 Token;Sonnet 4.6 仅需 1,024 个。发送较短的前缀虽然符合请求格式,但服务会忽略缓存指令。
  • 易变的字节发生变动 – 缓存要求字节级精确匹配。在系统 Prompt 的开头添加动态元素(如时间戳、new Date() 或用户邮箱)会改变字节序列,导致每个请求都被视为全新的、未缓存的写入。
  • 工具列表顺序发生变化 – 工具会被附加在 Prompt 前面。如果工具数组是根据对象键(object keys)构建的,则迭代顺序在不同调用之间可能会发生变化,从而改变字节布局并破坏缓存。

你现在可以采取的修复措施

  • 验证前缀长度 – 在发送请求之前,根据模型的最小值估算前缀的 Token 数量。如果不足,请拒绝请求或填充前缀。
  • 在每次调用时记录缓存读取情况 – 记录 “cache read tokens” 字段。如果连续出现零,则是缓存未命中的明确信号。
  • 固定 Prompt 的起始字节 – 将动态数据移出缓存段。如果必须包含用户特定信息,请将其放在缓存前缀之后。
  • 同步模型标识符 – 确保路由中使用的模型 ID 与存储在缓存表中的 ID 一致;ID 不匹配会导致无法进行缓存查找。

成本角度

对于每天进行数千次调用的应用来说,从不使用缓存转为使用缓存可以大幅降低每月支出——在报告的案例中,费用从约 1,890 美元降至 406 美元。即使是适度的流量也能看到明显的节省,而且重用大型静态 Prompt 的性能提升可以降低延迟。

反方观点

然而,由于这种失败具有静默性,确保你没有多付钱的唯一方法就是检查读取计数——这一点许多人都忽略了。

下一步需要关注什么

  • 指标仪表板 – 在请求量旁边增加一个缓存读取 Token 的仪表盘。
  • 工具排序的稳定性 – 如果你依赖动态生成的工具列表,请考虑在将其嵌入 Prompt 之前进行确定性排序。

总结: 当 Claude 的 Prompt 缓存静默忽略你的请求时,它不会报错。请通过记录读取 Token 来验证缓存的有效性,强制执行合适的前缀长度,并保持 Prompt 的起始字节不可变。只有这样,你才能获得承诺的成本和速度优势。