Claude Prompt Caching 实战:把大模型 API 成本降低 90% 的工程技巧 Claude Prompt Caching 实战把大模型 API 成本降低 90% 的工程技巧一、问题场景“我做了一个 RAG 系统每次提问都要把几千 Token 的文档塞进 Prompt账单越来越吓人。”“我的 Agent 有一个 3000 Token 的 System Prompt每次调用都要重新计费一天下来成本爆炸。”“多轮对话越聊越长历史消息每轮都重新计算Token 消耗像滚雪球。”如果你也遇到这些问题那Prompt Caching提示词缓存就是你的救星。这是一个被很多开发者忽略但能实打实把成本降低 90%、延迟降低 85%的工程技巧。本文将讲清楚 Prompt Caching 的原理、使用方法、计费模型并给出可直接套用的实战代码。读完你会获得Prompt Caching 的工作原理和省钱逻辑Claude API 中如何正确设置缓存断点三个典型场景的完整实战代码计费规则详解和 5 个避坑要点二、原理分析2.1 为什么 Prompt 会重复计费大模型 API 是无状态的——每次请求模型都要把整个 Prompt 从头处理一遍重新计算注意力。第 1 次请求[3000 Token System Prompt] [问题A] → 计费 3000 第 2 次请求[3000 Token System Prompt] [问题B] → 又计费 3000 第 3 次请求[3000 Token System Prompt] [问题C] → 再计费 3000那个固定的 3000 Token System Prompt每次都在重复付费。这就是浪费的根源。2.2 Prompt Caching 如何省钱Prompt Caching 让模型把处理过的固定前缀缓存起来后续请求命中缓存时这部分几乎不收费、不重算。第 1 次请求[3000 Token] 写入缓存缓存写入费略贵 [问题A] 第 2 次请求[3000 Token] 命中缓存仅 10% 费用 [问题B] 第 3 次请求[3000 Token] 命中缓存仅 10% 费用 [问题C]核心收益成本缓存命中部分只收10%的费用降低 90%延迟命中缓存可减少最多85%的首 Token 延迟适用System Prompt、长文档、Few-shot 示例、对话历史等固定前缀2.3 计费模型详解Claude Prompt Caching 有三种 Token 价格类型价格相对基础输入说明缓存写入1.25 倍首次写入缓存比普通输入略贵缓存命中读取0.1 倍命中缓存仅 10% 费用普通输入1.0 倍未缓存的部分正常计费关键缓存写入虽然贵 25%但只要后续命中2 次以上就回本了。对于高频复用的固定前缀省钱效果惊人。缓存有效期TTL默认 5 分钟每次命中会刷新计时。也就是说只要 5 分钟内有请求缓存就一直有效。2.4 缓存的工作机制请求结构从前到后 ┌─────────────────────────────┐ │ Tools 定义 │ ┐ ├─────────────────────────────┤ │ 设置 cache_control 断点 │ System Prompt │ │ 这部分被缓存 ├─────────────────────────────┤ ┘ │ 对话历史 / 用户问题 │ 这部分每次变化不缓存 └─────────────────────────────┘核心规则缓存是前缀匹配的。缓存断点之前的内容只要完全一致就能命中。所以固定内容必须放在前面变化内容放在后面。三、实践验证完整代码3.1 基础用法缓存 System Prompt 基础场景缓存固定的 System Prompt 适用Agent、客服等有长 System Prompt 的场景 fromanthropicimportAnthropic clientAnthropic()# 一个较长的 System Prompt假设 2000 TokenLONG_SYSTEM_PROMPT你是一个专业的法律顾问助手... 这里是大量的规则、术语解释、回答规范假设 2000 Token ...defask(question:str):responseclient.messages.create(modelclaude-sonnet-4-6,max_tokens1024,system[{type:text,text:LONG_SYSTEM_PROMPT,cache_control:{type:ephemeral}# ← 关键标记缓存断点}],messages[{role:user,content:question}])# 查看缓存使用情况usageresponse.usageprint(f缓存写入:{usage.cache_creation_input_tokens})print(f缓存命中:{usage.cache_read_input_tokens})print(f普通输入:{usage.input_tokens})returnresponse.content[0].text# 第一次调用写入缓存ask(合同违约金的上限是多少)# 第二次调用命中缓存System Prompt 部分只收 10% 费用ask(租赁合同可以提前解除吗)3.2 RAG 场景缓存检索到的长文档 RAG 场景缓存大段检索文档 适用基于同一批文档多次问答 fromanthropicimportAnthropic clientAnthropic()defrag_query_with_cache(documents:str,question:str):documents 是检索到的长文档question 是变化的问题responseclient.messages.create(modelclaude-sonnet-4-6,max_tokens1024,system[{type:text,text:你是知识库助手基于提供的资料回答问题。},{type:text,text:f参考资料\n{documents},cache_control:{type:ephemeral}# ← 缓存长文档}],messages[{role:user,content:question}])returnresponse.content[0].text# 同一批文档多次提问文档部分只在第一次付全费docs这里是检索到的 5000 Token 文档rag_query_with_cache(docs,产品的核心功能有哪些)rag_query_with_cache(docs,如何配置环境)# 命中缓存rag_query_with_cache(docs,常见错误怎么排查)# 命中缓存3.3 多轮对话缓存对话历史 多轮对话场景随着对话变长缓存前面的历史 适用聊天机器人、长对话 Agent fromanthropicimportAnthropic clientAnthropic()classCachedChat:def__init__(self,system_prompt:str):self.systemsystem_prompt self.messages[]defchat(self,user_input:str):self.messages.append({role:user,content:user_input})# 在倒数第二条消息上打缓存断点缓存之前的对话历史messagesself._add_cache_breakpoint()responseclient.messages.create(modelclaude-sonnet-4-6,max_tokens1024,system[{type:text,text:self.system,cache_control:{type:ephemeral}}],messagesmessages)replyresponse.content[0].text self.messages.append({role:assistant,content:reply})returnreplydef_add_cache_breakpoint(self):在最后一条用户消息前的内容打缓存断点msgs[dict(m)forminself.messages]iflen(msgs)2:# 给倒数第二条消息加缓存标记last_cachedmsgs[-2]ifisinstance(last_cached[content],str):last_cached[content][{type:text,text:last_cached[content],cache_control:{type:ephemeral}}]returnmsgs# 使用chatCachedChat(你是一个友好的助手。)print(chat.chat(我想学 Python))print(chat.chat(从哪里开始))# 缓存前面的对话print(chat.chat(推荐一些项目练手))# 继续命中缓存3.4 验证缓存是否生效通过response.usage的字段判断usageresponse.usage# cache_creation_input_tokens 0 → 这次写入了缓存# cache_read_input_tokens 0 → 这次命中了缓存省钱了# input_tokens → 未缓存的普通输入ifusage.cache_read_input_tokens0:savedusage.cache_read_input_tokens*0.9# 省了 90%print(f✅ 缓存命中约节省{saved:.0f}Token 的费用)四、避坑指南#坑现象解决方案1缓存内容放错位置缓存从不命中固定内容必须放前面变化内容放后面前缀匹配2缓存前缀有微小变化命中率低哪怕一个字符不同都无法命中确保前缀完全一致3缓存块太小没省到钱甚至更贵Claude 有最小缓存长度要求通常 1024 Token太短不缓存4忽略 5 分钟 TTL低频调用缓存失效高频场景才划算低频场景可考虑保活或不用缓存5只调用一次还用缓存写入费比省的多缓存写入贵 25%命中 2 次以上才回本6断点设置过多管理复杂、效果差一般 1-2 个断点足够最多支持 4 个计费回本公式缓存写入成本 N × 1.25首次 不用缓存成本 N × 1.0 × 调用次数 用缓存成本 N × 1.25 N × 0.1 × (调用次数 - 1) 当调用次数 ≥ 2 时用缓存就开始省钱 调用次数越多省得越多趋近 90%五、总结Prompt Caching 是大模型工程化中性价比最高的优化手段之一核心要点原理缓存固定前缀命中只收 10% 费用用法在固定内容System Prompt、长文档、对话历史后打cache_control断点布局固定内容放前面变化内容放后面回本命中 2 次以上就省钱高频场景降本 90%最适合用 Prompt Caching 的场景有长 System Prompt 的 Agent / 客服基于同一批文档多次问答的 RAG多轮长对话的聊天机器人大量 Few-shot 示例的分类/抽取任务推荐实践路径先用response.usage分析你的请求找出重复计费的固定部分在固定前缀后加缓存断点验证cache_read_input_tokens是否 0优化 Prompt 结构把所有固定内容前移监控缓存命中率持续调优延伸阅读Anthropic: Prompt Caching 官方文档Anthropic: 降低成本的最佳实践省下来的钱就是赚到的钱。一个cache_control断点可能就帮你把月度账单砍掉一大半。