一、开头:你有没有注意过,AI 其实一直在"从头背课文"
想象这样一个场景:你和一位知识渊博的教授坐在一张长桌旁,你请他帮你审阅一篇十万字的论文。你每问一个新问题,比如"第三段的论证逻辑是否有漏洞",教授都会先闭上眼睛,把整篇论文从第一个字重新读一遍,然后再回答你的问题。
你问第二个问题,他重新读一遍。 你问第三个问题,他又重新读一遍。
每次回答,他都要花费同样的时间"回忆"全文——即使大部分内容你根本没有改动。一小时的对话下来,他花在"重复阅读"上的时间,占总时长的九成以上。
这听起来很荒谬,对吧?但这就是今天绝大多数大语言模型(LLM)的工作方式。
每当你按下"发送",模型都要把你之前所有的对话历史、系统提示、工具定义、参考资料——全部从头处理一遍。它们不是像人类那样"记住了"之前的对话,而是每次都要重新"看"一遍。这些重复处理的内容,有一个专业名称:提示词前缀(prompt prefix)。
在一场涉及十万字上下文的深度对话中,前缀内容占了每轮请求的绝大部分——可能超过 90%。但你每次提问,模型都把它当成全新的输入来咀嚼,仿佛第一次见。
这就好比每次去同一家餐厅吃饭,服务员都要重新问你"请问您有什么忌口""请问您需要什么饮品",哪怕你昨天才来过,且什么都没变。
Prompt Cache(提示词缓存)的出现,就是为了终结这种荒诞。
---
二、核心概念:给 LLM 装一个"记事本"
2.1 什么是 Prompt Cache?
用最通俗的话说:Prompt Cache 就是给大模型配了一个"记事本",把反复出现的提示词前缀提前"背"下来,下次不用再从头背。
从技术上讲,LLM 处理文本时会把输入转换成一种叫"KV 状态"(Key-Value State)的内部表示。这个转换过程非常昂贵,需要大量的矩阵运算和内存带宽。但如果一段文本的前缀和之前某次请求一模一样,那它的 KV 状态也应该一模一样。
Prompt Cache 的核心洞察非常朴素:既然一样,为什么要算两次?
系统会在第一次遇到某个前缀时,把它的 KV 状态存进一个高速缓存区(通常放在 GPU 内存或专用缓存服务器上)。下一次只要请求的开头部分和缓存中的内容完全一致,就可以直接"搬"过来用,不用再让 GPU 吭哧吭哧从头算一遍。
这相当于给 LLM 的推理引擎装了一个"记忆层"——不是让模型"记住"对话内容(那是上下文窗口的事),而是让计算系统记住某些文本的计算结果,避免重复劳动。
2.2 一个生活中的比喻:复印店的打折策略
想象你开了一家复印店。有个客户每天来打印同一份 100 页的文件,只是每轮在最后一页手写一句新批注。
没有缓存时,你每次都要重新复印 100 页——包括那 99 页完全没变的部分。每轮收 100 页的钱。
有了缓存,你会对客户说:"前 99 页我已经印好了,存着呢。你只需要付第一遍的"存档费",以后每轮只收最后一页的复印费——而且最后一页我还给你打九折。"
这就是 Prompt Cache 的经济学:
- 首次写入:1.25 倍基准价格(因为你需要多干一点"归档"的活)
- 后续读取:基准价格的 10%(打一折,90% off)
- 有效期:默认 5 分钟(Anthropic 的设定),过期自动清除
- 门槛:至少 1024 个 token 的前缀才有资格进缓存
2.3 一个具体的数字冲击
来看 Anthropic 官方给的一个例子:一场涉及 100,000 token 上下文的深度对话。
| 场景 | 首次成本 | 后续每轮成本 |
|---|---|---|
| 不开缓存 | $0.30 | $0.30 |
| 开启缓存 | $0.375 | $0.03 |
如果这个对话持续 20 轮,总成本对比是:
- 不缓存:20 × $0.30 = $6.00
- 开缓存:$0.375 + 19 × $0.03 = $0.945
换句话说,这项技术不是"省一点小钱",而是把某些场景下的使用成本直接砍掉一个数量级。
---
三、技术细节:这个"记事本"是怎么工作的?
3.1 前缀匹配:一个极端严格的图书管理员
Prompt Cache 的匹配规则,可以用"严苛"来形容。它不是"意思差不多就行",而是字节级的逐字符比对。只要有一个字符不同、一个空格错位、一个换行符增减,整个缓存就会失效。
这背后的原因很简单:KV 状态对输入文本极度敏感。哪怕你把"请分析这段文字"改成"分析一下这段文字",底层计算出来的内部表示就可能天差地别。所以系统宁可错杀一千,也不放过一个——不匹配就重新算,绝不冒险。
这也意味着:前缀的顺序至关重要。缓存系统是从头开始匹配的,一旦中途有一个字符对不上,后续所有内容都会被打回"重新计算"。
比喻来说,这就像一位图书管理员检查你的借书卡。他不是看你"长得像不像"上次那个人,而是逐个核对你的身份证号、姓名、地址——哪怕一个字对不上,你就被当成全新客户处理。
3.2 缓存的"保质期":TTL 与驱逐策略
缓存不是永久存储。Anthropic 的默认设定是 5 分钟 TTL(生存时间)——超过 5 分钟没人访问,缓存就自动清理。这个设计很务实:缓存占用的 GPU 内存非常宝贵,不能无限期地给每个用户"存着"。
此外,还有一个 1024 token 的最低门槛。如果你的前缀太短(比如只有几百个 token),系统认为"重新算一遍也不贵",就不值得为它单独开辟缓存空间。
这就好比自助餐厅的餐盘回收:你刚放下的盘子很快就会被收走,而且如果你只拿了一小块面包,餐厅觉得不值得专门给你开个储物柜。
3.3 三个大坑:缓存失效的"死亡陷阱"
在实际工程中,Prompt Cache 有三大雷区,踩中任何一个,你的缓存就会瞬间归零,之前所有的"建档费"全部打水漂。
第一坑:别动 Prompt。
任何对提示词文本的修改——加一个字、删一个空格、调整语气词——都会导致前缀不匹配。在 Claude Code 的实践中,团队花了大量精力确保系统提示(system prompt)和工具定义(tool definitions)的绝对稳定。因为它们稍有变动,整个缓存就会失效,所有 Sub-Agent 的上下文都要重新"建档"。
第二坑:别换模型。
不同模型的 KV 表示方式完全不同。你今天用 Claude 3.5 Sonnet 缓存的内容,明天切换到 Claude 3.5 Haiku,缓存完全作废——就像你用英文写的笔记,不能指望法语翻译官直接看懂。
第三坑:别动工具定义。
如果你的 AI Agent 使用外部工具(比如读取文件、执行代码、搜索网络),这些工具的描述文本也参与前缀计算。每当你新增一个工具、修改一个参数描述,或者工具返回的格式稍有变化,缓存就会失效。
这三个坑本质上是同一件事:缓存只对"完全不变的内容"有效,任何变动都是死刑。
3.4 Sub-Agent 策略:把"大锅饭"拆成"小灶"
在 Claude Code 的架构中,一个核心策略是大量使用 Sub-Agent(子代理)——把复杂任务拆成多个小任务,每个 Sub-Agent 只处理自己关心的那部分上下文。
这看似和缓存无关,实际上是一个精妙的配合策略。
想象一个大型项目的代码审查。如果所有文件都塞进一个对话上下文里,每次提问都要带着几万字的代码前缀,缓存压力巨大。但如果把不同模块分配给不同的 Sub-Agent,每个 Agent 只缓存自己那部分代码的前缀,整个系统的缓存利用率就会大幅提升。
Claude Code 的实践表明,Sub-Agent 架构配合 Prompt Cache,可以实现高达 92% 的缓存命中率——意味着超过九成的请求都能命中缓存,只需支付 10% 的成本。
3.5 Plan Mode:先写提纲,再动笔
Claude Code 还有一个有意思的模式叫 Plan Mode(计划模式)。在进入正式执行前,系统会先让模型生成一个执行计划,但这个计划阶段不会加载任何工具定义——因为还没确定要用哪些工具。
这样做有两个好处:一是计划阶段的上下文更短、更聚焦;二是避免了在计划阶段就"预加载"大量工具定义,从而浪费缓存资源。等计划确定了,再进入执行模式,按需加载工具。
这就像装修前先画设计图,而不是一边砌墙一边改设计——前者省料,后者废料。
3.6 Lazy Loading:按需加载,不急不躁
和 Plan Mode 一脉相承的是 Lazy Loading(惰性加载)。Claude Code 不会在对话一开始就加载所有可能的工具和资源,而是只在真正需要时才加载。
举个例子:如果你问了三个问题都没用到"代码搜索"工具,那它的定义就一直躺在"仓库"里,不进缓存。直到你第 4 个问题说"帮我搜一下这个函数在哪里定义的",系统才把它调进上下文。
这种"按需分配"的思路,最大化了缓存空间的利用效率——毕竟 GPU 内存不是无限的,能少占就少占。
3.7 Compaction:缓存的"过期食品清理"
长时间对话还有一个问题:上下文会不断膨胀。即使你一直在命中缓存,新增的每轮对话也会占用新的空间。如果不加控制,缓存区最终会被撑爆。
Claude Code 使用 Compaction(压缩) 策略来应对这个问题:定期把多轮对话中的关键信息提炼成一份"摘要",然后用这份摘要去替代原始的对话历史。这样既能保留必要的信息,又能控制上下文长度,避免缓存无限膨胀。
这就像整理冰箱:定期清理过期食品,把散落的食材归纳成几个保鲜盒,让空间持续可用。
3.8 Cache-Safe Forking:分叉时的缓存传承
在 Claude Code 中,当用户开启一个新的任务分支(fork)时,系统会尝试"携带"原有缓存。这意味着新分支不需要从头建档,可以直接继承父分支的前缀缓存。
这个设计的精妙之处在于:分支之间共享了不变的部分(比如系统提示、项目上下文),而只对新分支独有的内容重新计算。这让多任务并行时的成本得到了有效控制。
比喻来说,这就像复印店的"会员档案":你开了两个不同的业务账户,但基础身份信息是同一份,不需要重新录入。
---
四、意义与展望:从"成本优化"到"架构范式"
4.1 成本之外:延迟的降低
Prompt Cache 的最大卖点通常被描述为"省钱",但它的另一个价值同样重要:降低延迟。
在处理超长上下文(如 100,000 token 的代码库、法律文档、研究论文)时,前缀处理往往占据了推理时间的绝大部分。如果能跳过前缀的 KV 计算,仅处理新增的几百个 token,响应延迟可以从数秒降至数百毫秒。
对于交互式应用(如 Claude Code 这样的实时编程助手),这种延迟降低直接决定了用户体验的流畅度。没有人愿意每次提问后等 5 秒钟——即使成本可以承受,耐心也是有限的。
4.2 从"缓存"到"基建":Prompt Cache 的范式转移
Anthropic 的工程师在分享 Claude Code 的设计时提到一个重要观点:Prompt Cache 不是锦上添花的功能,而是架构层面的基础设施。
这意味着:当你设计一个 LLM 应用时,你不应该"等做完了再考虑要不要开缓存",而是从一开始就把缓存效率作为核心约束条件来设计。
具体来说:
- 系统提示要极度稳定,版本化管控;
- 工具定义要模块化,避免不必要的变动;
- 上下文组织要分层,不变的放前面,变动的放后面;
- Sub-Agent 的拆分粒度要兼顾任务隔离和缓存复用。
4.3 未来:缓存即服务?
展望未来,Prompt Cache 可能不仅仅是一个推理引擎的内部优化,而是会演变为一种独立的云服务。
想象这样一个场景:你有一个 50 万字的法律条文库,是你所有案件分析的共同前缀。传统的做法是每次请求都上传这 50 万字。有了"缓存即服务",你可以先做一次"缓存注册"操作,把这 50 万字"存"在云端。之后的所有请求只需要引用这个缓存 ID,而不需要重复传输文本。
Anthropic 已经在朝这个方向探索——他们允许用户显式声明哪些前缀段需要缓存,并提供缓存命中率的监控指标。未来可能会出现更精细的缓存管理 API:查看缓存状态、预热缓存、跨会话共享缓存、甚至缓存的持久化存储(突破 5 分钟的 TTL 限制)。
4.4 一个更大的图景:当 AI 越来越"像"人
Prompt Cache 的底层理念,其实暗合了人类认知的一个特征:我们不会每次思考都从第一性原理出发,而是大量依赖"缓存"的记忆和直觉。
当你看到一只猫,你不会重新分析"四条腿、毛茸茸、会叫"——你直接调用大脑中"猫"的缓存表征,瞬间完成识别。只有当遇到"四不像"时,你才会启动深度分析。
Prompt Cache 让 LLM 也开始拥有类似的"直觉反应":对于已经"背熟"的前缀,直接调用结果;只有遇到新内容时,才启动完整的推理流程。这种"分层认知"可能是让 AI 更高效、更经济的必经之路。
---
五、结语:重复是宇宙最大的浪费
古希腊哲学家赫拉克利特说:"人不能两次踏入同一条河流。"他讲的是变化的永恒。但在 LLM 的世界里,恰恰相反——我们每天都在踏入同一条河流,却每次都要重新学习游泳。
十万字的代码库,读了一遍又一遍。 同一套系统指令,解析了一次又一次。 那些从未改变过的常识,被反复咀嚼,反复消化。
Prompt Cache 是对这种浪费的温柔反抗。它说:既然我们早已知道答案,何必要假装第一次遇见?
当你下次和 AI 进行一场长对话时,不妨想一想:在那些毫秒级的响应背后,或许有一场"记忆的回声"正在发生——那些重复说出的话,终于不必再重复计算。
---
参考资料:
- easy-learn-ai Prompt Cache 教学模块(commit
515b759) - Anthropic: "Prompt Caching in Claude Code" — 工程实践分享
- Claude Code 文档: https://code.claude.com/docs