<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Prompt Caching on 鬼哥的空间</title><link>https://luoli523.github.io/tags/prompt-caching/</link><description>Recent content in Prompt Caching on 鬼哥的空间</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Fri, 17 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://luoli523.github.io/tags/prompt-caching/index.xml" rel="self" type="application/rss+xml"/><item><title>Prompt Caching 深度拆解：Claude Code 是如何做到 92% 命中率的</title><link>https://luoli523.github.io/p/llm-prompt-caching-explained/</link><pubDate>Fri, 17 Apr 2026 00:00:00 +0000</pubDate><guid>https://luoli523.github.io/p/llm-prompt-caching-explained/</guid><description>&lt;img src="https://luoli523.github.io/" alt="Featured image of post Prompt Caching 深度拆解：Claude Code 是如何做到 92% 命中率的" /&gt;&lt;p&gt;你有没有想过这样一个问题：&lt;/p&gt;
&lt;p&gt;当你跟 Claude Code 对话了 30 分钟，中间来回几十个 tool call 之后，&lt;strong&gt;每一次它要回复你，都会把前面所有的对话历史重新发一遍给模型。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;System prompt、tool schema、CLAUDE.md 里的项目约定、三轮之前已经处理过的那些文件内容——&lt;strong&gt;全部重新读、重新算、重新计费。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这不是 bug，是 LLM API 的工作方式。对于长会话的 Agent 来说，这种&amp;quot;重复计算&amp;quot;往往是你 AI 基础设施账单里&lt;strong&gt;最贵的一项&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;举个数：一个 2 万 token 的 system prompt，跑 50 轮对话，那就是 &lt;strong&gt;100 万 token 的纯冗余计算&lt;/strong&gt;，全部按输入价格计费，产生零新价值。而这笔开销会在每个用户、每个 session 上复利叠加。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="558px" data-flex-grow="232" height="570" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://luoli523.github.io/p/llm-prompt-caching-explained/redundant-compute.webp" srcset="https://luoli523.github.io/p/llm-prompt-caching-explained/redundant-compute_hu_4a7c96ee286129ff.webp 800w, https://luoli523.github.io/p/llm-prompt-caching-explained/redundant-compute.webp 1327w" width="1327"&gt;&lt;/p&gt;
&lt;p&gt;解决办法是 &lt;strong&gt;Prompt Caching&lt;/strong&gt;。但要真正把它用好，你得先搞清楚底下到底发生了什么。&lt;/p&gt;
&lt;p&gt;这篇文章来自 &lt;a class="link" href="https://x.com/_avichawla/status/2044670188998803855" target="_blank" rel="noopener"
 &gt;Avi Chawla 的一篇推文&lt;/a&gt;，作者把 Claude 如何做到 &lt;strong&gt;92% 缓存命中率&lt;/strong&gt;这件事讲得非常透彻。我把它翻译整理出来，并加入了一些自己使用 Claude Code 过程中的观察。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="一静态上下文-vs-动态上下文"&gt;一、静态上下文 vs 动态上下文
&lt;/h2&gt;&lt;p&gt;要优化一个 prompt，你得先理清楚：&lt;strong&gt;哪些是会变的，哪些是不变的。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;每一次 Agent 的请求，其实都由两个&lt;strong&gt;本质上完全不同&lt;/strong&gt;的部分组成：&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="476px" data-flex-grow="198" height="669" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://luoli523.github.io/p/llm-prompt-caching-explained/static-vs-dynamic.webp" srcset="https://luoli523.github.io/p/llm-prompt-caching-explained/static-vs-dynamic_hu_7ba484b4ea78e057.webp 800w, https://luoli523.github.io/p/llm-prompt-caching-explained/static-vs-dynamic.webp 1327w" width="1327"&gt;&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;&lt;/th&gt;
 &lt;th&gt;内容&lt;/th&gt;
 &lt;th&gt;特征&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;静态前缀&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;system 指令、tool 定义、项目上下文、行为规范&lt;/td&gt;
 &lt;td&gt;每轮都一样，永远不变&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;strong&gt;动态后缀&lt;/strong&gt;&lt;/td&gt;
 &lt;td&gt;用户消息、模型回复、tool 输出、终端观察&lt;/td&gt;
 &lt;td&gt;每轮都在增长&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;这个划分，就是 prompt caching 能成立的前提。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;推理基础设施会把静态前缀对应的数学状态（也就是 KV tensor）存下来，让后续发送&lt;strong&gt;完全相同前缀&lt;/strong&gt;的请求可以直接跳过计算，从内存里读出来。&lt;/p&gt;
&lt;p&gt;一旦你把这件事想通，后面所有的架构决策，都会变得非常显然。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="二kv-cache-到底在缓存什么"&gt;二、KV Cache 到底在缓存什么
&lt;/h2&gt;&lt;p&gt;要理解为什么缓存这么有效，得先看 Transformer 处理你的 prompt 时到底做了什么。&lt;/p&gt;
&lt;p&gt;LLM 推理有两个阶段：&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="516px" data-flex-grow="215" height="677" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://luoli523.github.io/p/llm-prompt-caching-explained/prefill-decode.webp" srcset="https://luoli523.github.io/p/llm-prompt-caching-explained/prefill-decode_hu_cdfda347ace53c5a.webp 800w, https://luoli523.github.io/p/llm-prompt-caching-explained/prefill-decode.webp 1456w" width="1456"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Prefill 阶段&lt;/strong&gt;：处理你输入的整个 prompt。在所有 token 上跑一轮密集矩阵乘法，构建模型的内部表示。这个阶段是 &lt;strong&gt;compute-bound&lt;/strong&gt;（算力瓶颈），非常贵。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Decode 阶段&lt;/strong&gt;：一个 token 一个 token 地生成。每次把新 token 追加到序列里，预测下一个。这个阶段是 &lt;strong&gt;memory-bound&lt;/strong&gt;（显存瓶颈），因为大部分工作是在读历史状态。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;在 prefill 阶段，Transformer 会为&lt;strong&gt;每一个 token&lt;/strong&gt; 计算三个向量：&lt;strong&gt;Query、Key、Value&lt;/strong&gt;。Attention 机制用它们来决定每个 token 跟其他 token 的关系。&lt;/p&gt;
&lt;p&gt;关键在于：&lt;strong&gt;一个 token 的 Key 和 Value 只依赖于它前面的那些 token。一旦算出来，就永远不会变。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;video src="kv-attention.mp4" autoplay loop muted playsinline style="width:100%;max-width:100%;border-radius:8px;"&gt;&lt;/video&gt;&lt;/p&gt;
&lt;p&gt;没有缓存的情况下，这些 Key 和 Value tensor 在每次请求结束后就被丢掉了，下次请求要从头再算一遍。对于 2 万 token 的前缀，那就是 2 万 token 的 attention 计算——完全没必要重复。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;KV Cache&lt;/strong&gt; 的做法是：把这些 tensor 持久化在推理服务器上，用 token 序列的&lt;strong&gt;加密哈希&lt;/strong&gt;做索引。当新请求进来、前缀完全一致时，哈希命中，tensor 直接从内存里加载，这段 prefill 计算&lt;strong&gt;整个跳过&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;这把每生成一个 token 的计算复杂度从 &lt;strong&gt;O(n²)&lt;/strong&gt; 降到 &lt;strong&gt;O(n)&lt;/strong&gt;。对于一个重复使用 50 轮的 2 万 token 前缀，省下的算力是非常可观的。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="三经济账"&gt;三、经济账
&lt;/h2&gt;&lt;p&gt;定价结构才是让这个架构决策&lt;strong&gt;真正有分量&lt;/strong&gt;的地方。&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cache Read&lt;/strong&gt;：0.1x 的基础输入价格——也就是&lt;strong&gt;九折优惠，打完一折&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cache Write&lt;/strong&gt;：1.25x 的基础价格——存 KV tensor 要加收 25% 溢价。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Extended 1-hour Caching&lt;/strong&gt;：2.0x 的价格。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;下面是 Claude 各模型的具体价格：&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="885px" data-flex-grow="369" height="368" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://luoli523.github.io/p/llm-prompt-caching-explained/cache-pricing.webp" srcset="https://luoli523.github.io/p/llm-prompt-caching-explained/cache-pricing_hu_1a7ad128b991d206.webp 800w, https://luoli523.github.io/p/llm-prompt-caching-explained/cache-pricing.webp 1358w" width="1358"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;但这笔账只有在缓存命中率够高的时候才划算。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;生产环境里最好的例子，就是 Claude Code。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="四claude-code-的-30-分钟实录"&gt;四、Claude Code 的 30 分钟实录
&lt;/h2&gt;&lt;p&gt;Claude Code 的整个架构设计，都围绕一个目标展开：&lt;strong&gt;让缓存一直保持热的（keep the cache hot）。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;下面这段是一次真实的 30 分钟编码会话从&lt;strong&gt;计费视角&lt;/strong&gt;看起来是什么样的：&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;第 0 分钟&lt;/strong&gt;：Claude Code 加载 system prompt、tool 定义、项目 CLAUDE.md 文件。这个载荷&lt;strong&gt;超过 2 万 token&lt;/strong&gt;，而且每个 token 都是新的，这是&lt;strong&gt;整场会话里最贵的一刻&lt;/strong&gt;。但这笔钱你只付一次。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第 1-5 分钟&lt;/strong&gt;：你开始下指令，Claude Code 派出 Explore Subagent 在代码库里游走，打开文件、跑 grep 命令。所有这些都被追加到动态后缀里。但那 2 万 token 的静态前缀现在是在&lt;strong&gt;以 $0.30/MTok 的缓存价读取&lt;/strong&gt;，而不是 $3.00/MTok。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第 6-15 分钟&lt;/strong&gt;：Plan Subagent 收到的是一份&lt;strong&gt;摘要版简报&lt;/strong&gt;，而不是原始结果——因为把原始输出塞进来只会让动态后缀没必要地膨胀。它产出一份实现计划，你批准后，Claude Code 开始改代码。每一轮都在从缓存里读静态前缀，&lt;strong&gt;命中率飙过 90%&lt;/strong&gt;，而且每次访问都会重置 TTL、让缓存保持温热。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第 16-25 分钟&lt;/strong&gt;：你提出修改，意味着更多 tool call、更多终端输出、动态后缀里堆积更多上下文。到这时，整场会话已经处理了&lt;strong&gt;几十万 token&lt;/strong&gt;，但每一轮都在从缓存读那 2 万 token 的地基。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;第 28 分钟&lt;/strong&gt;：你在终端敲 &lt;code&gt;/cost&lt;/code&gt;。&lt;strong&gt;不带缓存&lt;/strong&gt;的话，Sonnet 4.5 的定价下 200 万 token 要花 &lt;strong&gt;$6.00&lt;/strong&gt;。带上 92% 效率的缓存，其中 184 万 token 是 cache read，总成本降到 &lt;strong&gt;$1.15&lt;/strong&gt;——&lt;strong&gt;单次任务减少 81%&lt;/strong&gt;。&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="439px" data-flex-grow="183" height="559" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://luoli523.github.io/p/llm-prompt-caching-explained/claude-code-session-cost.webp" srcset="https://luoli523.github.io/p/llm-prompt-caching-explained/claude-code-session-cost_hu_fb319275f820682f.webp 800w, https://luoli523.github.io/p/llm-prompt-caching-explained/claude-code-session-cost.webp 1024w" width="1024"&gt;&lt;/p&gt;
&lt;p&gt;这就是一个&lt;strong&gt;热缓存&lt;/strong&gt;应该长的样子：为静态地基付一次钱，然后免费读取任意多次。动态尾部是唯一会被持续计费的部分。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;鬼哥的使用体感&lt;/strong&gt;：我平时重度用 Claude Code，每次敲 &lt;code&gt;/cost&lt;/code&gt; 都会注意一下 &lt;code&gt;cache_read_input_tokens&lt;/code&gt; 这一栏——动辄占到整个输入量的 90% 以上，这个数字非常直观地告诉你&lt;strong&gt;缓存是不是在工作&lt;/strong&gt;。如果哪天命中率突然掉下去，基本就是提示你：你可能刚刚做了什么破坏缓存的事——比如中途换模型、或者手抖改了某个 subagent 的定义。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="五哈希缓存的脆弱性"&gt;五、哈希缓存的脆弱性
&lt;/h2&gt;&lt;p&gt;关于 prompt caching，最反直觉的一点是：&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;&lt;strong&gt;&amp;ldquo;1 + 2 = 3&amp;rdquo; 可以命中缓存，但 &amp;ldquo;2 + 1&amp;rdquo; 就是一次 miss。&lt;/strong&gt;&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;推理基础设施是&lt;strong&gt;从头开始&lt;/strong&gt;对整个 token 序列做哈希。只要序列里任何东西变了，哪怕只是两个元素的顺序——哈希就变了，&lt;strong&gt;整个前缀都要按全价重算&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="434px" data-flex-grow="181" height="565" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://luoli523.github.io/p/llm-prompt-caching-explained/hash-fragility.webp" srcset="https://luoli523.github.io/p/llm-prompt-caching-explained/hash-fragility_hu_c18a6052d25c30fa.webp 800w, https://luoli523.github.io/p/llm-prompt-caching-explained/hash-fragility.webp 1024w" width="1024"&gt;&lt;/p&gt;
&lt;p&gt;这不是什么实现细节，&lt;strong&gt;这是 Claude Code 所有工程决策背后最核心的约束。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;下面是生产环境里真实出现过的、破坏缓存的几个例子：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在 system prompt 里注入了一个&lt;strong&gt;时间戳&lt;/strong&gt;——每次请求都生成一个独一无二的哈希。&lt;/li&gt;
&lt;li&gt;一个 JSON 序列化器&lt;strong&gt;对 tool schema 的 key 排序不稳定&lt;/strong&gt;——前缀直接作废。&lt;/li&gt;
&lt;li&gt;一个 AgentTool 的参数在会话中途被&lt;strong&gt;动态修改&lt;/strong&gt;——2 万 token 的缓存全部报废。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;从这里可以推出&lt;strong&gt;三条铁律&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;不要在会话中途修改 tool。&lt;/strong&gt; Tool 定义是缓存前缀的一部分，加一个、删一个，都会让下游所有东西失效。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;永远不要在会话中途切换模型。&lt;/strong&gt; 缓存是按模型绑定的，意味着切到便宜模型继续对话，要重建整个缓存——省的钱可能还抵不上重建成本。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;永远不要通过修改前缀来更新状态。&lt;/strong&gt; Claude Code 的做法是：把提醒标签追加到&lt;strong&gt;下一条用户消息&lt;/strong&gt;里，而不是去编辑 system prompt——前缀永远不动。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;鬼哥补充一条&lt;/strong&gt;：你在写自定义 Agent 的时候，&lt;strong&gt;注意 Python dict 序列化成 JSON 时的 key 顺序&lt;/strong&gt;。Python 3.7+ 的 dict 是有序的，但如果你的 tool schema 有一部分来自合并多个 dict 或者来自数据库查询，顺序可能每次都不一样。这种隐性的不确定性，是最容易让你整夜找不到原因的 cache miss 来源。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="六应用到你自己的-agent"&gt;六、应用到你自己的 Agent
&lt;/h2&gt;&lt;p&gt;不管你是直接用 Claude Code，还是从头搭自己的 Agent，规则都是一样的。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;按这个顺序组织你的 prompt&lt;/strong&gt;：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;System 指令和行为规范&lt;/strong&gt;放在最上面。会话期间不要改。&lt;/li&gt;
&lt;li&gt;**Tool 定义一次性全部加载完毕。**不要中途增减。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;检索到的上下文和参考文档&lt;/strong&gt;接下来。会话期间保持稳定。&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;对话历史和 tool 输出&lt;/strong&gt;放最下面。这才是你的动态后缀。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="439px" data-flex-grow="183" height="559" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://luoli523.github.io/p/llm-prompt-caching-explained/prompt-structure.webp" srcset="https://luoli523.github.io/p/llm-prompt-caching-explained/prompt-structure_hu_23ced9a4cd27b397.webp 800w, https://luoli523.github.io/p/llm-prompt-caching-explained/prompt-structure.webp 1024w" width="1024"&gt;&lt;/p&gt;
&lt;p&gt;如果你用的是 Anthropic API 的 &lt;strong&gt;auto-caching&lt;/strong&gt;，缓存断点会随着对话增长自动推进。如果不用 auto-caching，你得&lt;strong&gt;手动管理 token 边界&lt;/strong&gt;——边界错了一个位置，就意味着完全错过缓存。&lt;/p&gt;
&lt;p&gt;对于&lt;strong&gt;上下文压缩&lt;/strong&gt;（当你快接近上下文上限时），要用**&amp;ldquo;缓存安全的分叉&amp;rdquo;&lt;strong&gt;这种做法：保留同样的 system prompt、tool、对话历史，然后把压缩指令作为一条&lt;/strong&gt;新消息追加**在后面。缓存前缀得以复用，真正要被计费的新 token 只有压缩指令本身。&lt;/p&gt;
&lt;p&gt;&lt;img class="gallery-image" data-flex-basis="439px" data-flex-grow="183" height="559" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://luoli523.github.io/p/llm-prompt-caching-explained/cache-safe-forking.webp" srcset="https://luoli523.github.io/p/llm-prompt-caching-explained/cache-safe-forking_hu_408380e2df72fa4b.webp 800w, https://luoli523.github.io/p/llm-prompt-caching-explained/cache-safe-forking.webp 1024w" width="1024"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;验证缓存是否在工作&lt;/strong&gt;，盯死 API 响应里这三个字段：&lt;/p&gt;
&lt;table&gt;
 &lt;thead&gt;
 &lt;tr&gt;
 &lt;th&gt;字段&lt;/th&gt;
 &lt;th&gt;含义&lt;/th&gt;
 &lt;/tr&gt;
 &lt;/thead&gt;
 &lt;tbody&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;cache_creation_input_tokens&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;写入缓存&lt;/strong&gt;的 token 数&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;cache_read_input_tokens&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;从缓存读取&lt;/strong&gt;的 token 数&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
 &lt;td&gt;&lt;code&gt;input_tokens&lt;/code&gt;&lt;/td&gt;
 &lt;td&gt;&lt;strong&gt;没走缓存&lt;/strong&gt;、按全价计费的 token 数&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;缓存命中率&lt;/strong&gt; = &lt;code&gt;cache_read_input_tokens / (cache_read_input_tokens + cache_creation_input_tokens)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;把它当成你的&lt;strong&gt;可用率（uptime）指标&lt;/strong&gt;来盯。命中率掉下去，就是警报。&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="七takeaways"&gt;七、Takeaways
&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Prompt Caching 不是一个你打开开关就能用的特性，而是一种必须贯穿到架构层面的纪律。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;核心思想其实简单到一句话：&lt;strong&gt;把静态内容放最上面，动态内容从下面长。&lt;/strong&gt; 基础设施会对前缀做哈希、存储 KV tensor、然后在你每一次读取时给你&lt;strong&gt;九折&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;但&lt;strong&gt;纪律藏在所有细节里&lt;/strong&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不要往 system prompt 里注入时间戳&lt;/li&gt;
&lt;li&gt;不要打乱 tool 定义的顺序&lt;/li&gt;
&lt;li&gt;不要在会话中途切换模型&lt;/li&gt;
&lt;li&gt;不要在缓存断点上游去修改任何东西&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Claude Code 在生产规模上演示了这套纪律的效果：&lt;strong&gt;92% 的缓存命中率，81% 的成本削减&lt;/strong&gt;。&lt;/p&gt;
&lt;p&gt;如果你正在搭 Agent 却没有围绕 prompt caching 做设计，&lt;strong&gt;你就是在把大部分利润留在桌上。&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="参考资料"&gt;参考资料
&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;原文推文：&lt;a class="link" href="https://x.com/_avichawla/status/2044670188998803855" target="_blank" rel="noopener"
 &gt;Prompt caching in LLMs, clearly explained - @_avichawla&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Anthropic Prompt Caching 文档：&lt;a class="link" href="https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching" target="_blank" rel="noopener"
 &gt;Prompt caching - Anthropic Docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item></channel></rss>