# Claude Code Prompt 缓存

> Claude Code 自动 prompt caching、5 分钟与 1 小时 TTL、缓存失效动作、MCP/tool search 和成本字段解释。

URL: https://docs.passion8.cc/docs/claude-code/prompt-caching
Language: zh-CN
Publisher: Passion8

Claude Code 会自动使用 prompt caching。你通常不需要手写 `cache_control`,但需要知道哪些操作会让下一轮变慢、变贵,以及 5 分钟和 1 小时缓存到底差在哪。

逐命令缓存影响已经单独整理到 [命令与缓存影响](https://docs.passion8.cc/docs/claude-code/command-cache)。这页解释底层规则和排查方法。

## 一句话理解

每一轮请求都会把系统提示、项目上下文、历史对话、工具结果和新消息重新发送给模型。缓存命中时,上游不再重新处理相同前缀,只处理新追加的部分。




缓存匹配的是“从请求开头开始的完全一致前缀”。前缀中任何位置变了,后面的内容都要重新处理。




## Claude Code 的上下文层

| 层 | 包含什么 | 常见变化点 |
| --- | --- | --- |
| System prompt | 核心指令、工具定义、output style | 升级 CLI、工具定义变化、输出风格重建 |
| Project context | `CLAUDE.md`、auto memory、无条件 rules | 启动、`/clear`、`/compact` |
| Conversation | 用户消息、Claude 回复、工具结果 | 每一轮都会追加 |

越靠前的层越重要。System prompt 变了,后面全部失效。Conversation 只是在末尾追加,通常最容易命中缓存。

缓存 key 还包含:

- 模型:换模型会全量 miss
- effort level:换 `/effort` 会全量 miss
- fast mode header:首次开启可能重新建缓存

`/advisor` 是一个特别例子:官方说明 advisor tool 定义位于缓存断点之后,开关它通常不会破坏已有缓存前缀。

## 5 分钟 vs 1 小时

| 项目 | 5 分钟 TTL | 1 小时 TTL |
| --- | --- | --- |
| 默认对象 | API key、Bedrock、Vertex、Foundry、Claude Platform on AWS、第三方 provider | Claude subscription 在计划额度内 |
| 写入成本 | API 价格约 1.25 倍输入价 | API 价格约 2 倍输入价 |
| 读取成本 | 按当前模型缓存读取价格；不同系列比例不同 | 同样按模型缓存读取价格 |
| 适合 | 连续追问、短间隔迭代 | 大上下文、间隔更长的多轮工作 |
| 如何启用 | 默认,不需要配置 `ENABLE_PROMPT_CACHING_1H` | 显式设置 `ENABLE_PROMPT_CACHING_1H=1` |
| 如何强制 | `FORCE_PROMPT_CACHING_5M=1` | 不适用 |

命中缓存会刷新 TTL。也就是说,5 分钟不是总时长,而是“多久没用就过期”。




API key 和第三方 provider 默认是 5 分钟 TTL。不要把 `ENABLE_PROMPT_CACHING_1H=1` 放进通用模板;只有明确需要长间隔复用大上下文时再开启。Claude subscription 在包含额度内会自动请求 1 小时 TTL。超过计划限制后如果使用 usage credits,Claude Code 会降回 5 分钟 TTL。




## 会让缓存失效的操作

| 操作 | 为什么 |
| --- | --- |
| `/model` 换模型 | 每个模型独立 cache |
| `/effort` 换思考强度 | effort level 是 cache key |
| 中途开启 fast mode | 请求 header 参与 cache key |
| `opusplan` 进出 plan mode | 可能在 Opus 和 Sonnet 之间切换 |
| fallback model 触发 | 该轮换到备用模型,另建缓存 |
| MCP server 连接/断开 | 工具定义可能进入 system prompt |
| 启用/禁用带 MCP 的插件 | MCP 工具集变化 |
| 整个工具被 deny | 工具从上下文移除 |
| `/compact` | 历史被摘要替换,conversation 层变了 |
| 升级 Claude Code | system prompt 或工具定义变了 |

MCP 是否影响缓存,取决于工具定义是否 deferred。支持 tool search 时,工具通常延迟加载,对缓存更友好。自定义网关、Vertex 或不支持 tool search 的模型上,工具可能全部进入前缀,连接变化就更容易 miss。

## 不会立即失效,但也不立即生效

| 操作 | 结果 |
| --- | --- |
| 修改项目文件 | 只是在对话里追加“文件变了”提醒 |
| 修改根级 `CLAUDE.md` | 当前会话继续用旧版本 |
| 修改 `outputStyle` | 当前系统提示不变 |
| 切权限模式 | 通常不影响 prompt |
| 调用 skill/command | 作为消息追加到对话末尾 |
| `/recap` | 生成摘要并追加输出,不替换历史 |
| `/cd` | 尽量保留 conversation cache,新目录信息追加为消息 |
| `/advisor` | 工具定义在缓存断点后,通常不破坏旧前缀 |
| `/btw` | 旁路问题不进入主 conversation |
| `/goal` | 目标状态不改变 system prompt,后续推进按普通消息追加 |
| `/loop` | 每次触发是普通新轮次,间隔决定 TTL 是否还热 |
| `/rewind` | 回退到旧前缀,通常还能命中早前缓存 |
| `/statusline` | 脚本刷新本地执行,不调用模型 |
| `/usage`、`/cost` | 只查看用量,不改变 prompt 前缀 |
| 开启 OTel | 不改变 prompt,通常不影响缓存 |

根级 `CLAUDE.md` 和 `outputStyle` 的新内容会在 `/clear`、`/compact` 或重启后加载。

## `/compact` 的成本

`/compact` 会发一次摘要请求。这个摘要请求通常能读取现有缓存,因为它是在当前历史后追加一条“请总结”的指令。

真正变化发生在摘要完成后:旧历史被短摘要替换,下一轮会为这个更短的新 conversation 重建缓存。正确用法是:

- 在任务自然结束时 compact
- 不要等自动 compact 在关键步骤中间触发
- 想放弃错误方向时优先 `/rewind`,不是 `/compact`

## 子代理与 fork

[子代理](https://docs.passion8.cc/docs/claude-code/subagents) 会启动自己的对话,拥有独立上下文和独立缓存。它第一次调用通常没有缓存命中,之后在自己的多轮任务中逐步变暖。官方说明里,子代理使用 5 分钟 TTL,即使主会话在 Claude subscription 下自动使用 1 小时 TTL。

从主会话角度看,子代理调用和最终结果只是追加到 conversation 末尾,不会破坏主会话旧前缀。

`/fork` 或 `/branch` 更接近复制当前对话。fork 继承父会话已有系统提示、工具和历史,如果还在 TTL 内,第一轮更容易读到父会话缓存。`--worktree` 主要隔离文件系统和 Git 分支,详见 [Worktrees 并行工作区](https://docs.passion8.cc/docs/claude-code/worktrees)。

## 观测字段

Claude API usage 里有两个关键字段:

| 字段 | 含义 |
| --- | --- |
| `cache_creation_input_tokens` | 本轮写入缓存的 token,按缓存写入价计费 |
| `cache_read_input_tokens` | 本轮从缓存读取的 token，按当前模型与本站缓存读取价格计费 |

读写比越高,缓存越健康。如果 creation 每轮都高,说明前缀在变。优先检查模型、effort、output style、MCP、工具 deny、`/compact` 和 CLI 升级。

在 Passion8 或其他 `ANTHROPIC_BASE_URL` 网关下,还要确认网关是否原样转发 `anthropic-beta`、工具 schema、`output_config`、`context_management`、cache 字段和 usage 字段。详见 [网关与协议](https://docs.passion8.cc/docs/claude-code/gateway)。

## 禁用或强制 TTL

```bash
# 禁用全部 prompt caching
export DISABLE_PROMPT_CACHING=1

# 只禁用某类模型
export DISABLE_PROMPT_CACHING_SONNET=1
export DISABLE_PROMPT_CACHING_OPUS=1
export DISABLE_PROMPT_CACHING_HAIKU=1
export DISABLE_PROMPT_CACHING_FABLE=1

# 可选:API/provider 场景请求 1 小时 TTL
export ENABLE_PROMPT_CACHING_1H=1

# 强制 5 分钟 TTL,覆盖 1 小时设置
export FORCE_PROMPT_CACHING_5M=1
```

正常使用不要禁用缓存。禁用只适合排错。

## 缓存友好工作流





### 开局定模型和 effort


```text
先用 /model 和 /effort 定好本次任务配置。
任务中途不要频繁切。
```




### 稳定信息放前面


项目规则放 `CLAUDE.md`,任务范围先说清楚。不要把临时报错、长日志、随手待办写进长期记忆。




### 自然断点 compact


一个任务完成后再 `/compact`。如果要换完全不同的任务,直接 `/clear`。







## 官方参考

- [How Claude Code uses prompt caching](https://code.claude.com/docs/en/prompt-caching.md)
- [Commands](https://code.claude.com/docs/en/commands.md)
- [Model configuration](https://code.claude.com/docs/en/model-config.md)
- [Gateway protocol reference](https://code.claude.com/docs/en/llm-gateway-protocol.md)
- [Claude API prompt caching](https://platform.claude.com/docs/en/build-with-claude/prompt-caching.md)
- [Output styles](https://code.claude.com/docs/en/output-styles.md)
- [Status line](https://code.claude.com/docs/en/statusline.md)
- [Manage costs effectively](https://code.claude.com/docs/en/costs.md)
