几周前我写了一篇文章,解释了为什么你发给Claude的99%数据已经在缓存里。KV张量、VRAM、本地SSD——所有的内部机制。但我遗漏了最痛的部分:账单。
因为prompt缓存是那种看起来像超值优惠的东西,但一旦仔细看看数字,你就会发现为了节省成本,你竟然被要求付更多的钱。
成本悖论
让我们用一些数字来说明。在Claude Sonnet的定价中:
| 项目 | 每百万tokens价格 |
|---|---|
| 常规输入 | $3.00 |
| 缓存写入 | $3.75 (1.25倍) |
| 缓存读取 | $0.30 (0.10倍) |
注意一件事:写入缓存的成本比直接处理输入高25%。你为了让下一次使用更便宜而需要额外付费。
这就像加入Costco那样。年费有点心疼。但如果买得足够多,就会值回票价。
问题是,“足够多”取决于你能在缓存过期前读取它的次数。
什么时候你会亏钱?
假设你用cache_control发了一个100K tokens的prompt。第一次请求:
100,000 tokens × $3.75/M = $0.375 (缓存写入)
如果你没有用缓存发送它:
100,000 tokens × $3.00/M = $0.300 (常规输入)
你额外多付了$0.075,比常规价格高出25%。你亏钱了。
现在第二次请求,同样有100K tokens的前缀:
100,000 tokens × $0.30/M = $0.030 (缓存读取)
对比来看:
100,000 tokens × $3.00/M = $0.300 (常规未缓存输入)
你节省了$0.27。两次请求的总成本不仅回本了之前多支付的$0.075,现在还实现了盈亏平衡。
盈亏平衡点是1.4次读取。 用更直白的话说:如果你计划在接下来的5分钟内至少重复使用该前缀两次,缓存就是值得的。
为什么对Claude Code来说使用缓存是明智选择
在Claude Code的一次会话中,每条消息都会包含system prompt、工具定义以及整个对话历史。每条消息都在重复发送相同的上下文。如果没有缓存,每次发送“把这个按钮换个颜色”,你都需要为相同的150K tokens上下文支付$3.00/M。
没人能负担得起这个。
而有了prompt缓存,你只需为写入缓存支付一次费用,之后每次读取只需要$0.30/M。在包含150K上下文的50条消息会话中,差距很明显:
无缓存: 50 × 150,000 × $3.00/M = $22.50
有缓存: 1 × 150,000 × $3.75/M + 49 × 150,000 × $0.30/M = $2.77
从$22.50降到$2.77。节省了88%。这就是为什么Anthropic默认在Claude Code中启用缓存。如果不这样做,从经济角度看是不可行的。
反直觉点:缓存读取是你token计数飙升的原因
接下来是让人困惑的地方。
当你打开用量仪表盘并看到cacheReadInputTokens: 4,241,579,174,你的脑子会想:“我使用了四十多亿个tokens。”从技术上讲,这是真的:你的账户处理了这些tokens。但实际并不是你想的那样。
一次缓存读取不会重新计算KV张量。只需从内存中读取,对于Anthropic来说比常规输入便宜得多,所以他们以正常输入成本的90%折扣收费。
但数字看起来巨大,与其他统计值相比简直天差地别。我个人一个月的真实数据如下:
cacheReadInputTokens: 4,241,579,174 (99.5%)
cacheCreationInputTokens: 196,596,243 (4.6%)
inputTokens: 1,293,019 (0.03%)
outputTokens: 2,517,666 (0.06%)
我账户中过去99.5%的处理tokens是缓存读取。如果Anthropic决定将缓存读取按正常输入成本收费,我的账单会直接飙升10倍。字面意义上。
这还有一个实际后果:在与他人比较你的使用量时,cacheReadInputTokens是最没用的指标。进行200次短会话的人和进行10次长会话的人同样可以有完全不同的缓存读取统计值,但实际成本差别不大。
你可以控制的三大关键因素
如果你直接使用API(而非Claude Code,在后者中Anthropic为你管理缓存),以下三件事情可以帮助优化使用:
1. 按稳定性排列你的prompt内容
缓存按前缀工作。如果你更改了开头的某些内容,就会使接下来的所有内容缓存失效。这是黄金规则:
[System prompt — 永不更改]
[工具定义 — 很少更改]
[参考文档 — 偶尔更改]
[对话历史 — 随消息增长]
[用户的最后一条消息 — 总是新的]
如果你在参考文档前插入用户的消息,每次都会使文档的缓存失效。这是令你每次请求多花钱的“偷工减料”。
2. 明智使用缓存断点
Anthropic允许每个请求最多设置4个缓存断点(cache_control)。你可能会有将每个块都设置断点的冲动。但每个断点都将强制进行一次缓存写入,即使内容与之前缓存的完全相同。
我的推荐:在system prompt结束处设一个断点,再在对话历史结束处设一个断点。两个锚点就足够了,不需要四个。
3. 记住最小缓存块
缓存仅在块的长度至少为1,024 tokens时才有效(Opus版需要2,048)。如果你的system prompt长度只有500 tokens,就无法缓存。你可以通过API响应查看是否命中缓存:如果cache_read_input_tokens为0,说明块未达到最小长度。
你无法控制但无需担忧的事
标准层缓存的TTL是5分钟(在VRAM中)。如果用户在6分钟后响应,就会出现缓存失效,并重新计算所有内容。解决方法是购买扩展缓存(TTL长达1小时,但写入成本是输入的两倍)。
对于互动对话(用户与聊天机器人实时交互),5分钟通常足够了。而对于在请求之间有较长暂停的批量处理工作,如果prompt很长,可以考虑购买扩展缓存。记住,计算一下是否值得用读取成本的节省来抵消写入额外的2x费用。
心理效应
没人提到的一个副作用是:缓存会促使你增加请求数量,而不是减少。因为你知道每次额外请求的边际成本几乎为零。
这有点像从按流量计费切换到无限流量套餐的效果。当数据使用从按MB收费变成无限时,你开始用更多的数据,不是因为需要,而是因为额外使用成本趋近于零。
用prompt缓存时,如果上下文已经缓存,额外的请求边际成本几乎只包括输出成本。这真的会改变你的行为。你可能会更频繁地迭代内容,提出更多细小的问题,或者把这个模型当成超级版的“橡皮鸭”来调试代码。
这是坏事吗?因人而异。如果你有预算上限或使用配额(如Claude Max),这可能是个陷阱:虽然每次请求的成本下降了,但请求数量上升,而配额是由总使用量而非边际成本来衡量的。
总结
prompt缓存是一种运行逻辑与你直觉完全相反的优化方式:
- 开始时的付费更高(缓存写入成本是1.25倍)。
- 之后的付费少得多(缓存读取成本是正常输入的0.1倍)。
- 盈亏平衡点极低(只需1.4次读取)。
- 使用量的数字看起来异常巨大(你99%的tokens来源于廉价的缓存读取)。
- prompt内容的顺序比你想象的重要得多(稳定的前缀=更高的缓存命中率)。
如果你正在使用Anthropic的API,但没有使用prompt缓存,那么你就是在浪费钱。如果你已经在使用但不理解账单,现在你知道原因了:缓存通过先让你多付,最终为你省下一大笔。这是市面上最划算的优化方式。
**相关内容:**如果你想了解内部机制(如KV张量、VRAM、按前缀哈希),可以阅读为什么你发给Claude的99%数据已经在缓存里。如果你对如何在没有API访问权限下估算配额感兴趣,可以查看Tokamak:无API估算Claude配额。