缓存
理解为什么有时候 Claude 几乎不要钱,有时候同一句话却贵得离谱——以及怎么把账单永远控制在前者。
先打个比方
你每天点同一家外卖。第一次下单,要填地址、电话、楼层、单元号——填得很烦。第二次再来,App 弹出一条「使用上次地址?」,你点「是」,三秒下单。
那条「上次地址」就是缓存。它把你已经做过的工作存了起来,下次同样的场景直接复用,不用从头来一遍。本质就这么简单。
LLM 的缓存也是这样。你和 Claude 的每一次对话,前面那一大段历史不会凭空消失——它每次都跟你的新消息一起送回服务器。如果两次请求的开头长得一模一样,服务器没必要把同样的内容重新「读」一遍——直接拿上次算好的中间结果接着用就行。这一步省下来的,就是钱和时间。
计算机里到处都是缓存
在认真讲 LLM 的缓存之前,先看看缓存这个概念有多普遍。它不是 AI 时代的发明——它几乎和计算机一样古老。
| 层级 | 缓存什么 | 为什么 |
|---|---|---|
| CPU L1/L2/L3 | 最近用过的内存数据 | 读 RAM 比读 cache 慢 100 倍 |
| 操作系统 | 最近读过的文件 | 读硬盘比读内存慢 1000 倍 |
| 浏览器 | 下载过的图片、JS、CSS | 本地读取比走网络快 |
| CDN(如 Cloudflare) | 热门网页的副本 | 用户离 CDN 边缘节点比离源站近 |
| Redis / Memcached | 数据库查询的结果 | 跑一次复杂 SQL 比读 Redis 慢 10–100 倍 |
所有这些,背后是同一个思路:用空间换时间。我多占一点存储,把算过、读过、传过的东西存下来,下次就不用再算/读/传一遍。
LLM 的缓存——尤其是我们这章主角「Prompt Cache」——是这个传统在 AI 时代的延续。原理一脉相承,只是缓存的对象从「文件、数据」变成了「模型对一段文字已经做过的处理」。
为什么 LLM 也要缓存
要理解 LLM 缓存为什么省钱,先看一次请求里到底发生了什么。
你以为你只发了一句「帮我看看这个文件」,但实际送到 Anthropic 服务器的是一大坨:
[系统提示词] Claude Code 自带的几千 token 的「使用说明」
[CLAUDE.md] 你项目的规则、技术栈、代码约定
[对话历史] 前面 20 轮的来回,包括工具调用结果
[本次消息] 你刚打的那句话
这一整坨是 input,是收费的。Claude 每次回答前都要把它从头到尾「读」一遍——专业说法叫预填充(prefill),也就是把这些 token 一个个喂进模型,让模型形成对当前对话的理解,然后才能开始生成回复。
问题来了:你下一句话发出去时,前面那一坨几乎完全一样。系统提示词没变、CLAUDE.md 没变、前 20 轮历史也没变——只是末尾多了你刚才那句新的而已。
「几乎完全一样」加上「每次都要重读」,这就是浪费。Anthropic 的工程师当然也想到了:能不能把上一次预填充得到的中间状态存下来,下次发现前缀一样,直接接着用?
能。这就是 Prompt Cache。
Prompt Cache 是什么
Prompt Cache 是 Anthropic API 提供的一项功能:服务器把你 prompt 的某段前缀「记住」一段时间,下次同样的前缀来了,直接复用之前的计算结果。
它有两个关键性质:
命中和不命中
缓存命中(cache hit)= 服务器发现你的 prompt 前缀和缓存里的一模一样,直接复用。
缓存未命中(cache miss)= 没找到匹配,得从头做完整的预填充。
命中要求严格:前缀必须完全一致。哪怕只改一个字符,缓存都会失效。
「前缀一致」这个限制,决定了什么会让缓存失效:
- 改了 CLAUDE.md——整个对话从此都得重新建缓存。
- 切了模型(Sonnet → Opus)——缓存按模型分开存,不通用。
- 用了
/compact——把对话历史压缩重写了,前缀全变了。 - 用了
/clear——直接开新会话,缓存彻底没了。 - 5 分钟没动——超时自动清理。
- 设置变了(系统提示、温度、tools 列表等)——任何一项改动都会让缓存按「另一个 prompt」处理。
听起来很脆弱,但实际用下来 Claude Code 已经替你做了不少优化——它会把那些「应该稳定不变」的部分(系统提示、CLAUDE.md、工具定义)单独标记为可缓存,让你的对话历史天然分层。
直觉小例子
想象服务器在缓存里存了一张你上次的「书签」,记录了它读到 prompt 的第 8000 个字符时的状态。下次你来,它先比对你 prompt 的前 8000 个字符是否和书签处一致——一致就直接从书签往后读,不一致就只能从头再读一遍。
怎么看缓存有没有命中
Claude Code 在 /usage 里直接告诉你。打开看到的会是这样的几行:
> /usage
Session
Input tokens 12,453
Cached input tokens 48,720 (cache read)
Cache creation tokens 2,180 (cache write)
Output tokens 1,837
Cache hit rate 94%
Estimated cost $0.038
读懂这几行就够了:
命中率低于 50% 就值得检查了:是不是频繁改了 CLAUDE.md、是不是过度 /compact、是不是会话太碎(每问一个问题就开新会话)。
怎么提高命中率
具体到日常操作,能做的事就这些:
- 不要频繁改 CLAUDE.md。它在每次请求里都会被发送,是缓存最稳定的「锚点」。改一个字,整条缓存链路都得重建。如果要调,集中调,别每聊几句就动它。
-
少用
/compact。压缩会重写历史,把前缀彻底打乱。除非上下文真的快满了,不然让它自然增长——每加一句新对话只会让缓存的前缀更长,命中越多越赚。 - 长会话比开很多短会话便宜。每开一次新会话,前几句都是 cache write(1.25 倍价)。同一个任务保持在一个会话里跑,是最省钱的姿势。
-
5 分钟内保持活跃。哪怕发个
/status也能让缓存续一秒。如果你知道自己要去开 30 分钟会,回来缓存肯定凉了——不用纠结。 - 不要随便切模型。Sonnet 和 Opus 的缓存分开存。来回切意味着两边都要重建缓存。如果一定要切,尽量切完留在新模型上跑一段时间。
-
批量任务用 Haiku +
/goal。Haiku 本身就便宜,加上缓存复用,一组重复性高的任务(比如「给这 30 个函数加 JSDoc」)跑下来几乎免费。 -
大文件不要反复
@。每次@一个大文件,它的内容会被塞进对话里。第一次@之后 Claude 已经看过了,后续再问相关问题不用再@一遍——它还记得。
算一笔账
抽象的「省 90%」没有感觉。来个具体数字。
场景:用 Sonnet 做一个 1 小时的功能开发任务,期间和 Claude 来回 40 轮。每轮发出去的总 input 大约 30k token(含历史),output 大约 800 token。
Sonnet 当前单价(2026 年 5 月):
- 普通 input:$3 / 1M token
- 缓存 input(read):$0.30 / 1M token
- 缓存 input(write):$3.75 / 1M token
- output:$15 / 1M token
| 方式 | 计费 input(按 40 轮 × 30k 计) | output | 总计 |
|---|---|---|---|
| 无缓存 | 1,200,000 全价 → $3.60 | 32,000 → $0.48 | $4.08 |
| 有缓存(命中率 90%) | 120,000 全价 → $0.36 1,080,000 缓存读 → $0.32 30,000 缓存写 → $0.11 |
32,000 → $0.48 | $1.27 |
同样一小时的活,账单差三倍。一个月按 20 个工作日算,每天一小时——前者 $80,后者 $25。一年差一千多刀。这还只是个人用,团队规模乘上去更夸张。
所以「让缓存命中」这件事,长期看不是一个可选的优化,是账单会不会失控的关键变量。
不要为了省钱牺牲思考
看到上面这个对比,可能会有人想「那我永远不 /compact、永远不开新会话」。别这样——上下文一旦真的满了,模型质量会下降,那时候省下的几毛钱抵不过一次错误决策的成本。缓存是顺手优化,不是核心目标。
KV Cache 是另一回事
你如果在论文或者博客里见过 「KV Cache」这个词,会觉得「咦,是不是同一个东西」?严格说,不是。它们都叫缓存、都和 LLM 有关,但层级完全不同。
| Prompt Cache | KV Cache | |
|---|---|---|
| 在哪一层 | API / 计费层 | 模型推理引擎内部 |
| 解决什么问题 | 跨请求复用,省钱 | 单次请求中加速生成,省时间 |
| 谁来管 | Anthropic 服务器 | 每次跑模型时自动有 |
| 用户能感知吗 | 能(账单 + 命中率) | 感知不到(只能看到回复变快) |
| 类比 | 外卖 App 记住你的地址 | 你大脑读句子时记住前几个字 |
简单说:KV Cache 让一次回复变快,Prompt Cache 让多次回复变便宜。这本书你不需要懂 KV Cache 的实现细节——它是模型推理的内部机制,自动开启,无需配置。但下次有人在 AI 群里聊起这两个,你大概知道他们是在说不同层的事。
最后一段话
缓存这个概念,归根到底就一句话:不变的部分,别再让它从头算一遍。
在 LLM 的语境里,这意味着:让那些理应稳定的内容(系统提示、项目规则、对话历史)保持稳定。Claude Code 替你处理了大部分细节——CLAUDE.md 自动进缓存层、对话历史按层级分块——你只需要做一件事:不要主动破坏它。
下次看到 /usage 里的 cache hit rate 是 94%,你应该感到一种平静的满足感——账单稳了,响应快了,整个系统在以你期望的方式运转。如果某天突然掉到 30%,你也知道该去查什么:是不是改了 CLAUDE.md、是不是过度 compact、是不是会话开太碎。
缓存不是 Claude Code 的某个功能——它是这一整代 LLM 应用得以「负担得起」的底层逻辑。读完这一章,你看 Anthropic 计费页面、看自家 API 调用日志、甚至看其他 AI 工具,应该都能用同一套眼光去理解。