Prompt CachingOpenAIClaudeGeminiAPI 成本Nbility

Prompt Caching 真的省钱吗?同一份 12K 上下文算三家缓存账单

用 12,000 Token 固定前缀和 10 次请求,按 OpenAI、Claude 与 Gemini 官方缓存价格回放账单,拆解写入、命中、TTL、失效和盈亏平衡点。

Prompt Caching 真的省钱吗?同一份 12K 上下文算三家缓存账单

如果一个 Agent 每轮都携带相同的系统提示、工具定义、仓库规则和长文档,重复输入会反复计费。Prompt Caching 的承诺很直接:相同前缀只处理一次,后续请求按缓存读取价结算。

但“缓存输入便宜 90%”不是完整账单。你还要回答:

  • 首次写入是否加价?
  • 最少多少 Token 才会缓存?
  • TTL 是 5 分钟还是 1 小时?
  • 改一个字符会不会让整段失效?
  • 10 次请求以后,到底省了多少钱?

本文不伪造三组真实账号账单。实验环境没有三家可公开使用的生产密钥,因此采用官方价格 + 固定 Token 场景的可执行账单回放:输入规模和公式完全一致,脚本可以复算;缓存机制与价格截至 2026-07-19 逐项核对官方文档。它回答成本问题,但不冒充真实网络延迟 Benchmark。

先说结论

在本文的 10 次请求场景中:

方案无缓存输入费用使用缓存节省节省比例
OpenAI gpt-5.6-terra$0.302000$0.066500$0.23550077.98%
Claude Sonnet 4.6(5 分钟)$0.362400$0.079800$0.28260077.98%
Gemini 2.5 Flash(不计显式存储)$0.036240$0.007080$0.02916080.46%

这不代表 Gemini“缓存能力更强”,也不代表它在所有任务上更便宜。三家基础模型、输出价格、质量、上下文限制和缓存接口都不同。表格只比较固定 Token 场景下的输入侧账单结构

真正决定收益的是四件事:

  1. 可复用前缀有多长;
  2. 在 TTL 内复用多少次;
  3. 首次写入倍率;
  4. 请求是否保持精确或足够稳定的前缀。

实验怎么设计

固定参数:

固定前缀:12,000 input tokens
动态后缀:80 input tokens / request
请求次数:10
输出费用:不计入(各方案视为相同任务,本文只隔离输入缓存)
Gemini 显式缓存存储时间:默认按 0 小时计入主表

12K 前缀可以理解为:

  • 系统提示与安全规则;
  • 工具 Schema;
  • 仓库约定;
  • 一份长产品文档;
  • 每轮变化的用户问题放在末尾。

稳定前缀与动态后缀的正确排列

我们回放三种请求:

  1. Cold / Write:第一次发送完整前缀,创建或填充缓存;
  2. Warm / Read:保持 12K 前缀不变,只替换末尾 80 Token 问题;
  3. Miss:改动前缀中间内容,验证为什么后续部分不能继续按命中计算。

主表使用一次写入 + 九次读取。失效请求用于解释风险,不计入主表,否则不同供应商的路由和隐式缓存行为会让比较失去可复算性。

冷请求、缓存命中与前缀失效的三条路径

三家的缓存不是同一种产品

OpenAI:自动前缀缓存,新模型开始单独计算写入

OpenAI 对符合条件的请求自动启用 Prompt Caching。官方文档要求:

  • 默认至少 1,024 Token
  • 只对精确前缀匹配产生缓存命中;
  • 静态指令、示例、图片和工具定义放前面;
  • 用户变量放末尾;
  • gpt-4o 及更新模型支持缓存;
  • 使用 cached_tokens 观察读取量;
  • GPT-5.6 及以后还通过 cache_write_tokens 报告写入量,并支持显式断点;
  • GPT-5.6 及以后要获得更可靠的匹配,应设置稳定的 prompt_cache_key;官方建议单个键总流量约不超过 15 RPM,超过时按稳定规则分片。

一个重要的时效变化是:GPT-5.6 家族开始,缓存写入价为未缓存输入的 1.25 倍;读取价通常是输入价的 0.1 倍。旧模型通常没有额外写入费,不能把旧经验直接套到新模型。

本文选用官方价格页中的 gpt-5.6-terra

未缓存输入:$2.50 / MTok
缓存写入:  $3.125 / MTok
缓存读取:  $0.25 / MTok

对 GPT-5.6 及以后,prompt_cache_options.ttl 当前使用 30m:它表示前缀至少可复用 30 分钟,不是 30 分钟后必然失效。更早模型的内存缓存通常在闲置 5–10 分钟后清除、最长约 1 小时;部分旧模型可选最长 24 小时扩展保留。因此 TTL 探针必须按模型分别解释,不能把“等待 31 分钟”当成确定性 miss。

Anthropic:明确的缓存断点、5 分钟与 1 小时写入价

Claude 使用 cache_control。当前文档提供两种方式:

  • 顶层 cache_control 自动选择最后一个可缓存块;
  • 在内容块上设置显式断点,精确控制前缀。

TTL 有两档:

  • 5 分钟写入:基础输入价的 1.25 倍
  • 1 小时写入:基础输入价的 2 倍
  • 命中与刷新:基础输入价的 0.1 倍

Claude Sonnet 4.6 的官方价格是:

普通输入:$3.00 / MTok
5m 写入: $3.75 / MTok
1h 写入: $6.00 / MTok
缓存读取:$0.30 / MTok

对 Sonnet 4.6,最小可缓存长度是 1,024 Token。低于门槛不会报错,只是不会缓存。需要检查:

{
  "usage": {
    "cache_creation_input_tokens": 12000,
    "cache_read_input_tokens": 0
  }
}

后续命中时,写入量应降低,cache_read_input_tokens 增加。并发请求要注意:缓存条目要到首个响应开始后才可用;不能把十个请求同时打出去,再假定后九个全部命中。

Gemini:Interactions API 只有隐式缓存,generateContent 仍可显式管理

Gemini 当前文档必须区分两条 API 路线:

  • Interactions API:只支持隐式缓存,Gemini 2.5 及以后默认启用;
  • generateContent API:仍支持显式创建缓存对象和 TTL。

Interactions API 的当前最小输入门槛包括:

模型最少 Token
Gemini 3.5 Flash4,096
Gemini 3.1 Pro Preview4,096
Gemini 2.5 Flash2,048
Gemini 2.5 Pro2,048

隐式缓存应把稳定内容放在最前,并在短时间内发送相似前缀。命中量通过 usage.total_cached_tokens 观察。旧 generateContent 响应常见字段则是 cachedContentTokenCount,接入网关时不要把两种字段当成同一个原始 Schema。

Gemini 2.5 Flash 的官方价格:

普通输入:$0.30 / MTok
缓存读取:$0.03 / MTok
显式存储:$1.00 / MTok / hour

Google 的价格表把“缓存读取”和“显式缓存存储”分开。若只测试隐式缓存,不应凭空加一小时存储费;若创建显式缓存对象,就必须把存储时长加入总账单。

账单如何复算

设:

  • 固定前缀为 $P$;
  • 动态后缀为 $S$;
  • 请求数为 $N$;
  • 普通输入单价为 $U$;
  • 写入单价为 $W$;
  • 读取单价为 $R$。

不用缓存:

$$ C_{plain} = N(P+S)U $$

一次写入、后续命中:

$$ C_{cache} = PW + (N-1)PR + NSU $$

如果有显式存储费,再加:

$$ C_{storage} = P \times H \times T $$

其中 $H$ 是保留小时数,$T$ 是每 Token 每小时存储单价。

OpenAI 回放

无缓存:10 × 12,080 × $2.50 / 1M = $0.302000
有缓存:
  12,000 × $3.125 / 1M
+ 9 × 12,000 × $0.25 / 1M
+ 10 × 80 × $2.50 / 1M
= $0.066500

Claude 5 分钟回放

无缓存:10 × 12,080 × $3.00 / 1M = $0.362400
有缓存:
  12,000 × $3.75 / 1M
+ 9 × 12,000 × $0.30 / 1M
+ 10 × 80 × $3.00 / 1M
= $0.079800

Gemini 隐式缓存回放

无缓存:10 × 12,080 × $0.30 / 1M = $0.036240
有缓存:
  12,000 × $0.30 / 1M
+ 9 × 12,000 × $0.03 / 1M
+ 10 × 80 × $0.30 / 1M
= $0.007080

这里把第一次前缀按普通输入价计算,没有添加显式缓存存储费。若显式保存 12K Token 一小时,再增加:

12,000 × $1.00 / 1M × 1 hour = $0.012000

加上后 Gemini 此场景为 $0.019080,仍低于无缓存,但节省比例会从 80.46% 降低。

写入、读取与普通输入组成的账单结构

第几次复用才开始赚钱

忽略很短的动态后缀,盈亏平衡条件是:

$$ W + (N-1)R < NU $$

得到:

$$ N > \frac{W-R}{U-R} $$

写入策略写入倍率读取倍率第几次起总成本低于全量输入
OpenAI GPT-5.6 / Claude 5m1.25×0.1×第 2 次
Claude 1h0.1×第 3 次
Gemini 隐式(首次按普通输入)0.1×第 2 次

所以“只调用一次也开缓存”通常没有成本收益;1 小时缓存如果只使用两次,甚至可能更贵。TTL 应由实际重用间隔决定,而不是越长越好。

为什么你以为命中了,账单却没下降

1. 你改了前缀,不是只改末尾

缓存依赖前缀。时间戳、随机 ID、用户姓名或动态权限若放在开头,会让后续静态文档也无法复用。

正确顺序:

稳定系统规则
→ 稳定工具定义
→ 稳定参考文档
→ 用户/会话变量
→ 当前问题

2. 请求低于最小 Token

短 Prompt 加了缓存标记也可能安静地不缓存。必须检查 usage,而不是只看 HTTP 200。

3. 并发预热方式错了

首个请求尚未开始返回时,缓存可能还不可用。并行突发的十个冷请求不能直接等同于“一次写入、九次读取”。

4. 工具、图片或 Schema 发生变化

OpenAI 明确要求图片和工具也保持一致。对 Agent 来说,动态重排工具、每轮重新生成 JSON Schema,都可能破坏前缀。

5. 网关把相同前缀分发到不利于命中的渠道

这也是 MCP 与 A2A 协作架构 之外的另一层工程问题:协议能工作,不代表成本路径正确。多渠道网关若不了解缓存亲和性,普通负载均衡可能降低命中率。

网关必须记录哪些字段

只记 prompt_tokens 不够。至少要归一化:

统一指标OpenAIClaudeGemini
普通输入prompt_tokens 的未缓存部分input_tokenspromptTokenCount
缓存读取cached_tokenscache_read_input_tokenstotal_cached_tokenscachedContentTokenCount
缓存写入cache_write_tokenscache_creation_input_tokens依隐式/显式 API 处理
TTL 档位retention / model config5m / 1h缓存对象 TTL
命中率读取量与请求数读取量与请求数读取量与请求数

Nbility 后端已经区分这些语义:

  • OpenAI cached_tokenscache_write_tokens
  • Claude cache_creation_input_tokenscache_read_input_tokens
  • Claude 5 分钟和 1 小时写入量;
  • Gemini cachedContentTokenCount
  • 总体及 OpenAI/Claude 分项缓存命中率、读取量和写入量。

计费时还会把缓存读取、缓存创建和普通输入分开应用倍率,并防止上游重叠字段把普通输入扣成负数。这比把所有输入 Token 乘一个单价更接近真实账单。

可执行账单回放脚本

保存为 cost_replay.py

from dataclasses import dataclass

PREFIX = 12_000
SUFFIX = 80
REQUESTS = 10

@dataclass(frozen=True)
class Plan:
    name: str
    uncached: float
    write: float
    read: float

plans = [
    Plan("OpenAI gpt-5.6-terra", 2.50, 3.125, 0.25),
    Plan("Claude Sonnet 4.6", 3.00, 3.75, 0.30),
    Plan("Gemini 2.5 Flash", 0.30, 0.30, 0.03),
]

for p in plans:
    plain = REQUESTS * (PREFIX + SUFFIX) * p.uncached / 1_000_000
    cached = (
        PREFIX * p.write
        + (REQUESTS - 1) * PREFIX * p.read
        + REQUESTS * SUFFIX * p.uncached
    ) / 1_000_000
    print(p.name, round(plain, 6), round(cached, 6))

文章发布前已实际执行这份公式,得到文中主表。将 PREFIXSUFFIXREQUESTS 和官方价格换成自己的 usage 与模型价格,就能重建业务账单。

实际上线时怎么测

不要一次跑完三家然后比较总耗时。正确步骤是每家独立执行:

  1. 固定模型版本、区域、工具和生成参数;
  2. 记录请求 JSON 的稳定前缀哈希;
  3. 发送冷请求,等待响应开始;
  4. 连续发送 9 个只改变末尾问题的请求;
  5. 保存原始 usage、HTTP 总耗时和 TTFT;
  6. 修改前缀中部一处,再发送失效请求;
  7. 按供应商原生字段重建输入账单;
  8. 重复多轮并报告中位数和分位数。

本文没有三家生产密钥,因此不报告 TTFT 数字。缓存能降低处理工作量,但网络、排队、模型负载和区域都会影响延迟;用价格表推导 TTFT 会制造假数据。

什么时候不该用缓存

  • Prompt 本来就很短;
  • 相同前缀在 TTL 内只出现一次;
  • 每个用户的前缀都高度个性化;
  • 工具列表和权限每轮变化;
  • 1 小时显式存储成本高于复用收益;
  • 数据敏感性或保留政策不允许使用对应模式。

Prompt Caching 不是“打开后自动省 90%”,而是一个对请求布局、调度亲和、usage 归一化和计费模型都有要求的系统功能。

给生产团队的检查清单

  • 静态内容在前,动态内容在后
  • 前缀长度超过所用模型门槛
  • 首个请求响应开始后再依赖并发命中
  • 记录读取、写入和普通输入三类 Token
  • 区分 5 分钟、1 小时和隐式缓存
  • 监控请求命中率与 Token 命中率
  • 计算包含存储费的真实盈亏平衡点
  • 模型或工具 Schema 变更后重新预热
  • 网关路由避免无意义地破坏缓存亲和性
  • 价格页变化时重新执行账单脚本

结论

在 12K 固定前缀、10 次请求的账单回放中,三种方案的输入成本都下降了约 78%–80%。但收益来自“稳定前缀被连续复用”,不是缓存这个名字本身。

最实用的判断方法只有两个:

  1. 从原始 usage 重建读取、写入、普通输入和存储费用;
  2. 让实际请求次数、TTL 和前缀失效率进入公式。

如果你需要通过一个入口管理 OpenAI、Claude、Gemini 的模型与账单,可以在 Nbility 中统一配置渠道并查看用量;需要小额测试额度时,可在工单中心说明实验模型与场景。

官方资料

相关文章

用 Nbility 跑通你的 Agent 工作流

获取 API Key,统一接入 OpenAI 兼容模型和开发工具。

管理 API Key