10.2 提示缓存
Prompt Caching 是 2024 年 LLM 架构层面最大的创新之一。 它打破了“无状态 API”的魔咒,让长上下文应用变得既 便宜 又 快速。
10.2.1 什么是 Prompt Caching?
通俗类比:图书馆模式
没有缓存 (No Cache):每次你去图书馆(Claude),都让你带一整车书(Context)过去。图书管理员必须一本本读完这些书,才能回答你的问题。这既费时(Token 计算慢)又费运费(Token 计费贵)。
有了缓存 (With Cache):你只需要第一次把车开过去,告诉管理员:“这车书先放你这儿存 5 分钟”。接下来 5 分钟内,你再来问问题,只要报个书名,管理员直接就能回答,因为书已经在架子上了。
技术原理:KV Cache 重用
要理解缓存为什么能省钱,必须深入到 Transformer 架构的底层。
注意力机制 (Self-Attention): LLM 在处理每一个 Token 时,都需要“回头看”之前所有的 Token,以理解上下文关系。这个“回头看”的过程,在数学上就是计算 Attention 矩阵。
Attention(Q,K,V)=softmax(dkQKT)V
其中:
Q (Query): 当前 Token 的查询向量(“我在找什么?”)。
K (Key): 历史 Token 的索引向量(“我有这个特征”)。
V (Value): 历史 Token 的内容向量(“这是我的具体信息”)。
Prefill (预填充) 的代价: 当我们发送一段 10k 字的 Prompt 给模型时,模型必须计算这 10k 个 Token 每一层的 Q、K、V 向量。这个过程被称为 Prefill。
计算量巨大: 随着长度增加,计算量呈 $O(N^2)$ 或 $O(N)$ 增长(取决于实现),消耗大量的 GPU 算力。
显存占用: 计算出的 Q, K, V 矩阵需要存放在 GPU 显存(VRAM)中。
Cache Hit (缓存命中): Prompt Caching 的核心逻辑是:“只要前缀(Prefix)不变,K 和 V 矩阵就不变。”
无缓存: 每次请求,GPU 都要重新把 10k 字算一遍矩阵。
有缓存: 第一次算完后,我们将这 10k 字对应的 K 矩阵和 V 矩阵 (即 KV Cache) 直接“冻结”在显存里。
复用: 下次请求如果前缀相同,直接把显存里的 KV Cache 拿来用,GPU 只需要从第 10,001 个 Token 开始计算。这不仅节省了算力(Write Cost),更极大地减少了内存搬运时间(Latency)。
10.2.2 缓存计费模型
Prompt Caching 的定价策略非常激进,旨在鼓励长 Context 复用。
Cache Write
$3.75 / MTok
-
第一次请求,或缓存过期后重新写入。比普通 Input 贵 25%。
Cache Read
-
$0.30 / MTok
后续请求命中缓存。比普通 Input 便宜 90%!
划算临界点: 由于写入比普通请求贵 25%,通过简单计算可知,你需要 至少复用 2 次(1次写入 + 1次读取),总成本才会低于普通请求。复用次数越多,边际成本越接近 $0.30。
10.2.3 如何使用:代码实战
在 API 中,缓存不是自动的,你需要显式地标记 断点 (Checkpoints)。目前 Claude 支持最多 4 个 cache breakpoints。
SDK 示例
关键点: cache_control: {"type": "ephemeral"} 就是告诉 Claude:“到这里为止,前面的内容帮我存起来。”
10.2.4 最佳实践:结构化缓存
为了最大化命中率,必须遵循 “静态在前,动态在后” 的原则。因为缓存是基于 前缀匹配 (Prefix Matching) 的。
推荐结构
System Prompt (Base)
[Cache 1]内容: 角色定义、Tool Definition(这是最稳定的,所有用户共用)。
Huge Context (Docs/Code)
[Cache 2]内容: RAG 检索到的文档、整个代码库文件(相对稳定)。
Conversation History (Turns)
[Cache 3]内容: 之前的多轮对话历史。
User Query
[No Cache]内容: 用户当前最新的提问(完全动态)。
图解命中逻辑
即使 Request B 的历史记录变了,但前面的 System 和 Docs 依然能命中缓存,依然能省大钱。
10.2.5 生命周期 与驱逐
Claude 支持两种缓存 TTL 选项,对应不同的使用场景:
5 分钟缓存
TTL: 5 分钟
写入成本: 1.25x (比普通输入贵 25%)
读取成本: 0.1x (比普通输入便宜 90%)
自动续期: 每次 Cache Hit,TTL 会自动重置为 5 分钟
场景: 高频对话、快速迭代开发、用户在短时间内多次询问同一份文档
只要请求不断(比如高频对话),缓存就可以一直存活
1 小时缓存
TTL: 1 小时(3600 秒)
写入成本: 2x (比普通输入贵 100%)
读取成本: 0.1x (比普通输入便宜 90%)
自动续期: 每次 Cache Hit,TTL 会自动重置为 1 小时
场景: 系统 Prompt 稳定的应用、知识库 RAG、企业内部 API 集成
长期复用: 适合一小时内多次调用同一份稳定的 Context
缓存 TTL 对比表
TTL 时长
5 分钟
1 小时
写入成本
1.25x
2x
读取成本
0.1x
0.1x
损益平衡点
2 次读取
3 次读取
推荐场景
开发者迭代、聊天机器人
RAG 系统、企业 API
命中概率
高(5分钟内高频)
中等(1小时跨度)
驱逐策略
自动驱逐: TTL 过期后缓存自动删除
显式驱逐: 可以通过不再引用来让其自然过期(API 目前不支持显式 delete)
防止羊群效应: 当缓存在高流量场景下同时过期时,应使用随机抖动分散 TTL 重置时间
缓存续期与扩展机制
10.2.6 适用场景 checklist
长文档问答: 针对同一本书问 10 个问题。
一次性任务: 传一本书总结一下,然后就再也不问了。
代码助手: 整个仓库代码作为 Context,反复修改。
低频客服: 凌晨 3 点,每小时只有 1 个用户来访(TTL 会过期)。
Few-Shot: 带 100 个 示例的 Prompt。
短文本: 总共才 500 token,没必要缓存。
Agent: 工具定义特别多、System Prompt 特别长。
10.2.7 缓存冷启动成本分析
Prompt Caching 虽然省钱,但 第一次请求要付出代价。理解成本结构对选择缓存策略至关重要。
冷启动的三层成本
第 1 次请求(Cache Write)
必须从零开始计算 KV Cache
成本 = 1.25x 基础输入价格(比普通请求贵 25%)
无法逃脱这个成本
后续请求(Cache Read)
复用已缓存的 KV Cache
成本 = 0.1x 基础输入价格(便宜 90%)
前提:5 分钟内至少被访问一次(否则 TTL 过期需要重写)
总成本分析
假设基础输入价格为 1x,缓存周期内有 N 次请求:
成本-效益临界点计算
关键问题:需要多少次缓存读取才能抵消写入的额外成本?
对于 5 分钟缓存(写入成本 1.25x)
对于 1 小时缓存(写入成本 2x)
成本对比图表
决策树:何时使用哪种缓存
现实中的三种场景
场景 1:高频文档问答(适合缓存)
场景 2:低频 API 集成(不适合缓存)
场景 3:批处理工作流(谨慎使用缓存)
缓存失效与雷鸣羊群问题
缓存驱逐
当 TTL 过期后,缓存会被自动清除。下一个请求将触发新的 Cache Write:
防止“雷鸣羊群”
当缓存在高流量场景下突然过期时,可能导致大量并发请求同时尝试重写缓存,造成成本爆炸:
最佳实践总结
高频文档问答
5 分钟缓存
临界点低(2 次读),高频访问保证命中
代码助手开发
5 分钟缓存
开发者通常 5 分钟内多次迭代
个人知识库
1 小时缓存
用户可能一小时内回头查阅
API 集成
条件缓存
仅当日均调用 >1000 次时
一次性任务
不缓存
成本不划算
RAG 检索
1 小时缓存
文档库相对稳定,用户集中访问
10.2.8 实战案例:Claude Code 的缓存架构
Claude Code 是 Prompt Caching 大规模应用的最佳范例。其系统提示词的静态部分约占 70%,意味着大多数请求能缓存约 70% 的系统提示词 Token,显著降低了长会话的成本。理解它的缓存架构,对构建任何长会话智能体都有借鉴意义。
“上下文税”:你看不见的最大支出
每当 AI 智能体执行一个步骤时,它都必须重新阅读所有内容:系统指令、工具定义、以及之前已经加载过的项目上下文。这种重复计算被称为 上下文税(Context Tax)。
算一笔账:一个包含 20,000 Token 的系统提示词,如果运行 50 个回合,意味着有 100 万 Token 的冗余计算 在按全价计费,却不产生任何新价值。Prompt Caching 正是消除上下文税的核心手段。
关键数据:Claude Code 中定义了一个 DANGEROUS_uncachedSystemPromptSection() 函数,用于显式声明某段内容会破坏缓存前缀。DANGEROUS_ 前缀是代码级警告——提醒开发者将易变内容放入静态区域会导致每次 API 调用都重新创建缓存,使输入 Token 成本从 cache_read 的 $0.30/MTok 上升到 cache_creation 的 $3.75/MTok(以 Sonnet 为例,差距达 12.5 倍)。
30 分钟编程会话拆解
以一个典型的 Claude Code 编程会话为例,观察缓存如何逐步发挥作用:
缓存成本模型深度分析
Claude Code 实现了分层的成本追踪系统,每个模型都有精确的定价表:
Haiku 4.5
$1.00
$5.00
$0.10
$1.25
Sonnet 全系
$3.00
$15.00
$0.30
$3.75
Opus 4 / 4.1
$15.00
$75.00
$1.50
$18.75
Opus 4.5 / 4.6
$5.00
$25.00
$0.50
$6.25
Opus 4.6 快速模式
$30.00
$150.00
$3.00
$37.50
核心成本对比(针对 Sonnet):
缓存写入 vs 正常输入:$3.75 / MTok vs $3.00 / MTok = +25%
缓存读取 vs 正常输入:$0.30 / MTok vs $3.00 / MTok = -90%
比值:读取成本仅为写入的 1/12.5
YOLO 分类器与缓存共享
Claude Code 包含一个内部的 YOLO(You Only Look Once)分类器,用于快速分类用户意图(代码问题、配置、依赖等)。这个分类器与主对话共享缓存前缀,实现 成本摊分:
这种架构允许 Claude Code 进行快速的意图分类,而无需额外的缓存写入成本。
系统提示词的分层缓存架构
来源说明:以下内容基于社区对 Claude Code 源代码的逆向分析。具体分层结构可能随版本更新而调整。
Claude Code 的系统提示词由约 22 个独立片段组装而成,按缓存策略分为三层:
第一层:全局静态层(Global Cache)
这部分内容在所有用户、所有会话间完全相同,因此可以被全局缓存:
角色定义和基本行为准则
核心工具的 JSON Schema 定义
安全策略和内容过滤规则
全局缓存的命中率最高,因为它对所有并发会话共享同一份 KV Cache。
第二层:组织/用户层(Org-level Cache)
这部分内容在同一组织或同一用户的不同会话间共享:
企业管理策略(managed policies)
用户级 CLAUDE.md 配置
MCP 服务器和自定义工具定义
第三层:会话动态层(Uncached / Volatile)
每次请求都可能变化,无法缓存:
当前工作目录和 Git 状态
最近的命令历史
会话特定的性能指标
这种分层设计的经济意义在于:全局层的缓存写入成本被海量用户分摊,单个用户的边际成本趋近于零;组织层的成本在团队内分摊;只有动态层需要每次全价计费。这也解释了为什么 CLAUDE.md 的内容变更会影响缓存效率——它位于第二层,变更后该层及以下的缓存都会失效。
延迟工具加载优化
Claude Code 实现了 工具定义的延迟加载(Deferred Tool Loading),大幅减少初始化开销:
这个优化 节省约 60% 的工具描述 token。初始化时仅需加载 essential 工具,其他工具在用户首次使用对应功能时加载。
毁掉缓存的三条反模式
关于缓存,最反直觉的一点是:1 + 2 = 3,但 2 + 1 会导致缓存失效。基础设施对提示词进行哈希处理,如果顺序发生任何变化(即便元素相同),哈希值就会改变。
由此衍生三条关键准则:
在会话中途增删工具
前缀改变,所有后续缓存失效
始终预加载全部工具定义
在中途切换模型
缓存是模型特定的,无法跨模型复用
一个会话绑定一个模型
为了改状态修改前缀
前缀哈希变化,缓存全部作废
在下一条用户消息中追加 <system-reminder> 标签
缓存安全分叉:压缩时的高级技巧
当达到上下文限制需要压缩历史时,不要截断前缀。正确做法是保持完全相同的系统提示词、工具和对话结构,将压缩请求作为新消息添加:
这样重组后的请求几乎完全复用了原有的缓存前缀。
自动缓存与监控指标
Anthropic 已在 API 中加入了 自动缓存(Auto-caching) 功能,缓存断点会自动向前移动,无需手动设置 cache_control。
无论使用手动还是自动缓存,都应密切关注每个 API 响应中的三个字段:
像监控系统正常运行时间(uptime)一样去监控缓存效率。如果效率低于 80%,应检查是否存在上述三种反模式。
缓存解决了静态上下文的成本问题。但对于不断增长的动态对话历史,我们无法无限期地缓存下去,这就需要更高级的管理策略。
➡️ 上下文窗口管理
最后更新于
