Prompt caching 原理解析

@akshay_pachaar
英语4个月前 · 2026年3月09日
467K
1.1K
159
18
2.0K

TL;DR

深入探讨 Prompt caching 的运行机制,解析 KV caching 与架构优化如何助力 Claude 实现 92% 的缓存命中率,从而大幅节省成本。

Claude 如何实现 92% 缓存命中率:案例研究

每次 AI Agent 执行一个步骤,都要支付一次"税"。

它需要从头重新读取所有内容。

系统指令、工具定义、三回合前已经加载过的项目上下文——全部内容,每一回合都是如此。

这就是"上下文税"。对于长期运行的 Agent 工作流来说,这往往是整个 AI 基础设施中最昂贵的成本项。

我们来算一笔账:一个 20,000 token 的系统提示,运行 50 个回合,就意味着 100 万 token 的冗余计算 按全价计费,却没有任何新价值产出。

解决方案是提示缓存。但要用好它,你需要了解底层实际发生了什么。

从"什么会变、什么不变"开始

在优化之前,你需要清晰地思考 Agent 提示(上下文)的结构。

Agent 每次发送的请求包含两个截然不同的部分:

静态前缀: 包括系统指令、工具定义、项目上下文、行为准则。这些内容在会话的每一回合中都是完全相同的。

动态尾部: 用户消息、工具输出、终端观察结果。这部分在每个请求中都是独一无二的,并且随着对话的进行而不断增长。

Akshay 🚀 - inline image

这种区分至关重要。静态前缀是你一直在无谓地重新计算的高成本部分。动态尾部才是唯一需要全新计算的部分。

提示缓存的原理是存储静态前缀的数学状态,这样未来的请求就可以完全跳过重新计算。你为首次处理该前缀付费一次,后续的每一回合都从内存中读取。

为什么这很有效:Transformer 的实际运作方式

要真正理解缓存为何如此高效,你需要了解模型在读取你的提示时内部发生了什么。

每次 LLM 的推理请求都有两个阶段:

阶段 1:预填充(Prefill)

这是模型处理你的完整输入提示的阶段。它是计算密集型(compute-bound)的,意味着它对上下文中的每个 token 执行密集的矩阵乘法运算。模型读取所有内容并构建其表示。这是一个缓慢且昂贵的阶段。

阶段 2:解码(Decode)

这是模型逐个生成输出 token 的阶段。它是内存密集型(memory-bound)的,因为模型大部分时间都在读取先前计算好的状态,而不是执行繁重的计算。

Akshay 🚀 - inline image

在预填充阶段,Transformer 为每个 token 构建三个向量:Query、Key 和 Value。注意力机制利用这些向量来计算每个 token 与序列中其他所有 token 之间的关联。

关键洞察在于:Key 和 Value 向量仅取决于它们之前的 token。 一旦针对某个前缀计算完成,它们就再也无需更改。

下图直观地解释了我们刚才讨论的内容:

Akshay 🚀 - inline image

没有缓存,这些 Key-Value 张量会在请求完成后立即被丢弃。下一个请求将从头开始,再次为全部 20,000 个 token 重新计算它们。

KV 缓存通过存储这些张量来解决这个问题。 基础设施将它们保留在推理服务器上,并通过输入文本的加密哈希值进行索引。当一个具有相同前缀的新请求到来时,哈希值匹配,张量被立即检索出来,模型就跳过了所有计算。

这将每个生成 token 的计算复杂度从 O(n²) 降低到 O(n)。对于一个重复 50 回合的 20,000 token 前缀来说,这是一个巨大的降幅。

经济账

理解定价结构使得这个架构决策的影响如此之大。

以下是 Anthropic 在其模型系列中的缓存定价方式:

Akshay 🚀 - inline image

需要内化的三个数字:

  • 缓存读取价格是 基础输入价格的 10%,即从缓存读取的每个 token 享受 90% 的折扣
  • 缓存写入价格比基础输入价格 高 25%,这是为存储 KV 张量支付的少量溢价
  • 延长至 1 小时的缓存价格是 基础价格的 2 倍

只有当你的缓存命中率保持在高水平时,这笔账才算得过来。这就引出了实际中最能说明问题的一个案例。

Claude Code:30 分钟会话演练

Claude Code 完全围绕一个目标构建:保持缓存热度。

为了理解这具体意味着什么,我们来逐步拆解一个典型的 30 分钟编码会话,并精确追踪哪些部分产生了费用,哪些没有。

第 0 分钟:会话开始

Claude Code 加载其系统提示和工具定义。它还会读取项目根目录下的 CLAUDE.md 文件,该文件描述了代码库和约定。这个载荷通常超过 20,000 个 token。

这是整个会话中最昂贵的时刻。每一个 token 都是新的。但你只需要支付这一次费用。

第 1 到 5 分钟:首批命令

你输入第一条指令,例如:"查看 auth 模块并提出改进建议"。

Claude Code 派遣一个 Explore Subagent(探索子 Agent)。它浏览代码库、打开文件、运行 grep 命令,并构建相关代码的概览图。所有这些信息都会被追加到动态尾部。

那 20,000 token 的静态基础呢?已经在缓存中了。以 $0.30/百万 token 的价格被读取,而不是 $3.00/百万 token。你只需要为新的工具输出和你的消息付费。

第 6 到 15 分钟:深度工作

Plan Subagent(计划子 Agent)接收来自 Explore Subagent 的发现。Claude Code 不会逐字传递原始结果(这会不必要地膨胀动态尾部),而是传递一个简洁的摘要。这保持了尾部的可控性和缓存的高效性。

计划器生成一个结构化的实施方案。你审查、批准,然后 Claude Code 开始进行修改。这个循环中的每一轮都从缓存中读取 20,000 token 的前缀。每次缓存命中都会重置 TTL(生存时间),为后续轮次保持缓存的活跃度。

第 16 到 25 分钟:迭代

你要求调整。Claude Code 修改其方案。更多的工具调用,更多的终端输出。动态尾部正在增长,但它仅代表本次会话中新的、独特的内容。

至此,本次会话总共已经处理了数十万个 token。但那个 20,000 token 的基础,每轮都是从缓存中读取的。

第 28 分钟:运行 /cost 命令

没有缓存的情况下,这样的一个会话很容易超过 200 万 token。按 Sonnet 4.5 的费率计算,大约需要 6.00 美元

而在高效缓存运行的情况下:

  • 绝大多数 token 以 $0.30/百万 token 的价格从缓存读取
  • 只有新的动态尾部 token 才是全新计算的

在实践中,对于单个任务,你预计可以获得超过 80% 的成本降低。现在,将这个效果乘以每个用户、每一天。

总结一下,随着会话的进行,系统提示的布局如下所示:

Akshay 🚀 - inline image

打破一切的规则

以下是关于提示缓存最反直觉的一点。

1 + 2 = 3。但 2 + 1 会导致缓存未命中。

基础设施会对提示进行哈希处理。哈希值是一个用于加密的标识符。如果顺序有任何变化,即使只是两个元素的顺序不同,哈希值也会改变。缓存是空的。整个前缀将以全价重新计算。

由此产生的三条规则:

  1. 在会话过程中不要添加或移除工具。缓存的前缀包含工具。更改工具会使之后的所有内容失效。
  2. 永远不要在会话中途切换模型。缓存是针对特定模型的。在对话中途切换到更便宜的模型需要重建整个缓存。
  3. 永远不要为了改变状态而改变前缀。相反,Claude Code 会在下一条用户消息中添加一个标签来提醒系统。前缀从不改变。

这对你的意义

以上解释了 Claude Code 如何处理缓存。如果你正在构建自己的 Agent,同样的规则也适用。

以下是如何构建你的提示:

  • 顶部是系统指令和规则。中途不要更改。
  • 预先加载你需要的所有工具。不要添加或移除它们。
  • 之后是检索到的上下文和文档。在会话期间保持静态。
  • 底部是对话历史和工具输出。

启用自动缓存后,断点会随着对话的进行自动向前移动。

Claude Code 负责管理自己的缓存。Anthropic 刚刚在其 API 中增加了自动缓存功能,因此你也可以为自己的 Agent 实现同样的功能。

如果没有自动缓存,你需要记住 token 的边界在哪里。一个错误的边界意味着无法命中缓存。

Akshay 🚀 - inline image

使用缓存安全的分叉(cache-safe forking)来压缩以适应上下文限制。使用相同的系统提示、工具和对话,然后将压缩指令作为一条新消息添加。

Akshay 🚀 - inline image

压缩调用看起来几乎与上一次调用完全相同。缓存的前缀被再次使用。唯一按新内容计费的是压缩指令。

要检查 API 是否按预期工作,请关注每个响应中的这三个字段:

  • cache_creation_input_tokens(缓存创建输入 token):放入内存的 token 数
  • cache_read_input_tokens(缓存读取输入 token):从内存读取的 token 数
  • input_tokens(输入 token):正常处理的 token 数

你的缓存效率得分是比较读取 token 数与创建 token 数。请像关注服务正常运行时间一样关注这个指标。

核心要点

提示缓存不是一个你可以"打开"的功能。它是一种你需要围绕其构建的架构纪律。

Claude Code 是大规模实践这一纪律的最佳范例。

缓存命中率高达 92%。成本降低了 81%。

如果你正在构建 Agent,这就是蓝图。你无法忽视上下文税,它确实存在。唯一重要的是,你是在为它买单,还是在消除它。

参考文献:

一键保存

使用 YouMind AI 深度阅读爆款文章

保存原文、追问细节、总结观点,并在一个 AI 工作空间里把爆款文章沉淀成可复用笔记。

了解 YouMind
写给创作者

把你的 Markdown 变成干净的 𝕏 文章

图片上传、表格、代码块,往 𝕏 上手动重排太痛苦。YouMind 把整篇 Markdown 一键转成干净、可直接发布的 𝕏 文章草稿。

试试 Markdown 转 𝕏

更多可拆解样本

近期爆款文章

探索更多爆款文章