海域重启礼包码汇总 海域重启最新可用兑换码分享
2026-07-21
2026-07-22 0
所谓"缓存命中便宜、不命中贵",省的不是 token 本身,是模型把你的 prompt 跑一遍预计算(prefill)的算力。命中就是复用上次算好的中间成果、跳过重复计算;不命中就得从头再算一遍。同一段 system prompt,第一次老实算,后面次次白嫖——账单差就在这。

把大模型想成一个赶作业的学霸。你每次交的"卷子",开头都要写一段一模一样的 2000 字个人陈述(这就是你的 system prompt)。
这里的**"复印件"就是缓存(KV cache)**——模型算好的中间成果。
为什么只有"开头"能复印?因为模型是逐字往后读的,后面每个字的理解都依赖前面的字。只要前面一样,前面的计算成果就能整个搬来用;前面一改,后面全得重来。所以缓存只认前缀。
拿 Anthropic 定价举例(base $5 / 百万 token):一段 2000 token 的 system prompt,每次再带 50 token 的用户问题。
| 方式 | 单次成本 | 10 次总成本 |
|---|---|---|
| 不缓存 | 2050 token 全原价 ≈ $0.0103 | ≈ $0.103 |
| 缓存(首写 1.25x,后续读 0.1x) | 首 0.0013 | ≈ $0.024 |
省了 3/4 以上。 请求越多越省,百次级能砍掉 85%+。这还只是 2000 token 的 system prompt——如果你的 prompt 里塞的是一整份几万 token 的文档(RAG、长文档问答),差距会拉到 10 倍。
Transformer 处理你的 prompt 时,会把整段文字过一遍所有层。每一层都给每个 token 算出两组向量:Key(K)和 Value(V),合称 KV。生成回答时,模型靠 attention 去"回顾"前面所有 token 的 K 和 V。为了不每次重算,推理框架把算过的 KV 留在显存里——这就是 KV cache。
关键点:attention 是单向的,只往后看。 第 1 到第 N 个 token 的 KV 向量,只取决于这前 N 个 token 自己,跟后面跟了什么话没关系。所以只要两个请求的前 N 个 token 一模一样,它们前 N 个位置的 KV cache 就分毫不差。第二个请求直接把这块 KV 捞出来用,省掉前 N 个 token 的预计算。
这块显存其实挺贵。拿 Llama-2 70B 算一笔账:每个 token 每层 KV 约 4KB(FP16,GQA 后 8 个 KV head),80 层就是 320KB/token。一个 2000 token 的 system prompt,KV cache 要占 ~640MB 显存。每次请求都重算再扔掉,纯属浪费——prefix caching 就是把这块显存留住、复用。
推理框架不会傻到逐 token 比对,而是把 KV 切成固定大小的块(vLLM 用 PagedAttention,16 token 一块;SGLang 用 RadixAttention,前缀树组织)。匹配靠链式哈希:
key_0 = hash(tokens[0 : 16])key_1 = hash(key_0 || tokens[16 : 32])key_2 = hash(key_1 || tokens[32 : 48])...
为什么搞链式?因为两个 prompt 可能末尾一样、前面不一样。比如"A 国首都是巴黎,2+2=?"和"B 国首都是巴黎,2+2=?",最后那句"2+2=?"的 KV 其实不同——前面上下文变了,它 attend 到的东西就不同。链式哈希保证:只要前面某一块对不上,后面所有块的 key 全变,自然不会误命中。
flowchart LRsubgraph A["请求1: system + 问题X"]A1["Token 1..2000
system prompt"] --> A2["Token 2001..2010
问题X"]endsubgraph B["请求2: system + 问题Y"]B1["Token 1..2000
system prompt"] --> B2["Token 2001..2012
问题Y"]endKV[("GPU 显存
Token 1..2000 的 KV Cache")]A1 -->|"首次计算并驻留"| KVB1 -->|"命中前缀·直接复用"| KV
flowchart TDApp["应用层: 你的代码
cache_control / prompt_cache_key"] --> Product["产品层: 厂商 API
Prompt Caching / Context Caching
按命中差价计费"]Product --> Engine["系统层: 推理引擎
vLLM PagedAttention / SGLang RadixAttention
按块哈希命中前缀"]Engine --> GPU["物理层: GPU 显存
KV Cache
每层每 token 的 K/V 向量"]
我们平时说的"token 缓存命中",落到最底下就是物理层那块 KV 被复用了。
flowchart TDReq["新请求到达"] --> Hash["对 prompt 前缀做哈希"]Hash --> Match{"缓存里有
相同前缀?"}Match -->|"命中"| Reuse["复用已算好的 KV
只算尾部新增 token
按 cache read 低价计费"]Match -->|"不命中"| Full["整段 prefill 重算
按正常 input 价计费"]Full --> Store["把前缀 KV 写入缓存
供后续请求复用
部分厂商收写入费"]
两个反直觉、但必须记住的点:
| 厂商 | 触发方式 | 最小可缓存 | 命中折扣 | TTL | 写入费 |
|---|---|---|---|---|---|
| Anthropic | 显式 cache_control | 1024 token | 90% off(0.1x) | 5min(默认)/ 1h(付费) | 5min 写 1.25x / 1h 写 2x |
| OpenAI | 全自动(>1024) | 1024 token,128 递增 | 50%~90% 不等,越新越深 | 5–10min,1h 内清 | 老模型免费;GPT-5.6+ 写 1.25x |
| Gemini | 隐式自动 + 显式 API | 隐式 1024 / 显式 32768 | 隐式 75% off / 显式约 90% | 显式可配,默认 1h | 存储 $1.00/M token/小时 |
几个我踩过或观察到的坑:
prompt_cache_key 帮它路由命中。另外它返回 usage.prompt_tokens_details.cached_tokens,这是验证命中的唯一真实信号,别只看账单。cachedContent 是显式资源,TTL 默认 1 小时,适合"一份大文档被反复问"的场景。回到开头的"抄作业"比喻——你想 photocopy 的那段,必须每次都一模一样、且放在最前面。
1. 静态内容放最前,动态内容放最后。 这是铁律。system prompt、few-shot 示例、工具定义、RAG 文档这些不变的,全堆在 prompt 头部;用户每次不同的输入放尾巴。缓存只看前缀,尾巴随便变不影响前缀命中。
2. 顺序要稳定。 system → tools → 记忆 → 历史对话 → 当前消息,这个顺序每次保持一致。工具定义按名字排序(确定性顺序)。OpenAI 的匹配是"最长精确前缀",你 reorder 一下前面,整段缓存就断了。
3. 别在缓存前缀里塞"会变的量"。 时间戳、请求 ID、随机种子、当次日期——这些只要出现在被缓存的前缀段里,每次都不同,缓存必失。需要的话把它们挪到尾部动态区。我见过有人把 当前时间:{now()} 写进 system prompt,结果缓存一次都没命中过,排查了半天才发现。
4. Anthropic 把 breakpoint 打在稳定边界上。 最多 4 个:system prompt 结尾、工具定义结尾、静态文档结尾、历史对话前缀结尾。每个 breakpoint 之前到上一个 breakpoint 之间的内容被缓存。让"会变的部分"恰好落在最后一个 breakpoint 之后。
5. 低频负载的处理。 5 分钟 TTL 对低频接口是诅咒——请求间隔一长,缓存早过期,你每次都交写入费。两个办法:用 1h TTL(写贵一倍,但命中赚更多);或者搞个缓存 warmer,定时用同一前缀打一个低成本请求把缓存焐热。
6. 一定要监控命中率。 别凭感觉。Anthropic 看 cache_read_input_tokens / cache_creation_input_tokens;OpenAI 看 cached_tokens;Gemini 看缓存对象的复用统计。命中率为 0 但你以为开了——多半是前缀没对齐或没过最小 token 阈值(1024)。
7. 不在每次都变的内容上浪费缓存。 缓存只对"会被重复的前缀"有意义。一份每请求都不同的 RAG 上下文塞进缓存,等于每次都写、从不读,纯亏写入费。判断标准一句话:这个前缀,后面还会有请求用一模一样的开头吗?不会就别缓存。
Token 缓存不是玄学,就是"相同前缀别重复算"这一件事,被三家包装成了不同的 API 和价目表。要把它用明白,记住三件事:静态前置、字节一致、盯着命中率。做到了,长 system prompt / 多轮对话 / 大文档问答这类负载,账单砍掉 60%~90% 很常见;做不到,你可能一直在交 1.25x 的写入费,还以为自己省了。