prompt caching 这玩意儿出来一年多,我前后用过几次都没真省下钱,后来才发现自己一直在错的场景往里塞。看 Anthropic 价目表 ——cache write 是 base input 价格的 1.25 倍,cache read 是 0.1 倍 —— 这个 12.5 倍的"读 vs 写"差价决定了什么场景值得缓存、什么不值得。
这篇就把我现在还在用的 4 个场景 + 砍掉的 2 个写清楚,附踩坑实录。
一、先把计价机制对清楚(不然后面的判断都是错的)
Anthropic 官方计价(Sonnet 4.6 / Opus 4.7 价目结构相同,单位 token 数不同):
| 类型 | 单价倍率 | 说明 |
|---|---|---|
| 普通输入 | 1.0× | base price |
| Cache write | 1.25× | 第一次把内容写进缓存的请求 |
| Cache read | 0.1× | 命中缓存的后续请求里那段内容的成本 |
TTL:默认 5 分钟,可显式延长到 1 小时(再贵 25%)。
关键洞察:cache write 多花 0.25× 一次,cache read 每次省 0.9×。所以净收益 = 命中次数 × 0.9 - 0.25。你至少要在 5 分钟 TTL 里命中 1 次才不亏,命中 2 次以上才开始真省。这个简单计算后面会反复回来用。
二、4 种我真在用的场景
场景 1:长 system prompt + 频繁短查询(客服 / 编程助手)
最经典也最被低估的场景。我自己的 chatbotapp 后端有个客服 bot:
- system prompt 约 8000 token(业务规则 + tone 模板 + 几个 few-shot 示例)
- 用户每次查询 50-300 token
- 同一会话 5 分钟内通常 3-5 轮对话
不开 cache:每轮 input ≈ 8000 + 200 = 8200 token,全 base 价。
开 cache:第一轮 8000 token cache write(1.25×)+ 200 base,后续每轮 8000 cache read(0.1×)+ 200 base。
5 轮总输入成本对比(以 8000+200=8200 为单轮 input):
- 不开 cache:5 × 8200 × 1.0 = 41000 单位
- 开 cache:8000 × 1.25 + 200 + 4 × (8000 × 0.1 + 200) = 10000 + 200 + 4000 + 800 = 15000 单位
省 63%。这是 prompt caching 最甜的场景,没有之一。
场景 2:大文档分析(同一文档问多个问题)
我们有个场景是给法务同事看合同——一份合同丢进 Claude,然后问 10-15 个不同角度的问题(违约责任、付款条款、知识产权归属…)。
合同 PDF 转 text 大概 15000-40000 token。如果每次都重新塞进 prompt,就是把同样的 30000 token 跑 15 遍。
开了 cache 之后:文档进去那次 1.25×,后续 14 个问题都吃 0.1×。
14 个问题成本:
- 不开 cache:15 × 30000 × 1.0 = 450000 单位
- 开 cache:30000 × 1.25 + 14 × 30000 × 0.1 = 37500 + 42000 = 79500 单位
省 82%。文档越大、问题越多,省得越凶。这种 batch QA 场景几乎是 cache 的 textbook example。
场景 3:Few-shot heavy 的分类 / 标注任务
我有个文章分类的离线 job:用 GPT-4o 不香(响应慢、JSON mode 偶发歪),改用 Claude Haiku + 12 个 few-shot 示例。12 个 few-shot 例子大概 4000 token,每次只问"下面这篇文章属于哪类"。
跑一晚上 5000 篇文章:
- 不开 cache:5000 × (4000 + 文章 800) ≈ 24M 单位 input
- 开 cache:4000 × 1.25 + 5000 × (4000 × 0.1 + 800) = 5000 + 6M = 6M 单位
省 75%。注意 TTL 限制:5 分钟 TTL 适合并发跑(一份脚本同时打 5-10 个请求让 cache 一直热),不适合慢节奏(每次间隔超过 5 分钟就要重 write)。我们这个 job 跑得快,TTL 一直续上,没问题。
场景 4:Agent loop(同一工具集 + 上下文多轮调用)
LLM agent 在执行任务过程中,通常会:
- 同一组 tool definitions(1500-3000 token)
- 同一份背景上下文(5000-15000 token)
- 多轮 tool_use → tool_result → 进一步推理
每一轮的 input 都包括前面的全部上下文。10 轮 agent 跑下来,最后一轮的 input 已经是 20000+ token。
cache breakpoint 设在 tools + 背景的边界:每轮 read 这块固定部分,只有最新一轮的 tool_use/result 走 base 价。
我现在用 claude-agent-sdk 跑的几个 agent,这层 cache 几乎是 5-8 倍的成本压缩。这也是 Anthropic 自己 docs 里反复强调的用法。
三、2 个我砍掉的场景
反模式 1:输入很短的应用
我之前给一个翻译工具加了 cache,因为"system prompt 也有 800 token 嘛"。但用户每次 query 平均 300 token,TTL 5 分钟里平均只命中 1.2 次。
算账:cache write 800 × 1.25 = 1000 单位,省的钱 = 命中 0.2 次 × 800 × 0.9 = 144 单位。
净亏 856 单位。
经验法则:cacheable 前缀至少要比单次 query 大 5 倍以上,5 分钟内命中至少 2 次,再考虑加 cache。否则 0.25× 的 write 溢价直接把你"省下来"的吃光。
反模式 2:cache 前缀经常变动的场景
我有个分析助手,prompt 里要拼一个"今天的市场快讯摘要"——这玩意儿每分钟都在变。前 7000 token 是稳定的(角色 + few-shot),后面 1500 token 是动态的。
我没把 cache breakpoint 放在 7000 那个边界,而是错放在了快讯之后。结果:每次快讯一变,整段 8500 token 全部 cache miss、全部重 write。
后来挪到正确位置(动态部分之前)才省下来。但调通这个之前已经烧了几百块——cache miss 比不 cache 还贵。
经验法则:cache breakpoint 必须放在"真稳定的前缀末尾",breakpoint 之后的所有内容都按 base 价格计算。把动态部分推到 breakpoint 之后,永远别让它出现在可缓存前缀里。
四、踩了不会再踩的 3 个陷阱
1. 4 个 cache_control 上限:Anthropic 限制单次请求最多 4 个 cache breakpoint。我一度想给 system / tools / docs / examples 各放一个 —— 是允许的(刚好 4 个),但每加一个 breakpoint 都意味着前面那段必须 ≥ 1024 token(Sonnet)或 ≥ 2048 token(Haiku)才会真正缓存。短碎片塞 breakpoint 等于浪费 slot。
2. 工具定义改一个字段,全段 miss:tools 数组只要任何 description / parameter 改了一个字符,整个 tools 段的 hash 就变,cache 击穿。我们团队有过一次"我就改了一个 typo 怎么这周账单涨了 30%"——就是这个。
对策:tools 定义在 codebase 里固化 + commit hash 当版本号,不轻易改。
3. 5 分钟 TTL 重置规则:每次 cache 命中会刷新 TTL。看起来很爽,但没命中的请求不会延寿。低频请求场景(≈ 每 8-10 分钟 1 次)TTL 实际命中率会很低,体感算下来不如不开。要么改成 1 小时 TTL(多付 25% write 溢价),要么放弃 cache。
五、决策清单(照着判断要不要开 cache)
下次给一个 Claude 应用加 prompt caching 之前,按这 5 条判:
- ✅ 可缓存前缀 ≥ 1024 token(Sonnet)/ 2048 token(Haiku)
- ✅ 前缀稳定(修改频率 < 每周 1 次)
- ✅ TTL 内命中次数 ≥ 2(保守至少 3)
- ✅ 前缀比单次新增 input 长至少 3 倍
- ✅ cache breakpoint 能放在"完全稳定段的末尾"
5 条全过 → 开。任何一条不过 → 别开,省下的钱付不了 write 溢价。
收尾一句话:prompt caching 不是免费午餐 —— 是个为"高命中率 + 大前缀 + 稳定前缀"三个条件同时成立时特别甜的工具。三个条件缺一个就别凑,cache miss 比不 cache 还贵。