Claude Prompt Caching 入门:从零到能用
面向第一次接触 Anthropic Messages API 缓存功能的同学。读完你能做到:写出会缓存的请求、看懂账单、判断为什么没命中。一、一句话理解
把一段反复使用的长 prompt(系统说明 / 长文档 / few-shot 示例)标记一下,服务器就会把它存起来。下次相同前缀的请求来,服务器跳过重复处理,便宜约 10 倍、也更快。5 分钟内没人再用,就过期。二、为什么要用 —— 看账单
以输入 token 价格为 1× 计:| 类型 | 价格 | 说明 |
|---|---|---|
| 普通输入 | 1× | 不缓存的部分,该多少钱多少钱 |
| 缓存写入(5 分钟 TTL) | 1.25× | 第一次写入贵一点点 |
| 缓存写入(1 小时 TTL) | 2× | 想存更久就要付更多 |
| 缓存读取(命中) | 0.1× | 重头戏。后续每次便宜 90% |
三、触发缓存的三个硬条件
缺一不可。1. 必须显式打标记 cache_control
content 不能是纯字符串,必须是 content block 数组,在要缓存的那一块上加 cache_control: {"type": "ephemeral"}:
2. 长度必须达到最小阈值
短于阈值的内容,就算打了标记也不会缓存(也不报错,静默忽略)。按模型不同:| 模型 | 最小 tokens |
|---|---|
| Sonnet 4.5 / 4 / 3.7 | 1024 |
| Sonnet 4.6 / Haiku 4.5 之前的 Haiku | 2048 |
| Opus 4.5 / 4.6 / 4.7、Haiku 4.5 | 4096 |
3. 前缀必须逐字节相同
缓存按前缀匹配:从请求开头一直到cache_control 标记位置,这段字节流必须和上一次完全一样。改任何一个字符——哪怕是空格、JSON 字段顺序、时间戳——都算”新前缀”,会重新写入而不是命中。
实践含义:稳定的东西放前面,易变的东西放后面。
四、最小可运行示例
跑两次同一个长文 + 不同问题。第一次写入,第二次命中。read ≈ 第 1 次的 write,说明同一段前缀被命中复用了。
五、怎么判断命中没命中 —— 看三个字段
每次响应的usage 里:
| 字段 | 含义 | 计费倍率 |
|---|---|---|
input_tokens | 没被缓存的剩余输入 token | 1× |
cache_creation_input_tokens | 这次写入缓存的 token 数 | 1.25× 或 2× |
cache_read_input_tokens | 这次从缓存读取的 token 数 | 0.1× |
read > 0,你就在省钱。
六、几个最常见的踩坑
| 现象 | 原因 |
|---|---|
write 永远是 0 或字段不存在 | 没打 cache_control 标记 / 长度没到阈值 / 中转站没透传 |
第 2 次 write 又 > 0,read 还是 0 | 前缀变了。常见:prompt 里有 datetime.now()、UUID、变化的用户 ID;或 JSON 序列化顺序不稳定;或加了带时间戳的 system 提示 |
| 隔了一会儿再调,又变成写入 | 5 分钟没人用就过期。需要常驻可以加 {"type": "ephemeral", "ttl": "1h"} |
| 同一份 prompt 切换模型后没命中 | 缓存按模型隔离,换模型相当于换 key |
| 多轮对话第一轮命中、第三轮又不命中 | 单次请求最多 4 个 cache_control 断点;且每个断点只往前找 20 个 content block,长对话要定期往新消息上补打断点 |
七、进阶:多轮对话怎么打
把cache_control 打在最近一条 user 消息的最后一个 content block 上。每加一轮就把上一次的标记保留、再在新的最末块上加一个。这样每一轮的缓存读取范围都会自动延伸到上一轮结束的位置。
八、用中转站(比如 apiyi)的额外提示
中转站是否真的支持缓存,取决于它两件事都做对:- 把请求里的
cache_control字段原样转发给 Anthropic 上游; - 把上游响应里的
cache_creation_input_tokens/cache_read_input_tokens原样回吐给你。
write > 0 和 read > 0),换到中转站 usage 字段就丢了或恒为 0,那就是中转的问题。先用直连做对照实验,再上中转。
九、要点回顾
- 标记:
cache_control: {"type": "ephemeral"},加在 content block 上。 - 长度:够长(Sonnet 4.6 ≥ 2048 tokens)才会真的缓存。
- 顺序:稳定内容在前,易变内容在后。
- 验证:看
usage.cache_read_input_tokens > 0。 - 省钱:命中只要 0.1×,但写入要 1.25×,2 次以上才回本。