提示词缓存最低门槛:文档低估了 1.4-2.4 倍
一位客户反馈,我们的网关在达到模型文档标明的 token 数后,提示词缓存仍未生效。我们复现了这个问题,又通过另一条独立的服务路径重新测试了所有模型。这条路径来自规模最大的 AI 网关之一,结果精确复现了相同的差距。过于乐观的是文档,而不是某个网关:文档公布的最低值只是满足缓存条件的下限,并不代表达到这个长度就能命中缓存。对于自动缓存的模型系列,两者相差 1.4 到 2.4 倍。OpenAI 文档标注的是 1,024 个 token,实测首次命中的门槛约为 1,456 个 token;Gemini 2.5 Flash 文档标注的是 2,048 个 token,接近 5,000 个 token 才首次从缓存读取;Claude 只在显式标记的位置进行缓存,实测门槛与各模型文档值的偏差仅为几个百分点。
TL;DR
- OpenAI 文档标注的缓存最低门槛是 1,024 个 token,但两条路径实测的有效门槛约为 1,456 个 token。
- Gemini 2.5 Flash 文档标注的是 2,048 个 token,但接近 5,000 个 token 才首次从缓存读取,约为文档值的 2.4 倍。
- Claude 的显式
cache_control在文档标注的最低门槛附近命中,偏差仅为几个百分点(Opus 实测 1,073,文档值为 1,024)。 - GLM 5.2 和 DeepSeek V4 均未公布最低门槛,约 800 个 token 起即可读取缓存;MiniMax M3 无论长度如何,都报告约 114 个缓存 token。
- 自动缓存还需要 2 到 8 次调用预热,之后才会首次读取缓存。
每项测试都通过两条服务路径执行:一条是我们自己的网关,另一条来自规模最大的独立 AI 网关之一。只有两条路径结果一致时,我们才将其视为模型本身的行为。引入第二条路径是为了确定问题归属:如果差异能在无关厂商的技术栈上复现,原因就在模型,而不是我们的网关。OpenAI、Gemini 和 GLM 的交叉验证结果很明确:两条路径都能缓存,有效门槛也相同。但并非所有模型都能这样验证。第二个网关主要通过未实现厂商提示词缓存的 GPU 服务商托管开源权重模型,网关自身的 endpoint 元数据也逐一证实了这一点。未固定路由时,请求还会在这些服务商之间漂移,导致缓存亲和性丢失。无法通过第二条路径验证时,下文数据来自能够访问各厂商原生缓存 API 的路径。长度均按各模型自己的 token 计算,并通过返回的 usage 校准,而不是按字符数计算。每组测试都使用全新的前缀,并记录首次产生缓存读取的调用序号,而不是只测一次命中或未命中。
文档门槛与有效门槛之间的差距
文档公布的最低门槛只表示提示词从何时开始具备缓存资格。有效门槛则是重复发送提示词后,实际能够从缓存读取的长度。对于自动缓存的模型系列,这两个数字并不相同。
| 模型系列 | 缓存类型 | 文档最低门槛 | 实测首次命中门槛 | 差距 |
|---|---|---|---|---|
| OpenAI GPT-5.5 / 5.4-mini | 自动 | 1,024 | ≈1,456 | +40% |
| Gemini 2.5 Flash | 自动 | 2,048 | ≈5,000 | 2.4x |
| Gemini 3.5 Flash | 自动 | 4,096 | ≈5,200 | +27% |
| Claude Opus 4.8 / Sonnet 5 | 显式标记 | 1,024 | 1,073 | 一致 |
| Claude Haiku 4.5 | 显式标记 | 4,096 | 4,206 | 一致 |
OpenAI 在两条路径上的结果精确到 token 都相同:1,356 个 token 的提示词始终无法读到缓存,1,456 个 token 则可以。Gemini 的差距最大。起初扫描到 3,300 个 token 为止都没有任何缓存读取,看起来像是缓存未开启;将范围扩大到 5,000 个 token 后,两条路径都在相同长度稳定读到了缓存。文档中的 2,048 只是具备缓存资格的下限,并不代表此时就会提供缓存读取。
整项测试呈现出的规律很明确:显式标记的缓存,其规格准确;自动发生的缓存则不是。
最低门槛并非唯一未写入文档的变量
超过有效门槛只是必要条件,还不足以保证命中。自动缓存的模型系列需要预热:首次读取会出现在更靠后的调用中,而不是第二次调用。
- OpenAI:第 2 到第 3 次调用首次读取。
- Gemini:第 4 到第 8 次调用首次读取。
这会直接影响成本建模。6,000 个 token 的提示词已经超过 Gemini 文档和实测的所有门槛,但如果某个工作负载只发送两次就不再使用,仍可能两次都按全价计费,因为缓存尚未完成预热。即使长度符合条件,短时或突发流量也可能按未缓存费率计费。至少重复调用十二次并在调用之间留出稳定时间后,我们才会判定“无法缓存”。较短的扫描曾让 Gemini 出现假阴性,增加调用次数后才推翻这一结论。
缓存 token 数还会按固定区块取整,对账时需要考虑这一点:OpenAI 以 128 个 token 为一个区块,DeepSeek 以 64 个 token 为一个区块。对于包含 5,014 个 token 的提示词,如果读到 4,073 个缓存 token,这是部分前缀命中并取整到区块边界的结果,不是 bug。
可控缓存的规格是准确的
Claude 只缓存通过 cache_control 标记的片段,而且相关规格准确。我们验证的 Anthropic 声明全部成立:
- 各模型的最低门槛精确到 token。 Opus 4.8 和 Sonnet 5 文档标注的是 1,024 个 token,实测在 1,073 个 token 时首次读取;Haiku 4.5 文档标注的是 4,096 个 token,实测为 4,206 个 token。少量超出来自区块取整,不是门槛漂移。
- 读取费率为输入费率的 0.1x。 我们先根据各模型未命中缓存的记录推导输入价格,再根据命中记录反算缓存读取费率。Opus 4.8 和 Haiku 4.5 的结果均为 0.10,与文档中的倍数一致。
- 五分钟刷新,每次读取都免费续期。 写入一个前缀后,分别在两分钟、四分钟和六分钟时重新读取,每次都能命中。只要在每个五分钟窗口内读取一次,缓存项就会继续存活,且不会产生额外写入。
- 级联失效。 保持 system 前缀不变并定义一个工具,仅修改该工具的描述,就会强制重写其下游的全部 system 缓存。修改工具定义会使 system 和 message 缓存失效,与文档描述的层级关系一致。
测试还发现了一处文档之间的冲突。某份第三方表格将 Claude Opus 的最低门槛列为 4,096 个 token;实测在 1,073 个 token 时即可读取,因此 Anthropic 自己公布的 1,024 才是正确数字。
开源权重模型系列通常不公布门槛
上述模型系列至少公布了一个可能不准确的数字。开源权重模型和中国实验室推出的模型大多完全不公布最低门槛,只能靠实测确定。我们的厂商缓存对比分析了命中后各厂商实际费率与公开费率是否一致;这里仅讨论首次出现缓存读取时的提示词长度。
| 模型系列 | 文档最低门槛 | 实测首次命中门槛 | 粒度 |
|---|---|---|---|
| GLM 5.2 (Z.ai) | 未公布 | 两条路径均从 ≈800 起读取 | 64-token 区块 |
| DeepSeek V4 | 未公布 | 通过厂商 API 时从 ≈800 起读取 | 64-token 区块 |
| MiniMax M3 | 512 | 任意长度都报告固定的 ≈114 个缓存 token | 非标准 |
GLM 5.2 没有公布最低长度,两条路径均从约 800 个 token 起开始缓存,粒度为 64-token 区块,比所有公布门槛的模型系列都低。DeepSeek V4 同样未公布最低门槛,约 800 个 token 起即可读取,粒度也是 64-token 区块,但只有通过其原生缓存 API 时才会生效。DeepSeek 文档明确将缓存描述为 best-effort,不保证命中率,而中间网关呈现的行为正是如此:另一个网关通过一组 GPU 服务商提供 DeepSeek,其中只有 DeepSeek 自己的 endpoint 实现了缓存。路由未固定到该 endpoint 时,完全不会返回缓存读取。
MiniMax M3 的问题在于上报数字本身具有误导性。文档标注的最低门槛是 512 个 token,但从 200 到 5,000 个 token,无论长度如何,它都会从第一次调用开始报告固定约 114 个缓存 token。这个数字不会随提示词长度变化,即使路径根本没有执行缓存也会出现,因此它反映的是模型自身的记账方式,而不是实际复用了多少内容。较新的 OpenAI 模型从另一个方向说明了同一问题:usage 中的 token 字段可能与真实缓存行为不一致。缓存节省的成本很重要时,应根据 usage.cost 对账,而不是依据 token 数量。
最新模型正在改变规则
不能直接假设旧模型的行为会延续到新模型,有两项文档层面的变化需要关注。在 GPT-5.6 系列中,OpenAI 指南明确写明缓存写入费用是未缓存输入费率的 1.25x,而早期系列可以免费写入。该指南还将隐式缓存描述为在最新一条 message 上设置 breakpoint,这与跨多轮对话缓存稳定 system 区块前缀的模式不同。如果希望这些模型在不同 user 轮次之间复用稳定前缀,应设置显式 breakpoint,而不是依赖隐式路径。需要逐个模型确认写入倍数和最低门槛,因为这两项现在会因模型系列而异,而单个文档页面掩盖了这些差异。
应对方式
- 实测自己的有效门槛。 按自身使用的 token 逐步增加提示词长度,并记录首次返回缓存读取的长度。不要假设文档最低门槛就是开始命中的位置。
- 为预热预留成本。 对自动缓存厂商进行成本建模时,应将新前缀的前两到八次调用视为未缓存。
- 厂商支持显式标记时,优先使用显式标记。 Claude 的
cache_control提供了准确且可测试的规格:明确的最低门槛、读取费率、TTL 和失效规则。这种可预测性比一个无法依赖、看似更低的文档门槛更有价值。 - 新模型系列上线后重新建立基线。 在本次测试期间,同一厂商的不同产品线就已经出现最低门槛、写入价格和 breakpoint 行为的变化。
关于这些门槛背后的读取费率、TTL 和缓存键规则,可以查阅我们的提示词缓存指南,其中整理了各厂商的具体机制。
结论很简单:文档标注的最低值只是具备缓存资格的下限,并非命中门槛;对于自动缓存,两者相差 1.4 到 2.4 倍。真正决定账单的数字,应使用自己的 token 和实际流量进行验证。