Claude Code 的 Prompt Cache 到底怎么工作? 5 个让缓存失效的坑
用 Claude Code 一段时间后我发现,同样的工作量,token 账单能差好几倍——差别几乎全在 Prompt Cache 有没有用对。官方文档把"有这个功能"讲了,但"怎么才不会踩坑"基本没说。这篇把我踩过的坑和读源码/官方博客理解的机制整理一下。
纯技术,不涉及任何平台推荐,就事论事。
---
## 一、为什么 Claude Code 对缓存特别敏感
普通 API 调用输入输出大致 1:1 ,prompt 短,缓存收益有限。
Claude Code 反过来——**单次请求的输入 token 远大于输出**。一次"改个 bug"的对话,输出可能就 200 token ,但输入要带:
- 系统提示词(约 3000 token ,含全部工具定义)
- [CLAUDE.md](http://claude.md/) (项目指令,几百到几千 token )
- 历史对话(几千到几万 token )
- 当前文件内容
**典型一次请求:输入 15K ,输出 500 ,输入是输出的 30 倍。** 这种结构下,输入 token 的单价几乎决定总账单。而 Prompt Cache 对命中部分给的是 **90% 折扣**(只收 10%),不是小优化,是数量级差异。
---
## 二、工作原理:前缀匹配,不是"重复内容打折"
很多人以为是"系统检测到重复内容就打折",这是错的。
真实机制:**服务端保存你最近发送的 prompt 前缀。下次请求只要前缀完全一致(一字不差),就从缓存读取、跳过重算。**
关键点:**前缀任何一处变化,后面所有内容的缓存全部失效。**
```plaintext
请求 1:[系统提示][工具定义][CLAUDE.md][对话 1-5][新消息]
请求 2:[系统提示][工具定义][CLAUDE.md][对话 1-6][新消息]
前面完全相同 → 命中,只有"对话 6+新消息"按全价
```
但如果你在请求 2 里给 [CLAUDE.md](http://claude.md/) 偷偷加了一行,从 [CLAUDE.md](http://claude.md/) 往后**全部失效**,包括之前已经缓存的对话历史。
### 一个反直觉的设计细节
[CLAUDE.md](http://claude.md/) 不是拼在 system prompt 里发送的,而是通过 `<system-reminder>` 标签注入到 messages 数组。为什么?因为**同版本 Claude Code 的 system prompt 在所有用户之间字字相同**,服务端可以做全局共享缓存;如果把每个人不同的 [CLAUDE.md](http://claude.md/) 拼进 system prompt ,这个共享缓存就没了。拆开放,既保住全局共享,又让你的 [CLAUDE.md](http://claude.md/) 独立缓存。
---
## 三、5min vs 1h 两档,怎么选
| 档位 | 写入价格 | 读取价格 | 回本条件 |
| -------- | ---------------- | --------- | ------------------ |
| 5 分钟 | 1.25× 基础输入价 | 0.1× | 1 次命中即回本 |
| 1 小时 | 2× 基础输入价 | 0.1× | 2 次命中回本 |
- 高频连续工作(<5min 一次请求)→ 5min 档
- 任务间隔长、跨会议/午餐 → 1h 档
Claude Code 内部对 system prompt + 工具定义默认 5min (高频复用),用户上下文按 session 长度自动选档。
---
## 四、5 个让缓存失效的坑(最实用的部分)
### 坑 1:中途修改 [CLAUDE.md](http://claude.md/)
最常见。几轮对话后随手给 [CLAUDE.md](http://claude.md/) 加条规则——从 [CLAUDE.md](http://claude.md/) 往后全部失效,之前几轮的输入全按全价重算。 **对策**:session 开始前配好,开始后只读不改,要改先 `/new`。
### 坑 2:prompt 里塞动态内容
```plaintext
"当前时间 2026-07-21 15:23:45 ,请…"
```
时间戳、随机 ID 、UUID 只要进了前缀,缓存命中率直接归零(每次都不一样)。 **对策**:动态信息放最后一条用户消息里,别混进 system 或前置。
### 坑 3:中途切模型
不同模型缓存隔离。opus 切 sonnet ,之前的缓存直接作废。 **对策**:同任务保持模型一致,要切先 `/new`。
### 坑 4:/compact 的隐藏成本
`/compact` 的总结请求用的是**专门的总结 system prompt 、且不带工具定义**,前缀从第一个 token 就和日常缓存不同,**整个对话历史按全价计费一次**。 **对策**:别攒到几十轮才 compact ;做完一个子任务就 compact 一次(被全价的内容少);只想清空的话 `/new` 更划算。
### 坑 5:/resume 破坏缓存
`--resume` / `/resume` 在多个版本存在缓存失效——恢复后前几轮全价,可能 10–20 倍成本暴增。原因是序列化/反序列化后 messages 结构有微小差异,服务端当成新前缀。 **对策**:长任务尽量一个连续 session 做完;不得不断,宁可新 session 简短复述,也别 resume 。
---
## 五、怎么确认缓存真的命中了
看响应里的 usage 字段:
```json
{
"usage": {
"input_tokens": 245,
"cache_creation_input_tokens": 3120,
"cache_read_input_tokens": 8450,
"output_tokens": 412
}
}
```
- `cache_creation_input_tokens`:本次写入缓存( 1.25× 或 2×)
- `cache_read_input_tokens`:本次命中( 0.1×)
- 连续 session 第 N 轮( N>1 ),`cache_read` 应远大于 `input_tokens`
- 如果 `cache_read` 一直是 0 ,前缀肯定哪里被破坏了,照上面 5 个坑排查
---
## 六、三条核心原则
1. **保持前缀稳定**——别中途改 [CLAUDE.md](http://claude.md/) 、加时间戳、切模型
2. **同任务一气呵成**——长 session 比频繁 resume 划算
3. **/compact 早用别攒**——越晚 compact 被全价的内容越多
[CLAUDE.md](http://claude.md/) 我个人保持在 50 行以内,当"索引"用(列关键文件路径、命令、约定),详细文档放 `docs/` 让 Claude Code 自己 Read——既省 token 又不容易失效。
以上是我自己的实践,有不同经验欢迎评论区交流。
*基于 Claude Code 1.x 与 Anthropic 官方文档,如有错误欢迎指正。
---
原文链接:[点击查看](https://www.v2ex.com/t/1229144)
纯技术,不涉及任何平台推荐,就事论事。
---
## 一、为什么 Claude Code 对缓存特别敏感
普通 API 调用输入输出大致 1:1 ,prompt 短,缓存收益有限。
Claude Code 反过来——**单次请求的输入 token 远大于输出**。一次"改个 bug"的对话,输出可能就 200 token ,但输入要带:
- 系统提示词(约 3000 token ,含全部工具定义)
- [CLAUDE.md](http://claude.md/) (项目指令,几百到几千 token )
- 历史对话(几千到几万 token )
- 当前文件内容
**典型一次请求:输入 15K ,输出 500 ,输入是输出的 30 倍。** 这种结构下,输入 token 的单价几乎决定总账单。而 Prompt Cache 对命中部分给的是 **90% 折扣**(只收 10%),不是小优化,是数量级差异。
---
## 二、工作原理:前缀匹配,不是"重复内容打折"
很多人以为是"系统检测到重复内容就打折",这是错的。
真实机制:**服务端保存你最近发送的 prompt 前缀。下次请求只要前缀完全一致(一字不差),就从缓存读取、跳过重算。**
关键点:**前缀任何一处变化,后面所有内容的缓存全部失效。**
```plaintext
请求 1:[系统提示][工具定义][CLAUDE.md][对话 1-5][新消息]
请求 2:[系统提示][工具定义][CLAUDE.md][对话 1-6][新消息]
前面完全相同 → 命中,只有"对话 6+新消息"按全价
```
但如果你在请求 2 里给 [CLAUDE.md](http://claude.md/) 偷偷加了一行,从 [CLAUDE.md](http://claude.md/) 往后**全部失效**,包括之前已经缓存的对话历史。
### 一个反直觉的设计细节
[CLAUDE.md](http://claude.md/) 不是拼在 system prompt 里发送的,而是通过 `<system-reminder>` 标签注入到 messages 数组。为什么?因为**同版本 Claude Code 的 system prompt 在所有用户之间字字相同**,服务端可以做全局共享缓存;如果把每个人不同的 [CLAUDE.md](http://claude.md/) 拼进 system prompt ,这个共享缓存就没了。拆开放,既保住全局共享,又让你的 [CLAUDE.md](http://claude.md/) 独立缓存。
---
## 三、5min vs 1h 两档,怎么选
| 档位 | 写入价格 | 读取价格 | 回本条件 |
| -------- | ---------------- | --------- | ------------------ |
| 5 分钟 | 1.25× 基础输入价 | 0.1× | 1 次命中即回本 |
| 1 小时 | 2× 基础输入价 | 0.1× | 2 次命中回本 |
- 高频连续工作(<5min 一次请求)→ 5min 档
- 任务间隔长、跨会议/午餐 → 1h 档
Claude Code 内部对 system prompt + 工具定义默认 5min (高频复用),用户上下文按 session 长度自动选档。
---
## 四、5 个让缓存失效的坑(最实用的部分)
### 坑 1:中途修改 [CLAUDE.md](http://claude.md/)
最常见。几轮对话后随手给 [CLAUDE.md](http://claude.md/) 加条规则——从 [CLAUDE.md](http://claude.md/) 往后全部失效,之前几轮的输入全按全价重算。 **对策**:session 开始前配好,开始后只读不改,要改先 `/new`。
### 坑 2:prompt 里塞动态内容
```plaintext
"当前时间 2026-07-21 15:23:45 ,请…"
```
时间戳、随机 ID 、UUID 只要进了前缀,缓存命中率直接归零(每次都不一样)。 **对策**:动态信息放最后一条用户消息里,别混进 system 或前置。
### 坑 3:中途切模型
不同模型缓存隔离。opus 切 sonnet ,之前的缓存直接作废。 **对策**:同任务保持模型一致,要切先 `/new`。
### 坑 4:/compact 的隐藏成本
`/compact` 的总结请求用的是**专门的总结 system prompt 、且不带工具定义**,前缀从第一个 token 就和日常缓存不同,**整个对话历史按全价计费一次**。 **对策**:别攒到几十轮才 compact ;做完一个子任务就 compact 一次(被全价的内容少);只想清空的话 `/new` 更划算。
### 坑 5:/resume 破坏缓存
`--resume` / `/resume` 在多个版本存在缓存失效——恢复后前几轮全价,可能 10–20 倍成本暴增。原因是序列化/反序列化后 messages 结构有微小差异,服务端当成新前缀。 **对策**:长任务尽量一个连续 session 做完;不得不断,宁可新 session 简短复述,也别 resume 。
---
## 五、怎么确认缓存真的命中了
看响应里的 usage 字段:
```json
{
"usage": {
"input_tokens": 245,
"cache_creation_input_tokens": 3120,
"cache_read_input_tokens": 8450,
"output_tokens": 412
}
}
```
- `cache_creation_input_tokens`:本次写入缓存( 1.25× 或 2×)
- `cache_read_input_tokens`:本次命中( 0.1×)
- 连续 session 第 N 轮( N>1 ),`cache_read` 应远大于 `input_tokens`
- 如果 `cache_read` 一直是 0 ,前缀肯定哪里被破坏了,照上面 5 个坑排查
---
## 六、三条核心原则
1. **保持前缀稳定**——别中途改 [CLAUDE.md](http://claude.md/) 、加时间戳、切模型
2. **同任务一气呵成**——长 session 比频繁 resume 划算
3. **/compact 早用别攒**——越晚 compact 被全价的内容越多
[CLAUDE.md](http://claude.md/) 我个人保持在 50 行以内,当"索引"用(列关键文件路径、命令、约定),详细文档放 `docs/` 让 Claude Code 自己 Read——既省 token 又不容易失效。
以上是我自己的实践,有不同经验欢迎评论区交流。
*基于 Claude Code 1.x 与 Anthropic 官方文档,如有错误欢迎指正。
---
原文链接:[点击查看](https://www.v2ex.com/t/1229144)
· 0 个赞
· 0 个赞