同一个 system prompt 被反复发送 1000 次,每次都完整计算。这背后的浪费值得算一算。

大模型推理有一个你可能没注意到的优化:命中缓存。简单说,如果你的 prompt 前缀跟之前某次请求一样,模型不用重新算,直接复用上次的结果。

什么是命中缓存

大模型推理时,prompt 中每个 token 的 Key 和 Value 矩阵会被计算出来参与注意力运算。如果前缀没变,这些矩阵是确定性的——算过了存下来,下次直接用。

就像做数学题,前面的步骤算过了不用重算,只算新加的那一行。

需要注意,缓存的 token 仍然占用上下文窗口,不是独立存储。

省什么

两个维度。

省延迟。首 token 时间(TTFT)大幅缩短,因为前缀的计算被跳过了。对用户体验最直接的影响就是回复更快出现。

省钱。缓存命中的输入 token 有独立单价,比未缓存便宜得多。只省输入 token,输出 token 不受影响,每次生成都是新的。

算一笔账

用 DeepSeek 的实际价格算一下(DeepSeek-V4-Flash:缓存命中 $0.0028/M,未缓存 $0.14/M,截至 2026 年 5 月)。假设首次请求 miss,后续请求持续命中缓存:

短 prompt(~500 tokens,每天 1000 次请求): - 无缓存月费:500 × 1000 × 30 = 15M tokens → 15 × $0.14 = $2.10 - 有缓存月费:15 × $0.0028 = $0.04 - 月省 $2.06,绝对值不大,优化优先级低

中等 Agent(~2000 tokens,每天 1000 次请求): - 无缓存月费:60M tokens → 60 × $0.14 = $8.40 - 有缓存月费:60 × $0.0028 = $0.17 - 月省 $8.23,值得优化

超长 RAG(~50k tokens,每天 500 次请求): - 无缓存月费:750M tokens → 750 × $0.14 = $105 - 有缓存月费:750 × $0.0028 = $2.10 - 月省 $102.90,优化收益很高

那临界点在哪?大概的推导是这样的:缓存优化的收益 = 月 token 量 × (未缓存价 - 缓存价)。以 DeepSeek V4-Flash 为例,单价差 $0.1372/M。如果月省 $10 算「值得花时间优化」,那月 token 量至少要 73M。换算成日请求量:如果你的 prompt 是 1000 tokens,每天需要 2400+ 次请求;如果是 5000 tokens,每天 480+ 次就够了。粗略地说,prompt 超过 1000 tokens 且日请求量超过 100 次,就值得认真算一算。

命中条件

这是最关键的部分——不是所有请求都能命中缓存。

前缀必须完全一致。一个字符不同就 miss。你在 system prompt 里加了个时间戳?缓存全废了。

顺序不能变。不能在中间插入或修改内容。system prompt 放前面、用户消息放后面,就是为了最大化命中率。

各家有最低缓存 token 阈值。OpenAI 前缀需要 ≥1024 tokens,DeepSeek ≥64 tokens,Anthropic ≥2048 tokens,低于阈值不触发缓存。

缓存粒度也不同。OpenAI 按 128 token 的 block 匹配,不是逐 token 精确匹配。

命中是自动还是显式配置,取决于提供商。

各家实现对比

以下是截至 2026 年 5 月的各提供商缓存机制对比:

维度 DeepSeek OpenAI Anthropic
适用模型 V3、R1、V4-Flash gpt-4o、gpt-5、o3 等 Claude Sonnet 4.6、Claude Opus 4.7 等
缓存折扣 V4-Flash 98%(价为原价 2%),V3/R1 90% gpt-4o 50%,gpt-5 90%,o3 75% 90%(缓存命中价为输入价的 10%)
缓存写入价 同输入价 同输入价 输入价的 125%(首次写入更贵)
最低缓存 tokens ≥64 ≥1024 ≥2048
TTL ~5 分钟 ~5-10 分钟 5 分钟
配置方式 自动,零配置 自动前缀匹配 需手动标记 cache_control 断点

DeepSeek 折扣最狠,V4-Flash 缓存命中价只有未缓存价的 2%。如果预算敏感且 prompt 较长,DeepSeek 目前最划算。OpenAI 的 gpt-5 缓存折扣(90%)比 gpt-4o(50%)大很多,越新的模型缓存优化越激进。Anthropic 的缓存折扣同样是 90%,但需要显式标记断点,配置成本高一些,换来更精确的缓存控制。代价是缓存写入时要付 125% 的价格,所以首次请求反而更贵——只有后续命中才能回本。

代码实操

怎么在 API 调用中看到缓存是否命中?

OpenAI(Python SDK):

from openai import OpenAI
client = OpenAI()

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {"role": "system", "content": "你的长 system prompt..."},
        {"role": "user", "content": "用户的问题"}
    ]
)

# 读取缓存命中数
cached = response.usage.prompt_tokens_details.cached_tokens
total = response.usage.prompt_tokens
if total > 0:
    print(f"缓存命中: {cached}/{total} tokens ({cached/total*100:.0f}%)")

Anthropic(Python SDK): 需要显式标记缓存断点:

import anthropic
client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    system=[{
        "type": "text",
        "text": "你的长 system prompt...",
        "cache_control": {"type": "ephemeral"}
    }],
    messages=[{"role": "user", "content": "用户的问题"}]
)

# 读取缓存数据
print(f"创建缓存: {response.usage.cache_creation_input_tokens} tokens")
print(f"读取缓存: {response.usage.cache_read_input_tokens} tokens")

cache_creation_input_tokens 是首次写入缓存的 token 数,cache_read_input_tokens 是后续命中缓存的 token 数。

验证方法:第一次调用看 cache_creation_input_tokens > 0,第二次调用看 cache_read_input_tokens > 0。如果第二次仍然是 0,说明你的 prompt 结构有问题。

实操技巧

怎么让命中率最高?

Prompt 结构建议:

[System prompt — 稳定,放最前]
[工具定义 — 稳定,紧随其后]
[历史消息 — 按时间顺序累积]
[用户最新消息 — 放最后,变化最大]

频繁变化的内容放最后面,不要改前面的部分。长 prompt 比短 prompt 更值得优化,固定成本摊薄更明显。多轮对话中历史消息的累积会扩大缓存命中范围。

缓存预热。流量尖峰前先发一次请求建立缓存,后续请求才能命中。如果等流量来了才建缓存,第一批请求必须走完整计算。

边界和限制

TTL 过期后首次请求有冷启动。各家 TTL 不同(OpenAI ~5-10 分钟,Anthropic 5 分钟,DeepSeek ~5 分钟),过期后缓存失效,需要重新计算。

缓存不等于记忆。它只是省了重复计算,模型并不「记得」你之前问过什么。

输出 token 永远不会被缓存。每次生成都是新的。

并发场景下,缓存还没建立时第一批请求必须走完整计算。流量尖峰的第一个请求会比后续请求慢。

常见误区

「多加几条 system prompt 没关系」——每多一条都会改变前缀,可能打断缓存。system prompt 越精简越好。

「缓存会自动跨 session」——不会。缓存是按前缀匹配的,不是按用户或 session。两个不同用户的请求,如果前缀一样,也能命中同一个缓存。

「用了缓存就不需要优化 prompt」——缓存只是锦上添花。prompt 本身的质量(指令清晰度、结构合理性)仍然是第一位的。

「动态注入用户信息到 system prompt 没影响」——有影响,而且很大。如果 system prompt 里嵌入了用户名、时间戳等每次请求都不同的内容,前缀就永远不一致,缓存命中率会趋近于零。把这些内容放到用户消息里。

开源模型本地部署

如果你是自己部署模型,缓存逻辑类似但实现不同。用 vLLM 部署开源模型时,可以通过 --enable-prefix-caching 开启前缀缓存。没有 TTL 限制,不受提供商定价影响,但需要 GPU 显存来存储 KV Cache,粗略估计每 10k tokens 需要 1-2GB 显存(取决于模型大小、层数和精度)。对于 70B 模型处理 50k token 的上下文,KV Cache 大约会占用 10-20GB 显存。

取舍很清楚:API 缓存省心但受 TTL 和定价限制;本地缓存无 TTL 但需要额外显存投入。

最后

缓存命中不是什么高深技术,。它对 API 账单的影响取决于你的使用模式。短 prompt、低频调用的场景下优化收益很小,不值得花太多精力。真正值得投入的是长 prompt、高频调用的 Agent 和 RAG 系统。这种场景下缓存优化的月省幅度可以达到 90% 以上。

如果你还没看过自己 API 响应里的 cached_tokens 字段,建议先跑一次上面的代码看看命中率。可能比你想象的高,也可能比你想象的低。


数据来源: