报错是这么冒出来的。按文档把长 system prompt 放在最前面,用户问题放后面,期望命中缓存,结果账单里 cached_tokens 始终是 0,请求量每天两万次,同样的 system 文本每天重复用。
中间走过弯路,把「请求走的是两个不同项目 key,缓存不共享」当成主因,改完现象没变。
排查方向其实有限,先把可能性排一排。system 里拼了当前时间戳,前缀每次都不一样。也可能是缓存只对前缀生效,动态内容被放到了前面。
不容易想到的是,prompt 短于最小可缓存长度,达不到门槛。
动手时先把 system 文本做哈希,看两次请求是否相同
python -c "import hashlib;print(hashlib.md5(open('sys.txt','rb').read()).hexdigest())"
然后用返回的 usage 字段确认缓存命中
python -c "print({'cached_tokens':0,'prompt_tokens':3100})"
再往下把动态变量全部挪到消息末尾
python -c "print({'order':['static_system','few_shot','user_query','date']})"
同一 key 连发两次请求对比耗时
curl https://api.openai.com/v1/chat/completions -H "Authorization: Bearer $KEY" -d @req.json -w '%{time_total}\n'
恢复的判定其实很直接。第二次请求的 cached_tokens 大于零,首 token 延迟下降三成以上,账单里缓存部分单独计价。
缓存命中的前提是前缀逐字节相同,任何时间戳、随机 id 都要往后放,这是最容易忽略的一条。线上能稳定复现的问题都不算难,难的是只在大流量下才出现的那种。
