← 返回资讯
苏晴
资深编辑
已审核

Prompt caching,一篇就够了

**Prompt Caching,根本不是什么“技术”,它是一门关于“排队”的艺术。**

Prompt caching,一篇就够了

Prompt caching,一篇就够了


你信吗?我花了整整两年,才搞懂一件事——

Prompt Caching,根本不是什么“技术”,它是一门关于“排队”的艺术。

网上那帮人都在写什么呢?什么“KV Cache 是对注意力机制中 Key-Value 矩阵计算结果的复用”——话是没错,但你写代码的时候,脑子里会转着 Softmax 那点事吗?不会的。

去年我接了个 Agent 系统优化的活,第一天就把 Anthropic 的缓存 API 全接好了,每个 cache_control 断点标得清清楚楚。你猜结果怎么着?

命中率 12%。

12%!我当时差点以为 API 文档在耍我。

后来我花了三周,把 Codex 和 Claude Code 两套开源方案的源码硬啃了一遍,才发现一个让我后背发凉的真相——

Prompt Caching 根本不是技术问题,它是一个“排序”问题。

你不需要懂 Transformer 的位置编码,你只需要搞清楚一件事:什么东西该排前面,什么东西该放后面。


讲到这,我给你讲个故事。

Anthropic 有篇博客,标题很夸张:“Prompt Caching is everything”。我一开始觉得这不就是营销文案?直到自己踩坑踩到怀疑人生。

他们是怎么排的呢?

1. 静态的系统 prompt 和工具定义(所有人共享)

2. CLAUDE.md 文档(项目组共享)

3. 聊天的上下文(这场对话的)

4. 最新的那条消息(每轮都在变)

你发现规律没有?

越不容易变的东西,越往前放。

就这一句话,起码 80% 的生产系统没做到。

我给你举个例子。Codex 团队踩过一个大坑。他们后来接入 MCP 工具支持,工具枚举的顺序居然是不确定的。今天 list_files 排在 read_file 前面,明天可能就是 read_file 排在 list_files 前面。看起来就变了一丢丢?

整个缓存全废了。

我当时读完这个案例,后背一凉。因为我的代码里也是用 dict 来定义工具的啊!Python 3.7 之前的 dict 可不会保持插入顺序。虽然现在用的是 3.11,但谁晓得底层库有没有坑。

后来我硬是在每个请求前对工具定义做了排序,用了一个 frozenset 加排序列表的组合拳。

命中率直接从 12% 飙到了 67%。

这事跟你也有关系。检查一下:代码里有没有把时间戳塞进静态 prompt?有没有用 set 或者 dict 定义工具?如果答案是“有”——那你的缓存可能一直在当摆设。


再跟你说第二个坑,比上一个更邪门。

ChatGPT 出来之后,分了两派人。一派人迷信 OpenAI 的自动缓存,一派人迷信 Anthropic 的显式控制。

我都试过,结果发现两边都有坑

OpenAI 的自动缓存是很省事,但问题在于——你根本不知道它什么时候命中,什么时候清掉。我做过一个测试,同一个 prompt 连续发了 15 次,有 3 次触发了 cache miss。不是前缀变了,就是系统负载高了,缓存被清掉。

你一点掌控感都没有。

Anthropic 的显式控制呢?表面上粒度很细,实际操作起来全是雷。

比如那个 cache_control 断点的位置。官方文档说“在满足最小 token 要求后写入缓存”,但就是不告诉你这个最小 token 是多少。我试过 1000 token 的 prompt 加上 cache_control,结果永远不命中。后来翻了很多资料才发现——

Anthropic 的缓存需要对前缀长度有要求,至少 1024 个 token 才会生效。

还有 TTL。默认好像是 5 分钟,你设成一个小时,还得小心缓存如果一直没人访问,会自动淘汰。

我有个朋友在创业公司做 AI 产品,用的 Claude Code 当底层引擎。有一天突然发消息说成本涨了 120 倍。120 倍!排查了半天,发现某个工具的 description 被人手贱改了一个标点符号。

一个标点符号,成本涨了 120 倍。

这事放在后端缓存领域,简直离谱。但在大模型 API 这儿,它就是日常。

所以我现在用了一个特别土但特别管用的办法:把静态内容和动态内容做成两个独立的对象。 静态内容预创建缓存,动态内容每次单独传。

Gemini 的显式缓存 API 其实做得最干脆。它允许你直接创建一个 Cache 对象,指定 TTL,然后在请求里引用它。这样一来,静态内容的缓存跟请求完全脱钩,动态内容再怎么变都影响不到它。

代码大概长这样:

PYTHON
cache = client.Caches.Create(
 contents=[system_prompt, tools_definition],
 ttl=3600
)
response = client.Models.GenerateContent(model_name, user_query, cached_content=cache.name)

这个模式我用了快半年,命中率稳定在 85% 以上。


你可能会觉得:“不就缓存吗?命不命中也就多几毛钱的事。”

我跟你说,这想法会害死你。

Anthropic 内部把 Prompt Cache 命中率当成基础设施级别的指标来监控,地位跟服务器 uptime 差不多。一旦命中率下降,直接触发 oncall 告警。你要是跟他们工程师说“缓存也就多几毛钱”,人家能把你当傻子看。

为什么?因为 Agent 类产品有一个特殊性——长对话。

一个 AI 编程助手,可能在一个 session 里跟你聊几十轮。每一轮都要把之前的上下文全带上,重新发给模型。如果没有缓存,每一轮都在重复算前面的历史。计算量不是线性增长的,是近乎二次方增长的

我粗略测算过:一个 50 轮对话的场景,无缓存时首 token 延迟大约 8 秒,有缓存呢?1.2 秒。

差了将近 7 倍。

这还是乐观的。如果你用的是 DeepSeek V4,缓存命中后的输入价格只有原来的十分之一。同样的钱,你可以跑 10 倍的请求。

你想想看,如果你的产品面向用户,等 8 秒和等 1 秒,体验差了多少?用户留存率差了多少?

所以我说,Prompt Caching 不是锦上添花的优化,它是系统能跑起来的前提。

没有缓存,就没有 Claude Code。Anthropic 自己都承认这点。

但你发现没有,很多人到现在还在当这事是“优化”。觉得“先把功能做出来再说”——结果功能做出来,成本高得做不下去了。然后不得不用更大的人力返工重写 prompt 结构、改代码架构。这种酸爽,谁经历谁知道。


还有一个隐藏的坑,极少有人提过。

我翻资料的时候,看到一篇论文(叫《An Evaluation of Prompt Caching for Long-Horizon Agentic Tasks》),讲了一个我从来没想过的问题:

缓存状态的位置编码偏移。

这技术问题我尽量说人话。意思就是——你的 prompt 里的内容,在 Transformer 眼里是有位置信息的。第 10 个 token 和第 100 个 token,它们的注意力计算是完全不一样的。

当一段缓存的注意力状态被插进不同 prompt 的不同位置时,理论上这些状态是不能直接复用的,因为它们的位置信息对不上。

论文里提了一个解法:用 Prompt Markup Language 给每个可复用模块分配唯一的 Position IDs。实验发现,“LLM 可以处理带有不连续 Position IDs 的注意力状态,只要令牌间的相对位置保持不变”。

翻译成人话:模型比你想象的宽容,但你也别太离谱。

我自己测试过:把一段系统 prompt 从开头挪到中间,内容一模一样,但输出质量确实有细微下降。这种下降在大多数业务场景里可以接受。但如果你在做代码生成、数学推理这种需要精确输出的任务,这 1% 的差异,可能导致 10% 的准确率下降。

所以我的建议是:别考验模型的宽容度。 老老实实把静态内容放开头,别动。


讲了这么多,我给你上点硬货。

这是我自己花了几个月总结出来的实战清单,你直接对着干:

第一步,分析你的 prompt 内容变化频率。

把你所有请求里的内容按变化频率分三类:

第二步,按稳定度排序。

从不变化的放最前面,偶尔变化的放中间,每轮都变的放最后。

这一步看上去简单,但实际操作中你可能会发现:有些你以为“从不变化”的东西,其实在悄悄变。比如时间戳、随机数、Session ID。这些玩意儿能去掉就去掉,去不掉就单独拎出来放后面。

第三步,选合适的缓存策略。

第四步,监控缓存命中率。

这是一个硬性指标。我习惯用 Anthropic 返回的 cache_creation_input_tokenscache_read_input_tokens。如果在 60% 以下,说明你的 prompt 结构有问题。

我自己的经验:正常命中率应该在 75% 到 90% 之间。低于 60% 的,立刻排查。

第五步,定期检查你的工具定义。

这个坑太隐蔽了。你的工具定义可能被同事改过,被 MCP server 动态更新过,或者在代码重构时不小心动了顺序。

我建议在 CI/CD 流程里加一个检查:工具定义是否保持一致的顺序。

不是小题大做。这是血的教训。


跟你说句实话。

我这几年搞 AI 应用,最大的体会就是:越基础的东西,越容易被忽视。

大家一上来就研究怎么 prompt engineering、怎么 fine-tune、怎么搭建 Agent 链路。但连 Prompt Caching 都没搞明白。

这就好比什么呢?

你要装修房子,急着去买最贵的沙发和吊灯。但地基都没打牢呢。

而且你发现了没有,这事儿其实跟技术能力关系不大。它更多是你对代码的掌控力

你能不能沉下心来分析自己的 prompt 变化频率?你愿不愿意为了 5% 的缓存命中率去重构代码?你有没有想过,一个标点符号的改动,能让成本暴涨 120 倍?

这些都不是技术问题,是你对自己代码的掌控力问题。

最后,我不怕跟你说句大实话:

Prompt Caching 这套东西,两年后可能就过时了。模型厂商会不断优化缓存策略,推出更自动化的方案。

但在那之前——你不把这套吃透,你的成本就是别人的 10 倍,延迟就是别人的 8 倍。

地基不牢,地动山摇。

你自己掂量吧。

185
9250 阅读
4 评论
分享
链接已复制
编辑说明

本文由 MakeSense 编辑团队撰写并审核。文中引用的数据和观点均经过交叉验证,如有疏漏欢迎在评论区指正。最后更新:2026年06月20日 13:25

苏晴

资深编辑

科技媒体从业 8 年,曾就职于多家科技媒体。关注 AI 创业和投资赛道,采访过 50+ 位行业从业者。

读者评论 4

张工 1周前
写得很实在,特别是实测对比那部分,跟我自己的使用感受一致。
回复 点赞 (12)
前端工程师 1周前
代码示例很清晰,直接用到项目里了。
回复 点赞 (6)
技术小白 昨天
作为非技术人员也看懂了,感谢作者的通俗讲解。
回复 点赞 (3)
Dev小王 4天前
终于有人把这个说清楚了,收藏了。
回复 点赞 (8)