做RAG问答、文档分析或者多轮Agent应用的开发者,对Claude API的账单应该深有体会:每次请求都要重新发送几十万token的上下文,输入费用占了大头,响应的首字延迟也被长提示词拖慢。Anthropic为此推出了Prompt Caching功能,允许把请求中稳定不变的前缀部分缓存下来,后续请求直接复用,读取缓存的价格只有正常输入token的十分之一。这篇文章详细讲讲它的工作原理、具体配置和实战中的优化技巧。

Prompt Caching的工作原理与计费模型
要理解Prompt Caching,先要看清楚一个请求的token结构。Claude的API是无状态的,每次请求都会把完整上下文重新发给服务器。一个典型请求可以拆成三部分:系统提示词、工具定义、历史消息与当前输入。前两部分在多次请求之间几乎不变,历史消息在多轮对话中也是逐步追加的。Prompt Caching的核心思路就是利用这种前缀稳定性,把请求开头的一段内容写入缓存,后续请求只要前缀完全一致,就能直接命中。
计费上分两种情况:写入缓存的那次请求,对应token按基础输入价格的1.25倍收费,这是为了覆盖存储成本;命中缓存之后的读取,只按基础价格的0.1倍收费。举个例子,假设输入价格是每百万token 3美元,一段10万token的系统提示词加文档,第一次写入花费约0.375美元,之后每次命中只需0.03美元。如果这段前缀被复用50次,不缓存的总成本是15美元,缓存后只有大约1.9美元,降幅非常可观。缓存默认保留5分钟,每次命中会刷新这个时间窗口,所以在高频对话场景中基本不用担心过期。
需要注意的一点是,缓存匹配是严格的前缀匹配。系统会从请求的第一个token开始逐字节比对,一旦出现差异就停止匹配。这意味着哪怕你在系统提示词里插入了一个动态时间戳,整个缓存都会失效。设计提示词结构时,一定要把会变化的内容放到消息末尾,把稳定的内容放在前面。
cache_control的配置方法与断点设置
启用Prompt Caching不需要改接口路径,只需要在messages或system字段上添加cache_control标记。目前推荐的做法是在目标内容块的末尾打一个缓存断点,API会缓存从请求开头到断点为止的所有内容。下面是一个Python调用示例:
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
system=[
{
"type": "text",
"text": "你是一个专业的法律文档分析助手,以下是完整的合同文本:\n" + long_contract_text,
"cache_control": {"type": "ephemeral"} # 缓存断点,缓存到此处为止
}
],
messages=[
{"role": "user", "content": "请总结这份合同的主要风险条款"}
]
)
print(response.usage)
# 输出中包含 cache_read_input_tokens 和 cache_creation_input_tokens
一个请求最多可以设置4个断点,这在实际开发中非常实用。典型的多断点布局是:第一个断点放在系统提示词末尾,第二个放在工具定义之后,第三个放在长文档内容末尾,最后一个放在对话历史的最新位置。这样层层递进的缓存结构,可以在对话不断延长时,仍然命中前面的大段缓存,只有新增的部分需要重新写入。判断缓存是否生效,直接看响应里usage字段的cache_read_input_tokens,如果这个值一直是0,说明缓存没有命中,需要排查前缀是否有变动。
断点位置的选择还有个细节:缓存的最小长度要求是1024个token(Sonnet系列,其他模型可能更高)。如果标记断点的内容块太短,缓存不会生效,API也不会报错,只是静默忽略,这一点容易让人误以为功能有问题。建议把频繁引用的大段参考资料、few-shot示例统一放在前面,一个断点覆盖全部。
典型应用场景与常见问题排查
第一个场景是多轮对话。很多人把整段对话历史直接传回去,但只要历史里的内容逐字不变,配合递进式断点,每一轮都能命中大部分缓存。注意不要在前端对历史消息做任何加工,比如重排、删减中间轮次或者补充时间标记,任何字符级改动都会让缓存失效。
第二个场景是工具密集的Agent。工具定义通常占据大量token,且在会话期间完全不变,是理想的缓存对象。把tools列表放在system之后、messages之前的位置,并在工具定义结束处设置断点。工具本身的schema是不支持cache_control字段的,需要把断点打在紧随其后的system块或者第一条消息上,这是文档里容易被忽略的细节。
第三个场景是结合extended thinking推理模式。开启thinking后,模型的思考过程不计入缓存前缀,但系统提示词、工具、历史消息仍然可以正常缓存,两者互不冲突。需要注意的是,thinking的预算参数建议在会话期间保持一致,因为interleaved thinking场景下请求结构的变化也可能影响前缀匹配。
排查缓存未命中,可以从这几个方向入手:检查是否在messages和system中使用了模板字符串拼接了动态内容;确认每个缓存段的长度是否超过最低阈值;查看是否超过了4个断点的上限导致后面的标记被忽略;如果是异步并发请求,注意第一个写入缓存的请求完成前,并发的其他请求无法命中,可以错开几百毫秒。另外,缓存的计费数据在控制台的usage报表里有单独分类,上线前建议用少量请求验证一遍计费数字是否符合预期,确保优化真正落到了账单上。
Claude APIPrompt Caching长上下文推理修改时间:2026-09-08 23:17:01