想靠 Gemini 缓存省钱?先别走 API 中转——三组测试的教训

目录

作者:litianc

时间:2026年3月10日

阅读时长:8分钟

前言

ClawParty 是我们内部的一个多模型对话平台,底层基于 OpenClaw 构建,目前主力模型是 Claude Haiku 4.5。最近在做成本审计时,我们把目光投向了 Gemini 3 Flash。

选择 Gemini 3 Flash 不只是因为便宜。从 PinchBench 等 benchmark 来看,Claude Haiku 4.5 的成功率为 67.0%,而 Gemini Flash 系列也在快速追赶——加上 Gemini 3 Flash 在推理和多模态任务上表现强劲、吞吐量超 200 tokens/s,作为 OpenClaw 平台上的备选模型完全够格。更关键的是价格:Gemini 3 Flash 的定价比 Haiku 便宜 50-60%(截至 2026 年 3 月,Gemini 3 Flash 输入 $0.50/M vs Haiku $1.00/M,输出 $3.00/M vs $5.00/M),如果再加上 Gemini 的隐式缓存(Implicit Caching),input token 可以再打一折——算下来成本能压到原来的 5-6%,非常诱人。

但我们的架构里有一层 NewAPI 中转代理,所有模型请求都经过这层代理做统一管理和计费。问题来了:隐式缓存在中转场景下还能生效吗?

为了验证这个问题,我花了一个下午跑了三组测试。结论先放在这里:不行,通过 NewAPI 代理无法触发 Gemini 隐式缓存。下面是完整的排查过程。

一、Gemini 隐式缓存机制简介

Google Gemini API 提供自动的隐式缓存机制,核心规则很简单:

  • 多个请求如果共享相同的前缀内容(比如 system prompt),Gemini 后端会自动缓存这些公共前缀
  • 缓存命中后,input token 费用享受 90% 折扣(只收 10%)
  • 最低门槛:Flash 系列需要 1024 tokens(包括 Gemini 3 Flash),Pro 需要 2048 tokens
  • 触发条件:相同 API key + 相同前缀内容(逐字节匹配)

不需要额外的 API 调用,纯自动生效——前提是满足上面的条件。

二、测试环境

项目
代理类型 NewAPI(支持 OpenAI 兼容 + Gemini 原生协议转发)
测试模型 gemini-3-flash-preview
System Prompt 约 1149 tokens 的专业知识 prompt
测试方式 固定 system prompt,变换 user query,观察 cached_tokens 是否 > 0

测试思路很直接:用同一个 system prompt 发多轮请求,如果缓存生效,从第二轮开始应该能在响应的 usage 字段中看到 cached_tokens(OpenAI 兼容格式)或 cachedContentTokenCount(Gemini 原生格式)大于 0。

三、测试一:OpenAI 兼容格式

先走最常用的 /v1/chat/completions 端点,这也是 ClawParty 目前在用的格式。

请求结构:

{
  "model": "gemini-3-flash-preview",
  "messages": [
    {"role": "system", "content": "<~1149 tokens system prompt>"},
    {"role": "user", "content": "What is Redis?"}
  ],
  "max_tokens": 30
}

5 轮请求,每轮间隔 3 秒,结果如下:

轮次 用户问题 prompt_tokens cached_tokens
1 What is Redis? 1149 0
2 What is Kafka? 1148 0
3 Explain Kubernetes. 1148 0
4 Redis follow-up (多轮) 1167 0
5 What is Docker? 1148 0

返回的 usage 结构长这样:

{
  "prompt_tokens": 1149,
  "completion_tokens": 26,
  "total_tokens": 1175,
  "prompt_tokens_details": {
    "cached_tokens": 0,
    "text_tokens": 1149
  }
}

五轮全部 cached_tokens: 0,NewAPI 仪表盘也没有显示缓存命中。第一个格式宣告失败。

四、测试二:Gemini 原生协议(小 prompt)

OpenAI 兼容格式走的是 NewAPI 的格式转换层,可能是转换过程中破坏了缓存条件。于是我切到 Gemini 原生的 generateContent 端点试试:

{
  "contents": [
    {"role": "user", "parts": [{"text": "What is Redis?"}]}
  ],
  "systemInstruction": {
    "parts": [{"text": "<~1149 tokens system prompt>"}]
  },
  "generationConfig": {
    "maxOutputTokens": 30,
    "thinkingConfig": {"thinkingBudget": 0}
  }
}

同样 5 轮,结果依然一样:

轮次 用户问题 promptTokenCount cachedContentTokenCount
1 What is Redis? 1149 N/A
2 What is Kafka? 1148 N/A
3 Explain Kubernetes. 1147 N/A
4 What is Docker? 1149 N/A
5 Explain microservices. 1149 N/A

注意返回的 trafficTypeON_DEMAND,即全价计费,没有任何缓存命中的迹象。响应中连 cachedContentTokenCount 字段都不存在——说明 Gemini 后端压根没有尝试匹配缓存。

五、测试三:Gemini 原生协议(大 prompt)

1149 tokens 刚过 1024 的门槛,可能比较边缘。为了排除这个变量,我把 system prompt 扩大到约 1967 tokens(远超门槛),并增加到 7 轮、间隔 6 秒:

轮次 用户问题 promptTokenCount cachedContentTokenCount
1 What is Redis? 1967 N/A
2 What is Kafka? 1967 N/A
3 Explain Kubernetes. 1966 N/A
4 What is Docker? 1967 N/A
5 Explain microservices. 1967 N/A
6 What is gRPC? 1967 N/A
7 Compare SQL vs NoSQL. 1968 N/A

7 轮,接近 2000 tokens 的前缀,依然没有触发缓存。到这里基本可以确认:问题不在 prompt 大小,而在中转代理本身

六、额外发现

三组缓存测试做完了,结论已经很清楚。不过测试过程中还踩了两个坑,和 Gemini API 的使用直接相关,顺便记录一下。

流式协议兼容性问题

通过 NewAPI 使用 Gemini 原生流式协议(streamGenerateContent)时,下游的 @google/genai SDK 会报错:

Incomplete JSON segment at the end

原因是 NewAPI 返回的流式响应以 } 结尾,缺少 SDK 期望的终止标记。这是一个已知问题。解决方案是切回 OpenAI 兼容格式(/v1/chat/completions),NewAPI 对这个格式的流式支持没有问题。

Thinking 模型的测试陷阱

gemini-3-flash-preview 是 thinking 模型。测试连通性时如果设 maxOutputTokens: 1,思考过程会吃掉全部 token 预算,导致实际输出为空(parts: null),看起来像是请求失败了。

正确的做法是加上 thinkingConfig: {"thinkingBudget": 0} 禁用思考,同时给 maxOutputTokens 留够空间(比如 10 以上)。

七、原因分析

回到最核心的问题:为什么缓存不生效?

Gemini 隐式缓存要求 相同 API key + 相同前缀(逐字节匹配)。而最可能的原因其实很简单——NewAPI 的核心设计理念就是多 key 轮转和负载均衡,这恰好和隐式缓存的前提条件冲突。具体来说,至少有三个环节可能破坏缓存条件:

  1. API Key 轮转 — NewAPI 后端配置了多个 Google API key 做负载均衡,不同请求落到不同 key 上,缓存自然无法跨 key 命中。这是最主要的原因。
  2. 请求内容被修改 — NewAPI 转发时可能对 payload 做了微调(增删字段、调整顺序),哪怕一个字节的差异就会导致前缀不匹配。
  3. 响应元数据丢失 — 退一步讲,即使后端确实触发了缓存,NewAPI 在转换响应格式时也可能丢弃了 cachedContentTokenCount 字段,导致我们看不到。

八、结论与建议

三组测试结果一致:通过 NewAPI 中转代理无法触发 Gemini 隐式缓存

如果你也在用类似的中转架构,并且希望享受 Gemini 的缓存折扣,有以下几个替代方案:

方案 优点 缺点
直连 Google API 隐式缓存自动生效,90% 折扣 需要 AIza... 格式的 key,可能需要科学上网
显式缓存 API 可控 TTL,更可靠 需要直连,额外的 API 调用
联系 NewAPI 服务商 可能有配置选项透传缓存 取决于服务商是否支持
接受无缓存成本 零改动 大量对话时成本偏高

我们最终选择了直连 Google API。在 ClawParty 中把 Gemini 配置为独立的 provider,填入 Google 原生 API key,绕过 NewAPI 中转。根据 Google 官方文档,直连模式下隐式缓存应当自动生效——后续我们会验证并更新结果。

一句话总结:Gemini 隐式缓存和 API 中转代理天然不兼容,想省钱就直连

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开微信扫一扫,即可进行扫码打赏哦