Claude 提示缓存机制深度解析:自动缓存、显式断点与 20 块回顾窗口
Claude 提示缓存机制深度解析:自动缓存、显式断点与 20 块回顾窗口
引言
在使用 Claude API 构建对话应用时,提示缓存(Prompt Caching)是降低成本和延迟的关键功能。然而,官方文档中关于缓存回顾机制的一些细节容易被忽视,特别是"20 块回顾窗口"这一限制。本文将深入剖析这个机制,帮助你避免实践中可能遇到的坑。
什么是提示缓存?
提示缓存允许你标记提示中的某个位置,系统会将该位置之前的内容缓存起来。下次请求如果前缀相同,直接从缓存读取,无需重复处理。
缓存有两种启用方式:
| 方式 | 做法 | 适用场景 |
|---|---|---|
| 自动缓存 | 在请求顶层加cache_control,系统自动在最后一个可缓存块上放置断点 | 多轮对话,简单省心 |
| 显式缓存 | 在具体内容块上手动放置cache_control | 需要精确控制缓存边界 |
核心概念:断点、缓存写入与回顾窗口
要理解缓存机制,必须区分三个概念:
| 概念 | 含义 |
|---|---|
断点(cache_control) | 你标记的位置,告诉系统"从这里往回找缓存",同时也是新缓存的写入位置 |
| 缓存写入(cache write) | 系统在断点处实际存储的缓存条目,包含从开头到该位置的全部内容 |
| 回顾窗口(lookback window) | 系统从断点往回查找已有缓存条目的范围,固定为 20 个块 |
关键规则:系统只会往回找 20 个块。如果之前的缓存写入位置距离当前断点超过 20 个块,就会缓存未命中。
这条规则对自动缓存和显式缓存都同样适用,因为它们共用同一套底层基础设施。
用"书签"来理解这个机制
把缓存想象成在书里夹书签:
- 每次在某个块设置
cache_control,就在那一页夹了一张书签 - 下次翻开书时,从当前位置往前翻 20 页来找书签
- 如果书签在第 15 页,而你翻到了第 35 页,往前翻 20 页只能到第 16 页——书签刚好差一页没看到
这就是 20 块回顾窗口的直观含义。
一步步拆解:缓存如何随着对话增长
第 1 轮:建立初始缓存
块 1, 2, 3, 4, 5, 6, 7, 8, 9, [10] ← 断点,写入缓存你在第 10 块设置断点,系统将块 1~10 存入缓存。
第 2 轮:命中缓存,写入新缓存
块 1...10, 11, 12, 13, 14, [15] ← 断点 ↑ 在位置 10 找到缓存,命中!对话增长到 15 个块。系统从第 15 块往回找,在第 10 块找到缓存。块 1~10 直接从缓存读取,只处理 11~15,然后在第 15 块写入新缓存。
第 3 轮:缓存失效
块 1...15, 16, 17, ... , 34, [35] ← 从这往回找 20 块 ↑ 只能到 16 [15] ← 缓存在这,刚好在范围外!对话增长到 35 个块。系统从第 35 块往回找 20 块(35 到 16),上次的缓存在第 15 块,刚好差一个没找到。缓存完全未命中,所有内容都要重新处理。
解决方案:多放一个断点
在同一个请求中设置多个cache_control:
块 1...10... [15] ... [35] ↑ ↑ ↑ 旧缓存 显式断点 自动/末尾断点系统会开启两个独立的回顾窗口:
- 从位置 35 往回找 20 块 → 没找到
- 从位置 15 往回找 → 在位置 10 找到缓存 ✅
这样块 1~15 从缓存读取,仅处理 16~35,缓存命中得以保持。
自动缓存的"坑"
自动缓存虽然方便,但它只在最后一个可缓存块上放置断点。这意味着:
| 场景 | 结果 |
|---|---|
| 每轮新增< 20 块 | 末尾断点能回溯到上次写入 → ✅ 命中 |
| 每轮新增≥ 20 块 | 末尾断点够不着上次写入 → ❌ 失效 |
对于长对话应用,纯自动缓存迟早会碰上这个限制。
最佳实践
推荐做法:自动缓存 + 显式断点搭配使用
请求结构: ┌─ 系统提示 + [显式断点] ← 锚点,始终保留 ├─ 历史对话... └─ 最新消息 ← 自动缓存负责末尾断点在对话早期的关键位置(如系统提示末尾、前几轮结束处)放置一个显式断点作为"锚点"。这个锚点始终在回顾窗口范围内,确保无论对话多长都能命中缓存。
其他关键注意事项
- 断点放在不变的内容上:如果断点放在每次请求都变化的内容(如时间戳、新用户消息)上,前缀哈希每次不同,永远无法命中缓存
- 最小令牌阈值:不同模型有最低缓存长度要求(1,024 到 4,096 令牌不等),短于此长度的内容即使标记了也不会被缓存
- 缓存 TTL:默认 5 分钟,可选择 1 小时(价格翻倍)
- 最多 4 个断点:自动缓存的隐式断点也会占用一个名额
- 缓存预热:使用
max_tokens: 0在用户请求到来前预先加载缓存,消除首次延迟
总结
Claude 提示缓存的核心约束可以归结为一句话:
系统从每个断点最多往回查找 20 个块。纯自动缓存在长对话中会因为回顾窗口限制而失效,最佳方案是搭配显式断点作为锚点,确保缓存命中覆盖整个对话生命周期。
理解了这个机制,你就能在构建 Claude 应用时充分发挥缓存的价值——既节省成本,又降低延迟。
本文基于 Anthropic 官方文档及对缓存机制的深入探讨整理而成。
