一、问题背景:长 prompt 的成本爆炸

做过 Agent 应用的人都遇到过这件事:精心设计了一个 30K tokens 的系统 prompt(角色定义、工具描述、few-shot 示例、style guide),每一次对话开头都要重新发一遍。10 轮对话就是 300K 输入 tokens 白白付钱。按 Claude Sonnet 4.6 的 $3 / 1M tokens 输入价算,光重复发的部分一次对话就是 $0.09,月活 10 万用户的 SaaS 应用一个月几万美金没了。

这就是 Prompt Cache 要解决的问题。

二、Prompt Cache 的原理

大模型推理时,输入 tokens 会被转成一组 KV cache(注意力机制里的 Key-Value 向量),这个过程占了推理总耗时的相当一部分。如果两次请求的前缀完全一样,理论上 KV cache 可以复用 —— 这就是 Prompt Cache 的底层逻辑。

Anthropic 的实现方式:

  • 开发者用 cache_control: {"type": "ephemeral"} 显式标记哪部分要缓存
  • 第一次请求会在服务端存下这段前缀的 KV cache,并按 1.25x 原价 收 cache write 费
  • 5 分钟 TTL(每次命中续期 5 分钟)
  • 后续请求只要前缀完全一致,命中后这部分按 0.1x 原价 收 cache read 费

核心收益是 cache read 价只有原价的 10%,相当于第二次起就 9 折给 90% 的内容。

三、如何启用:一个完整示例

Python SDK 的标准用法:

import anthropic

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    system=[
        {
            "type": "text",
            "text": "你是一个资深 Python 工程师...",  # 长度足够才能缓存
            "cache_control": {"type": "ephemeral"}
        }
    ],
    tools=[
        {
            "name": "search_docs",
            "description": "...",
            "input_schema": {...},
            "cache_control": {"type": "ephemeral"}  # 工具定义也能缓存
        }
    ],
    messages=[
        {"role": "user", "content": "..."}
    ]
)

# 响应里看 usage 字段
print(response.usage)
# CacheUsage(input_tokens=12,           # 非缓存输入
#            cache_creation_input_tokens=8200,  # 首次写入缓存
#            cache_read_input_tokens=0,         # 这次还没读到缓存
#            output_tokens=380)

第二次同样的 system + tools 发起请求时:

# cache_creation_input_tokens=0
# cache_read_input_tokens=8200    # 命中缓存,按 0.1x 计价
# input_tokens=15                 # 这次的新增 user 输入

关键是要把 cache_control 标记打在最长、最稳定的内容前缀末尾 —— 通常是 system prompt 或工具定义。每个请求最多可标记 4 个 cache block。

四、命中条件清单

缓存能不能命中,取决于这 5 个条件,缺一不可:

  • 前缀完全一致:从请求开头到 cache_control 标记的位置,token 序列必须完全一样。多一个空格、换行、字段顺序变了都会 miss。
  • cache block 顺序不变:如果有多个 cache_control 标记,它们的相对顺序不能换。
  • TTL 内有效:5 分钟未被命中就过期,每次命中续期。
  • 最小 token 数:Sonnet / Opus 至少 1024 tokens,Haiku 至少 2048 tokens,低于阈值的 cache_control 会被忽略。
  • 模型支持:Claude 3.5 Sonnet 之后的所有模型都支持。

实战中最常踩的坑是「前缀完全一致」—— 比如你在 system prompt 里塞了一个时间戳 当前时间:{now},每次请求时间都变,缓存永远 miss。

五、节省比例计算

假设场景:系统 prompt 8K tokens、每次 user 输入 200 tokens、输出 500 tokens、每天 1000 次调用、平均缓存命中率 80%。按 Sonnet 4.6 价格($3 / $15 per 1M)算一笔账:

方案每次输入价每天输入价每月输入价
不用缓存8200 × $3 / 1M = $0.0246$24.6$738
用缓存(80% 命中)200 次 write × $0.0308 + 800 次 read × $0.00266 = $8.3 / 天$8.3$249

每月输入成本从 $738 降到 $249,节省 66%。如果命中率上到 95%(高频场景),节省可以到 75% 以上。10 万 DAU 的 Agent 应用,一年下来真金白银省 5-6 位数。

简化的 ROI 公式:

节省比例 ≈ 命中率 × (1 - 0.1) - (1 - 命中率) × 0.25

命中率 50% 时省约 32%;命中率 80% 时省约 67%;命中率 95% 时省约 84%。

六、适用场景

什么场景能用好 Prompt Cache?四个典型:

  • 长系统 prompt:角色设定、行为规范、风格指南固定不变的对话机器人。
  • RAG 应用:检索到的文档片段如果对一段时间内的多个查询是相同的(比如「针对某文档的多个问题」),文档部分可缓存。
  • 多轮对话:把历史对话整段标记为缓存,每轮新增内容走 cache read。
  • Agent 工具定义:工具描述往往几 KB,几乎不变,缓存命中率接近 100%。

七、反模式:什么时候不要用

同样几个常见的「不要这样做」:

  • 不要缓存频繁变化的内容:把当前时间、用户当前 query 塞进 cache_control 之前的位置,命中率为零,还要白付 1.25x 的 cache write 费。
  • 不要拆得太碎:每个 cache block 都有 1024 tokens 最小阈值,超短 block 会被忽略。把 4 个 block 集中在前缀上比分散到全文有效得多。
  • 不要忽视 TTL:低频应用(比如 5 分钟内没几次调用)反而会因为缓存频繁过期 + 重写而变贵,这种场景关掉 cache 更便宜。
  • 不要在调试阶段开:开发期 prompt 改动频繁,每次改完就 miss,开了反而浪费。

八、结语

Prompt Cache 是 2024 年以来 LLM API 最被低估的成本优化武器。一个 Agent 应用从不用 cache 到用对 cache,月账单普遍能砍 50%-80%。配合 Batch API 的 50% 折扣,对可异步处理的任务,成本能压到「裸调用」价格的 1/4 以下。在 LLM API 单位价格不再每年砍半的当下,工程侧的优化收益反而比等模型降价更确定。