最近折腾 New API 反代 Codex 的时候,发现一个挺让人头疼的问题:缓存命中率总是上不去。

缓存命中率低的示意图

缓存命中率低导致请求频频穿透到上游

本来想着通过反代和缓存机制来节省 tokens、加速响应,结果实际跑起来,数据一看,缓存几乎形同虚设,请求还是频频穿透到上游。这就导致成本没降下来,速度也没快多少,甚至有时候还因为并发请求把自己给限流了。

问题表现

简单复盘一下现象:当你配置好 New API 并对 Codex 模型进行反向代理时,预期是相同的输入能够直接命中缓存,毫秒级返回结果。但实际情况是,即便参数完全一致,系统依然频繁向上游发起请求。

HTTP请求头示意图

请求头中的动态字段差异导致缓存失效

这对于我们这种追求极致性价比和速度的玩家来说,简直是不可接受的。毕竟,谁能拒绝白嫖自己的缓存呢?

深入分析原因

经过一番排查和测试,核心原因大概率出在 请求头(Headers) 的差异 上。

很多反代工具(包括 Nginx)在配置缓存策略时,默认的缓存 Key($request_id)可能包含了某些动态变化的字段。比如 User-AgentX-Forwarded-For 甚至是某些带有时间戳的自定义 Header。

只要这些字段里的值有一点不一样,缓存系统就会认为这是一个“全新的请求”,从而直接去上游拉取数据,而不是读取本地缓存。

Nginx配置文件示例

配置Nginx proxy_cache_key 示例

此外,Codex 这类接口对于 Prompt 的格式非常敏感。如果转发的请求体经过了某种规范化处理(比如 JSON 字段顺序的变化、空格增减),也可能导致 Hash 值不一致,进而无法命中缓存。

实战解决方案

既然找到了病根,对症下药就不难了。这里分享几个经过验证的调优思路:

1. 精简缓存 Key 的构成

JSON规范化清洗示意图

规范化JSON请求体确保一致性

检查你的 Nginx 或 Gateway 配置。在定义 proxy_cache_key 时,不要直接用 $scheme$proxy_host$request_uri 这种大礼包。相反,我们应该只关注真正决定输出结果的参数。

对于 New API,通常只需要关注请求体中的特定模型参数、Prompt 内容以及 API Key 的特征值。你可以尝试写一段脚本或者利用 Nginx 的 Lua 模块,提取出关键参数来生成 Key。

例如,确保 Key 只包含 modelmessages 的序列化字符串,忽略掉无关的 Header。

Nginx proxy_ignore_headers 配置示例

使用 proxy_ignore_headers 忽略特定Header

2. 规范化请求体

在转发请求给上游之前,对 JSON Body 进行一次清洗。去掉不必要的空格,统一 Key 的顺序(比如按字母表排序)。这能确保同样的逻辑请求,在物理层面上也是完全一致的字符串。

3. 调整忽略 Header 策略

在 Nginx 配置中,使用 proxy_ignore_headers 指令,告诉缓存系统去忽略那些变来变去的 Header。比如:

proxy_ignore_headers Set-Cookie Expires;

同时,确保上游返回的缓存控制头(Cache-Control)是被正确解析的,不要因为上游标榜“不可缓存”你就真的不去缓存。如果业务场景允许,可以强制设置缓存时间。

4. 检查 New API 自身配置

如果你使用的 New API 版本自带缓存功能,记得检查后台的开关。有些版本对于同一个渠道的不同 Key 会做隔离,导致无法复用缓存。如果你使用的都是同一个上游 Key,务必确认没有做不必要的隔离设置。

总结

缓存命中率低不是玄学,多半是缓存 Key 的生成逻辑太“糙”了。把那些随风飘摇的 Header 剔除掉,守住核心的 Body 内容,命中率立马就能起飞。

折腾这些配置虽然有点费脑细胞,但看着命中率从 0% 跑到 80%+,那种成就感还是实打实的。省下的 tokens,刚好可以再多跑几个脚本,何乐而不为?

希望这篇笔记能帮到同样踩坑的朋友,有问题欢迎大家在评论区交流切磋!

标签: none

评论已关闭