Anthropic Prompt Caching 如何判断命中:cache_control 边界与成本核对
线上客服机器人把同一份产品手册反复发给 Claude,输入 token 很快就成了主要成本。Prompt Caching 能复用这段稳定前缀,但只写上 cache_control 并不等于每次都命中:断点放在会变化的用户问题上,结果仍可能是一次次缓存写入。真正可靠的做法是把断点放在“最后一个稳定区块”,再读取响应里的 usage 字段验收。
判断一次请求是否命中,先看
cache_read_input_tokens是否大于 0;如果只有cache_creation_input_tokens,这次是写缓存,不是读缓存。
tools → system → messages是缓存前缀的形成顺序,断点前的内容共同决定缓存键。- 会变化的时间戳、用户问题不要放在缓存断点里,断点应落在稳定前缀的最后一个区块。
- 默认 TTL 是 5 分钟;需要更长复用窗口时可使用 1 小时 TTL,但写入价格更高。
- 验收时同时记录
cache_creation_input_tokens、cache_read_input_tokens和普通input_tokens,不要只凭延迟猜命中。
先分清“写入缓存”和“读取缓存”
Anthropic 的缓存命中是前缀级别的。系统会把 tools、system、messages 按顺序拼成可检查的前缀,在指定的 cache_control 断点处尝试复用。第一次请求通常没有可读的旧条目,它会产生缓存写入;下一次请求只有在前缀匹配时才会出现缓存读取。
因此,业务日志里最好把三类 token 分开。cache_creation_input_tokens 表示本次写入了多少输入 token,cache_read_input_tokens 表示从已有缓存读取了多少输入 token,而 input_tokens 仍包含没有从缓存读取的输入部分。
把 cache_control 放在稳定前缀末尾
下面的示例把产品手册放在 system 内容里,把每次变化的客户问题放在 user 消息里。断点落在产品手册末尾,后面的问题不会改变缓存前缀。示例中的 cache_control、cache_read_input_tokens 和 cache_creation_input_tokens 都是需要在真实响应中核对的字段。
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="YOUR_CLAUDE_MODEL",
max_tokens=512,
system=[
{
"type": "text",
"text": "产品手册:退款条件、发货范围、售后联系方式……",
"cache_control": {"type": "ephemeral"}
}
],
messages=[
{"role": "user", "content": "客户问题:订单已经发出,还能修改收货地址吗?"}
]
)
print(response.usage.model_dump())
这里有一个容易忽略的边界:如果把当前时间、请求编号或客户问题也放进同一个断点之前,前缀就会随请求变化。缓存系统不会替你从变化内容后面“猜”出稳定部分;它只会在已写入的断点附近寻找可复用条目。

为什么同一份手册仍可能没有命中
缓存不是任意短文本的免费标记。当前文档为不同 Claude 模型定义了最小可缓存 token 数,短于对应门槛时,请求可以正常返回,但两个缓存 usage 字段都可能为 0。工程上应先确认稳定前缀足够长,再观察第二次请求是否出现 cache_read_input_tokens。
用 usage 字段做一次可重复验收
不要用单次响应的耗时判断命中,因为网络、排队和输出长度都会影响延迟。可以为每次请求保留下面这组最小记录:
| 字段 | 验收含义 | 排查方向 |
|---|---|---|
cache_creation_input_tokens | 本次写入缓存的输入量 | 首次请求或断点前缀发生变化 |
cache_read_input_tokens | 本次从缓存读取的输入量 | 大于 0 才能确认发生读取 |
input_tokens | 未由缓存读取的输入量 | 观察动态问题和未缓存后缀 |
usage = response.usage
audit = {
"input_tokens": usage.input_tokens,
"cache_creation_input_tokens": usage.cache_creation_input_tokens,
"cache_read_input_tokens": usage.cache_read_input_tokens,
}
if audit["cache_read_input_tokens"] > 0:
print("缓存命中", audit)
elif audit["cache_creation_input_tokens"] > 0:
print("缓存写入", audit)
else:
print("未发生缓存读写,检查前缀长度与断点", audit)
把这段判断放进请求指标或结构化日志后,缓存效果就能在压测和线上请求中复核。特别是灰度发布时,不要只看平均 token 成本,要按缓存读、写、未缓存三类拆开。

TTL、20 个区块回看与成本边界
默认缓存生命周期是 5 分钟,缓存条目在被使用时会刷新;生命周期从写入或读取请求开始计算,流式输出时间也会占用这段窗口。如果业务的两次请求间隔明显超过 5 分钟,可以显式指定 {"type": "ephemeral", "ttl": "1h"},但要把更高的缓存写入价格纳入预算。
显式断点最多有 4 个。每个断点向前查找时最多回看 20 个区块,而且只能找到过去真正写入过的断点。如果对话不断增长,旧断点离当前位置超过这个窗口,即使内容没有变也可能读不到;这时要提前在稳定位置设置另一个断点。
成本核对时记住三个比例:5 分钟缓存写入按基础输入价格的 1.25 倍计,1 小时写入按 2 倍计,缓存读取按基础输入价格的 0.1 倍计。具体美元单价会随模型和平台变化,预算表应以 Anthropic 当前 pricing 页面为准。
常见故障:为什么断点写对了还没有读
- 断点前内容变了:工具定义、system 指令或稳定手册有一处改动,都可能使后续缓存失效。先对比实际发送的请求,不要只对比业务输入。
- 缓存前缀太短:未达到当前模型的最小 token 门槛时,两个缓存字段可能同时为 0。
- 只发了一次请求:第一次请求只能证明写入是否发生,不能证明后续读取。
- 并发得太早:首个请求的缓存条目要等响应开始后才可用;需要验证读取时,先让写入请求开始,再发送下一次请求。
相关问题
cache_control 放在 user 问题上可以吗?
语法上可以,但如果 user 问题每次不同,就会让断点前缀不断变化。只有问题本身是稳定复用内容时才适合放在那里。
cache_read_input_tokens 为 0 就一定是配置错误吗?
不一定。还要检查请求是否首次发送、稳定前缀是否达到模型门槛、TTL 是否已过期,以及断点前的 tools、system、messages 是否发生变化。
多个 cache_control 会不会直接增加费用?
断点本身不单独计费,费用取决于实际发生的缓存写入、缓存读取和普通输入。多个断点的价值是控制不同稳定区块的复用边界。
应该用缓存命中替代业务侧缓存吗?
不应该。Prompt Caching 解决的是重复输入前缀的处理成本与延迟,业务答案的正确性、权限和失效策略仍应由应用自己的缓存层负责。
发布前检查清单
- 把静态工具定义、system 指令和产品手册放在动态问题之前。
- 将
cache_control放在最后一个稳定区块,而不是时间戳或用户问题之后。 - 连续发起至少两次可比请求,分别保存三个 usage 字段。
- 用
cache_read_input_tokens > 0确认读取,用写入量和 TTL 解释成本变化。
GitHub 如何从文件历史打开指定提交并恢复单个文件
- 上一篇
- GitHub 如何从文件历史打开指定提交并恢复单个文件
- 下一篇
- Go 1.27 httptest.NewTestServer 如何配合 testing/synctest:内存网络测试的新边界
-
- 科技周边 · 人工智能 | 4小时前 | websocket · 人工智能 · gemini · 实时语音 · Gemini Live API session resumption SessionResumptionUpdate GoAway
- Gemini Live API 的 session resumption 怎么避免实时语音会话中断:恢复令牌与重连边界
- 436浏览 收藏
-
- 科技周边 · 人工智能 | 8小时前 | 人工智能 · api设计 · Google AI · Gemini API · Context Caching · Gemini API Context Caching cachedContent 长提示词 generateContent
- Gemini API 的 cachedContent 怎么复用长提示词:缓存创建与请求绑定
- 257浏览 收藏
-
- 科技周边 · 人工智能 | 14小时前 | API · 人工智能 · agent · gemini · 工程实践 · agent 工具调用 Interactions API Gemini 3.7 Flash 任务验收
- Gemini 3.7 Flash 的 Agent 任务怎么验收:多步执行、工具结果与最终状态
- 176浏览 收藏
-
- 科技周边 · 人工智能 | 15小时前 |
- OpenAI Responses API 如何接收图片输入:多模态消息结构与结果读取
- 444浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ljg-skills
- ljg-skills 是李继刚开源的 AI 技能与提示词集合,面向大模型使用者整理了一批可复用的 prompt、角色设定和任务技能模板,适合用于学习提示词设计、搭建个人 AI 工作流和沉淀团队常用智能体能力。
- 5355次使用
-
- MELO音乐
- MELO音乐是一站式AI视频与音乐制作助手,对标suno, udio的高品质体验。提供伴奏生成、原创写词、无损导出、哼唱识曲、混音变声等全套音频与短视频编辑工具。无论是流行Kpop、电音说唱、民谣古风、摇滚儿歌还是商用轻音乐,MELO为你免费谱曲,轻松做同款!
- 4865次使用
-
- UniScribe
- UniScribe 是一款 AI 音视频转文字与内容整理工具,支持上传音频、视频文件或粘贴 YouTube 链接,自动生成转写文本、摘要、思维导图和关键问题,并支持多格式导出,适合会议记录、课程学习、访谈整理和内容创作复盘。
- 4816次使用
-
- 剧云
- 剧云是专业中文剧本创作平台,安全稳定运行十余年,集成AI编剧、剧本医生审核、人物小传、剧情关系图、大纲编写、多人协作、Word导入导出、版权管控功能,数据安全防护,轻松高效创作剧本。
- 5061次使用
-
- 万象有声
- 万象有声,一个专为有声创作者打造的新一代智能有声内容创作平台。平台提供专业的智能拆章、智能画本编辑、AI配音、AI生成音效、后期制作、智能对轨、智能审听等有声创作全流程工具,可以帮助创作者高效、低成本创作出引人入胜的有声作品。立即体验,让有声书制作更简单!
- 5020次使用
-
- 接口返回的数据和数据库不一致怎么办?按数据生命周期排查
- 2026-06-27 398浏览
-
- 关于golangtest缓存问题
- 2023-01-01 298浏览
-
- Go语言基于HTTP的内存缓存服务的实现
- 2022-12-24 388浏览
-
- Go Excelize API源码阅读SetSheetViewOptions示例解析
- 2022-12-24 485浏览
-
- Go快速开发一个RESTfulAPI服务
- 2023-01-01 493浏览

