Agent X-Ray
RuntimeNotesAbout
Notes/AI 前沿/大厂技术博客档案/第12章

LLM 提示词缓存原理详解 — 以 Claude Code 92% 命中率为例

7 分钟 · 更新于 2026-09-01 · 原文

核心要点

  • 冗余成本是最大开销:20k token 的系统提示跑 50 轮,就是 100 万 token 的重复计算,按全价计费但产生零新价值。
  • KV 缓存把 prefill 从 O(n²) 降到 O(n):推理服务器按 token 序列的密码学哈希把 Key/Value 张量持久化,相同前缀直接从内存加载,跳过预填充计算。
  • 定价杠杆:缓存读 0.1x(9 折 off),缓存写 1.25x,1 小时扩展缓存 2.0x — 只要命中率够高,账单可以压到零头。
  • Claude Code 是最佳产线样本:30 分钟会话、200 万 token,在 92% 命中率下从 $6.00 降到 $1.15,降本 81%。
  • 三条铁律:会话中不改工具、不切模型、不修改前缀任何字节(时间戳、JSON key 排序、工具参数变更都会让整个 20k token 前缀作废)。
  • Prompt 结构必须"静态在上、动态在下":系统指令 → 工具定义 → 检索上下文 → 对话历史;用 cache-safe forking 做上下文压缩;用 cache_read_input_tokens / (cache_read_input_tokens + cache_creation_input_tokens) 当作命中率 SLI 监控。

原文 英文原文 作者:Avi Chawla(@_avichawla)— Daily Dose of DS 主理人 发布日期:2026-04-16


图像

一份关于 Claude 如何做到 92% 缓存命中率的案例分析

AI agent 每走一步,都要把完整的对话历史重新发给 LLM。

这里面包括系统指令、工具定义,以及三轮之前就已经处理过的项目上下文。所有这些内容在每一轮都会被重新读取、重新计算、重新计费。

图像

对于长时间运行的 agentic workflow,这部分冗余计算往往是整个 AI 基础设施中最贵的一项成本。

一个 20,000 token 的系统提示跑 50 轮,就意味着 100 万 token 的重复计算——按全价计费,但产生零新价值。而且这笔成本会在每个用户、每个会话上不断累积。

解法是提示词缓存 (Prompt Caching)。但要用好它,你得先理解底层到底在发生什么。

静态 vs. 动态上下文

在优化 prompt 之前,你得先搞清楚"哪些会变、哪些不会"。

每次 agent 请求,本质上都由两个截然不同的部分组成:

图像

  • 静态前缀 (static prefix):跨轮次完全一致的内容,包括系统指令、工具定义、项目上下文、行为准则。
  • 动态后缀 (dynamic suffix):每轮都在增长的内容,包括用户消息、助手回复、工具输出、终端观测。

正是这种切分让提示词缓存得以实现。基础设施会存储静态前缀的"数学状态",后续任何共享同一前缀的请求都可以直接跳过计算、从内存读取。

一旦你内化了这一点,本文后续所有架构决策都会变得显而易见。

KV Cache 是怎么工作的?

要理解为什么缓存如此有效,你得先知道 Transformer 处理 prompt 时到底在做什么。

每次 LLM 推理请求都分为两个阶段:

图像

  • 预填充阶段 (prefill phase):处理整个输入 prompt。它要对上下文里所有 token 做稠密矩阵乘法,构建模型的内部表示。这是典型的计算密集型 (compute-bound) 阶段,非常昂贵。
  • 解码阶段 (decode phase):逐 token 生成输出。每个新 token 被追加到序列尾部,模型预测下一个 token。这个阶段是内存密集型 (memory-bound),因为它主要是读取历史状态,几乎不做重计算。

在预填充阶段,Transformer 会为每个 token 计算三个向量:Query(查询)、Key(键)、Value(值)。注意力机制靠这三个向量决定每个 token 与其他 token 的关系。对于任一 token,它的 Key 和 Value 只依赖它之前的 token,一旦算出来就永远不变。

<video preload="auto" tabindex="-1" playsinline="" aria-label="嵌入式视频" poster="https://pbs.twimg.com/tweet_video_thumb/HGAcO8VbMAAEtV_.jpg" src="https://video.twimg.com/tweet_video/HGAcO8VbMAAEtV_.mp4" type="video/mp4" style="width: 100%; height: 100%; position: absolute; background-color: black; top: 0%; left: 0%; transform: rotate(0deg) scale(1.005);"></video>

没有缓存时,这些 Key/Value 张量在每次请求结束后都会被丢弃,下一次请求再从头算一遍。对于一个 20,000 token 的前缀,这就意味着 20,000 token 的注意力计算本可以不做。

键值缓存 (KV Cache) 的做法是:把这些张量持久化在推理服务器上,并用 token 序列的密码学哈希作为索引。当新请求带着相同前缀到来时,哈希命中,张量直接从内存加载,这部分 token 的预填充计算被完全跳过。

这把每个生成 token 的计算复杂度从 O(n²) 降到了 O(n)。而对于一个 20,000 token 前缀、重复 50 轮的会话来说,这是极为可观的削减。

经济账

真正让这个架构决策变得举足轻重的,是定价结构。

  • 缓存读 (cache read) 的价格是基础输入价的 0.1 倍——每个命中的 token 享受 90% 折扣
  • 缓存写 (cache write) 是 1.25 倍——为了把 KV 张量存下来,要额外付 25% 溢价。
  • 扩展 1 小时缓存 (Extended one-hour caching) 是 2.0 倍

Anthropic Claude 系列各个模型的具体价格如下:

图像

这套算术只在命中率足够高时才成立。而关于"高命中率产线长什么样",目前最好的参考样本就是 Claude Code。

Claude Code 的 30 分钟编码会话

Claude Code 的整个架构都围绕一个目标:让缓存一直是热的 (keep the cache hot)

下面是一次真实 30 分钟编码会话在账单上的样子:

第 0 分钟:Claude Code 加载系统提示、工具定义,以及项目里的 CLAUDE.md 文件。这个 payload 超过 20,000 token,而且每个 token 都是新的——这是整个会话中最贵的时刻。但你只付这一次。

第 1–5 分钟:你开始下指令,Claude Code 派出 Explore 子 Agent (Explore Subagent) 去遍历代码库、打开文件、执行 grep。这些都会被追加到动态后缀里。但此时 20,000 token 的静态前缀已经在以 $0.30/MTok 的缓存价被读取,而不是原本的 $3.00/MTok

第 6–15 分钟:Plan 子 Agent (Plan Subagent) 拿到的是一份总结简报,而不是原始结果——因为把原始输出塞进去会把动态后缀撑得过大。它产出一份实施方案,你批准后 Claude Code 开始改代码。每一轮都从缓存读取静态前缀,命中率爬过 90%,每次访问还会重置 TTL、让缓存保持温热。

第 16–25 分钟:你要求修改,于是有更多工具调用、更多终端输出、更多内容累积在动态后缀里。到此为止,这个会话已经处理了几十万 token,但每一轮依然从缓存读取那 20,000 token 的基础。

第 28 分钟:你在终端运行 /cost。如果没有缓存,200 万 token 按 Sonnet 4.5 的价格要 $6.00。但在 92% 缓存效率下,其中 184 万 token 是缓存读取,总成本变成 $1.15——单次任务降本 81%

图像

这就是热缓存的样子:静态地基只付一次钱,之后无限次免费读取。动态尾巴是唯一被持续计费的部分。

基于哈希的缓存有多脆弱

提示词缓存最反直觉的一点是:

"1 + 2 = 3" 能命中,"2 + 1" 就 miss。

基础设施是从头对整个 token 序列做哈希。只要序列里有任何东西变了,哪怕只是两个元素的顺序,哈希就会变,整段前缀都要按全价重新计算。

图像

这不是一个次要的实现细节,而是 Claude Code 所有工程决策都要围绕的核心约束。

下面是产线里真实出现过的"缓存被打爆"的案例:

  • 把时间戳注入到系统提示里 → 每次请求哈希都不同。
  • 一个 JSON 序列化器在两次请求之间用了不同的 key 排序 → 整个前缀作废。
  • 一个 AgentTool 的参数在会话中途被更新 → 整个 20,000 token 缓存被清空。

由此衍生出三条铁律:

  1. 会话中途不要改工具。 工具定义是缓存前缀的一部分,加一个或删一个工具都会让下游所有内容失效。
  2. 会话中途不要切模型。 缓存是和模型绑定的,切到便宜模型等于从头重建整段缓存。
  3. 不要为了更新状态去改前缀。 与其编辑系统提示,Claude Code 的做法是把一条提醒标签 (reminder tag) 追加到下一条用户消息上,让前缀保持不动。

把这套规则套到你自己的 Agent 上

不管你在用 Claude Code 还是从零造 agent,规则都是一样的。

你的 prompt 结构要按以下顺序组织:

  1. 系统指令和行为规则放最上面。 会话中途不要改。
  2. 所有工具定义一次性全部加载。 不要在中途增删。
  3. 接下来是检索到的上下文和参考文档。 整场会话保持稳定。
  4. 对话历史和工具输出放最下面。 这才是你的动态后缀。

图像

Anthropic API 的自动缓存 (auto-caching) 打开后,缓存断点 (cache breakpoint) 会随着对话增长自动前移。如果不开自动缓存,你就得自己手动跟踪 token 边界——边界划错,整段缓存就 miss。

当上下文快到上限、要做 context compaction(上下文压缩)时,用 cache-safe forking:保留同一套系统提示、工具、对话历史,只把压缩指令作为新消息追加进去。这样缓存前缀还能复用,唯一新计费的只有那条压缩指令本身。

图像

要验证缓存是否真的在工作,监控每次 API 响应里这三个字段:

  • cache_creation_input_tokens:写入缓存的 token 数。
  • cache_read_input_tokens:从缓存读取的 token 数。
  • input_tokens:未走缓存、正常处理的 token 数。

缓存效率 = cache_read_input_tokens / (cache_read_input_tokens + cache_creation_input_tokens),把它当 uptime 那样监控起来。

要点回顾

提示词缓存不是一个"一键打开"的特性,而是一种你必须围绕它来做架构设计的纪律。

核心思想很简单:让 prompt 的静态部分待在顶部、动态部分在底部增长。基础设施对前缀做哈希、存下 KV 张量,每一次后续读取都给你 9 折 off。

但纪律都藏在细节里——不要往系统提示里塞时间戳,不要打乱工具定义顺序,会话中途不要切模型,也不要改动缓存断点之上的任何东西。

Claude Code 以产线规模示范了这套打法:92% 命中率、81% 成本削减。如果你在造 agent 却没围绕提示词缓存做设计,那你就是在把大部分毛利白白丢在桌子上。


就到这里!

如果你喜欢这篇教程:

关注作者 → @_avichawla

每天分享数据科学、机器学习、LLM 和 RAG 的教程与洞察。


  • 英文原文:Original (English)
  • 相关主题:
    • Lessons from Building Claude Code: Prompt Caching Is Everything
    • Harness engineering: leveraging Codex
本章目录
KV Cache 是怎么工作的?经济账Claude Code 的 30 分钟编码会话基于哈希的缓存有多脆弱把这套规则套到你自己的 Agent 上要点回顾Related Documents
苏ICP备2025204887号-2