提示词缓存是一项强大的功能,通过允许从提示词中的特定前缀恢复来优化您的 API 使用。这种方法可显著减少重复任务或具有一致元素的提示词的处理时间和成本。
以下是如何使用 Messages API 和 cache_control 块实现提示词缓存的示例:
curl https://api.anthropic.com/v1/messages \
-H "content-type: application/json" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-d '{
"model": "claude-sonnet-4-5",
"max_tokens": 1024,
"system": [
{
"type": "text",
"text": "You are an AI assistant tasked with analyzing literary works. Your goal is to provide insightful commentary on themes, characters, and writing style.\n"
},
{
"type": "text",
"text": "<the entire contents of Pride and Prejudice>",
"cache_control": {"type": "ephemeral"}
}
],
"messages": [
{
"role": "user",
"content": "Analyze the major themes in Pride and Prejudice."
}
]
}'
# Call the model again with the same inputs up to the cache checkpoint
curl https://api.anthropic.com/v1/messages # rest of input{"cache_creation_input_tokens":188086,"cache_read_input_tokens":0,"input_tokens":21,"output_tokens":393}
{"cache_creation_input_tokens":0,"cache_read_input_tokens":188086,"input_tokens":21,"output_tokens":393}在此示例中,整个《傲慢与偏见》文本使用 cache_control 参数进行缓存。这使得可以在多个 API 调用中重复使用这个大型文本,而无需每次都重新处理。仅更改用户消息允许您提出有关该书的各种问题,同时利用缓存的内容,从而实现更快的响应和提高的效率。
当您发送启用了提示词缓存的请求时:
这对以下情况特别有用:
默认情况下,缓存的生命周期为 5 分钟。每次使用缓存的内容时,缓存都会以零额外成本刷新。
提示词缓存缓存完整前缀
提示词缓存引用整个提示词 - tools、system 和 messages(按该顺序)直到并包括用 cache_control 指定的块。
提示词缓存引入了新的定价结构。下表显示了每个支持的模型每百万个令牌的价格:
| Model | Base Input Tokens | 5m Cache Writes | 1h Cache Writes | Cache Hits & Refreshes | Output Tokens |
|---|---|---|---|---|---|
| Claude Opus 4.5 | $5 / MTok | $6.25 / MTok | $10 / MTok | $0.50 / MTok | $25 / MTok |
| Claude Opus 4.1 | $15 / MTok | $18.75 / MTok | $30 / MTok | $1.50 / MTok | $75 / MTok |
| Claude Opus 4 | $15 / MTok | $18.75 / MTok | $30 / MTok | $1.50 / MTok | $75 / MTok |
| Claude Sonnet 4.5 | $3 / MTok | $3.75 / MTok | $6 / MTok | $0.30 / MTok | $15 / MTok |
| Claude Sonnet 4 |
上表反映了提示词缓存的以下定价倍数:
提示词缓存目前支持:
将静态内容(工具定义、系统指令、上下文、示例)放在提示词的开头。使用 cache_control 参数标记可重用内容的结尾以进行缓存。
缓存前缀按以下顺序创建:tools、system,然后 messages。此顺序形成一个层次结构,其中每个级别都建立在前一个级别之上。
您可以在静态内容的末尾使用单个缓存断点,系统将自动找到最长的匹配缓存块序列。了解这如何工作有助于您优化缓存策略。
三个核心原则:
缓存键是累积的:当您使用 cache_control 显式缓存块时,缓存哈希键是通过按顺序对话中所有先前块进行哈希生成的。这意味着每个块的缓存取决于其之前的所有内容。
向后顺序检查:系统通过从您的显式断点向后工作来检查缓存命中,按相反顺序检查每个先前的块。这确保您获得最长的可能缓存命中。
20 块回溯窗口:系统仅检查每个显式 cache_control 断点之前的最多 20 个块。在检查 20 个块而未找到匹配后,它停止检查并移动到下一个显式断点(如果有)。
示例:理解回溯窗口
考虑一个有 30 个内容块的对话,其中您仅在块 30 上设置 cache_control:
如果您发送块 31 且不更改先前的块:系统检查块 30(匹配!)。您在块 30 处获得缓存命中,仅块 31 需要处理。
如果您修改块 25 并发送块 31:系统从块 30 向后检查 → 29 → 28... → 25(无匹配)→ 24(匹配!)。由于块 24 未更改,您在块 24 处获得缓存命中,仅块 25-30 需要重新处理。
如果您修改块 5 并发送块 31:系统从块 30 向后检查 → 29 → 28... → 11(检查 #20)。在 20 次检查后未找到匹配,它停止查找。由于块 5 超出 20 块窗口,不会发生缓存命中,所有块都需要重新处理。但是,如果您在块 5 上设置了显式 cache_control 断点,系统将继续从该断点检查:块 5(无匹配)→ 块 4(匹配!)。这允许在块 4 处缓存命中,演示了为什么应该在可编辑内容之前放置断点。
关键要点:始终在对话末尾设置显式缓存断点以最大化缓存命中的机会。此外,在可能可编辑的内容块之前设置断点,以确保这些部分可以独立缓存。
如果您想要以下情况,可以定义最多 4 个缓存断点:
重要限制:如果您的提示词在缓存断点之前有超过 20 个内容块,并且您修改了这 20 个块之前的内容,除非您添加更接近该内容的额外显式断点,否则您不会获得缓存命中。
最小可缓存提示词长度为:
较短的提示词无法缓存,即使标记了 cache_control。任何缓存少于此令牌数的请求都将在不缓存的情况下处理。要查看提示词是否被缓存,请参阅响应使用 字段。
对于并发请求,请注意缓存条目仅在第一个响应开始后才可用。如果您需要并行请求的缓存命中,请在发送后续请求之前等待第一个响应。
目前,"ephemeral"是唯一支持的缓存类型,默认生命周期为 5 分钟。
缓存断点本身不会增加任何成本。 您仅需支付:
添加更多 cache_control 断点不会增加您的成本 - 您仍然根据实际缓存和读取的内容支付相同的金额。断点只是让您控制哪些部分可以独立缓存。
请求中的大多数块都可以使用 cache_control 指定为缓存。这包括:
tools 数组中的工具定义system 数组中的内容块messages.content 数组中的内容块,用于用户和助手轮次messages.content 数组中的内容块,在用户轮次中messages.content 数组中的内容块,在用户和助手轮次中这些元素中的每一个都可以用 cache_control 标记以启用该部分请求的缓存。
虽然大多数请求块可以缓存,但有一些例外:
思考块无法直接用 cache_control 缓存。但是,当思考块出现在先前的助手轮次中时,它们可以与其他内容一起缓存。以这种方式缓存时,它们在从缓存读取时确实计为输入令牌。
子内容块(如 引用)本身无法直接缓存。相反,缓存顶级块。
在引用的情况下,作为引用源材料的顶级文档内容块可以缓存。这允许您通过缓存引用将引用的文档来有效地使用提示词缓存。
空文本块无法缓存。
对缓存内容的修改可能会使部分或全部缓存失效。
如 构建您的提示词 中所述,缓存遵循层次结构:tools → system → messages。每个级别的更改都会使该级别及所有后续级别失效。
下表显示了不同类型的更改会使缓存的哪些部分失效。✘ 表示缓存失效,✓ 表示缓存保持有效。
| 什么改变 | 工具缓存 | 系统缓存 | 消息缓存 | 影响 |
|---|---|---|---|---|
| 工具定义 | ✘ | ✘ | ✘ | 修改工具定义(名称、描述、参数)会使整个缓存失效 |
| 网络搜索切换 | ✓ | ✘ | ✘ | 启用/禁用网络搜索会修改系统提示词 |
| 引用切换 | ✓ | ✘ | ✘ | 启用/禁用引用会修改系统提示词 |
| 工具选择 | ✓ | ✓ | ✘ | 对 tool_choice 参数的更改仅影响消息块 |
| 图像 | ✓ | ✓ | ✘ | 在提示词中的任何位置添加/删除图像会影响消息块 |
使用这些 API 响应字段监控缓存性能,在响应中的 usage 内(或如果 流式传输 则为 message_start 事件):
cache_creation_input_tokens:创建新缓存条目时写入缓存的令牌数。cache_read_input_tokens:为此请求从缓存检索的令牌数。input_tokens:未从缓存读取或用于创建缓存的输入令牌数(即最后一个缓存断点之后的令牌)。理解令牌分解
input_tokens 字段仅表示请求中最后一个缓存断点之后的令牌 - 不是您发送的所有输入令牌。
要计算总输入令牌:
total_input_tokens = cache_read_input_tokens + cache_creation_input_tokens + input_tokens空间解释:
cache_read_input_tokens = 断点之前已缓存的令牌(读取)cache_creation_input_tokens = 断点之前现在被缓存的令牌(写入)input_tokens = 最后一个断点之后的令牌(不符合缓存条件)示例: 如果您有一个请求,其中有 100,000 个令牌的缓存内容(从缓存读取),0 个令牌的新内容被缓存,以及 50 个令牌在您的用户消息中(在缓存断点之后):
cache_read_input_tokens:100,000cache_creation_input_tokens:0input_tokens:50要优化提示词缓存性能:
根据您的场景定制提示词缓存策略:
如果遇到意外行为:
tool_choice 和图像使用在调用之间保持一致cache_control 参数,以确保所有内容都可以缓存tool_use 内容块中的键具有稳定的排序,因为某些语言(例如 Swift、Go)在 JSON 转换期间随机化键顺序,破坏缓存对 tool_choice 的更改或提示词中任何位置的图像的存在/不存在将使缓存失效,需要创建新的缓存条目。有关缓存失效的更多详情,请参阅 什么使缓存失效。
当使用 扩展思考 与提示词缓存时,思考块具有特殊行为:
与其他内容自动缓存:虽然思考块无法使用 cache_control 显式标记,但当您使用工具结果进行后续 API 调用时,它们会作为请求内容的一部分被缓存。这通常在工具使用期间发生,当您将思考块传回以继续对话时。
输入令牌计数:当思考块从缓存读取时,它们在您的使用指标中计为输入令牌。这对于成本计算和令牌预算很重要。
缓存失效模式:
cache_control 标记,也会发生此缓存行为有关缓存失效的更多详情,请参阅 什么使缓存失效。
工具使用示例:
请求 1:用户:"巴黎的天气怎么样?"
响应:[thinking_block_1] + [tool_use block 1]
请求 2:
用户:["巴黎的天气怎么样?"],
助手:[thinking_block_1] + [tool_use block 1],
用户:[tool_result_1, cache=True]
响应:[thinking_block_2] + [text block 2]
# 请求 2 缓存其请求内容(不是响应)
# 缓存包括:用户消息、thinking_block_1、tool_use block 1 和 tool_result_1
请求 3:
用户:["巴黎的天气怎么样?"],
助手:[thinking_block_1] + [tool_use block 1],
用户:[tool_result_1, cache=True],
助手:[thinking_block_2] + [text block 2],
用户:[Text response, cache=True]
# 非工具结果用户块指定新的助手循环,所有先前的思考块都被忽略
# 此请求的处理方式就像思考块从未存在过一样当包含非工具结果用户块时,它指定新的助手循环,所有先前的思考块都从上下文中删除。
有关更多详细信息,请参阅 扩展思考文档。
组织隔离:缓存在组织之间隔离。不同的组织永远不会共享缓存,即使他们使用相同的提示词。
精确匹配:缓存命中需要 100% 相同的提示词段,包括直到并包括用缓存控制标记的块的所有文本和图像。
输出令牌生成:提示词缓存对输出令牌生成没有影响。您收到的响应将与不使用提示词缓存时获得的响应相同。
如果您发现 5 分钟太短,Anthropic 还提供 1 小时缓存时长需额外付费。
要使用扩展缓存,在 cache_control 定义中包含 ttl,如下所示:
"cache_control": {
"type": "ephemeral",
"ttl": "5m" | "1h"
}响应将包含详细的缓存信息,如下所示:
{
"usage": {
"input_tokens": ...,
"cache_read_input_tokens": ...,
"cache_creation_input_tokens": ...,
"output_tokens": ...,
"cache_creation": {
"ephemeral_5m_input_tokens": 456,
"ephemeral_1h_input_tokens": 100,
}
}
}请注意,当前 cache_creation_input_tokens 字段等于 cache_creation 对象中值的总和。
如果您有定期使用的提示词(即每 5 分钟以上使用一次的系统提示词),继续使用 5 分钟缓存,因为这将继续以零额外成本刷新。
1 小时缓存最适合用于以下场景:
5 分钟和 1 小时缓存在延迟方面的行为相同。对于长文档,您通常会看到改进的首令牌时间。
您可以在同一请求中使用 1 小时和 5 分钟缓存控制,但有一个重要的限制:具有较长 TTL 的缓存条目必须出现在较短 TTL 之前(即 1 小时缓存条目必须出现在任何 5 分钟缓存条目之前)。
混合 TTL 时,我们在提示词中确定三个计费位置:
A:最高缓存命中处的令牌计数(如果没有命中则为 0)。B:A 之后最高 1 小时 cache_control 块处的令牌计数(如果不存在则等于 A)。C:最后一个 cache_control 块处的令牌计数。如果 B 和/或 C 大于 A,它们必然是缓存未命中,因为 A 是最高缓存命中。
您将被收费:
A 处的缓存读取令牌。(B - A) 处的 1 小时缓存写入令牌。(C - B) 处的 5 分钟缓存写入令牌。以下是 3 个示例。这描绘了 3 个请求的输入令牌,每个请求都有不同的缓存命中和缓存未命中。每个都有不同的计算定价,如彩色框所示。
为了帮助您开始使用提示词缓存,我们准备了一个提示词缓存食谱,其中包含详细的示例和最佳实践。
下面,我们包含了几个代码片段,展示了各种提示词缓存模式。这些示例演示了如何在不同场景中实现缓存,帮助您理解此功能的实际应用:
| $3 / MTok |
| $3.75 / MTok |
| $6 / MTok |
| $0.30 / MTok |
| $15 / MTok |
| Claude Sonnet 3.7 (deprecated) | $3 / MTok | $3.75 / MTok | $6 / MTok | $0.30 / MTok | $15 / MTok |
| Claude Haiku 4.5 | $1 / MTok | $1.25 / MTok | $2 / MTok | $0.10 / MTok | $5 / MTok |
| Claude Haiku 3.5 | $0.80 / MTok | $1 / MTok | $1.6 / MTok | $0.08 / MTok | $4 / MTok |
| Claude Opus 3 (deprecated) | $15 / MTok | $18.75 / MTok | $30 / MTok | $1.50 / MTok | $75 / MTok |
| Claude Haiku 3 | $0.25 / MTok | $0.30 / MTok | $0.50 / MTok | $0.03 / MTok | $1.25 / MTok |
| 思考参数 | ✓ | ✓ | ✘ | 对扩展思考设置(启用/禁用、预算)的更改会影响消息块 |
| 传递给扩展思考请求的非工具结果 | ✓ | ✓ | ✘ | 当在启用扩展思考的请求中传递非工具结果时,所有先前缓存的思考块都会从上下文中删除,任何在这些思考块之后的上下文中的消息都会从缓存中删除。有关更多详情,请参阅 使用思考块缓存。 |
这对于理解成本和速率限制很重要,因为在有效使用缓存时,input_tokens 通常会比您的总输入小得多。