每轮请求的 system 开头拼了当前时间,日志里 cached_tokens 一直是 0,账单按全价扣;把时间戳挪到 user 消息之后,同一段 2400 token 的 system 第二天命中率回到九成。
原因不止一个,得分开看。缓存按最长公共前缀匹配,开头的动态内容直接断掉前缀;JSON 序列化时字段顺序每次不同,前缀字节不一致;请求里带了随机的 request_id 放在最前面;同一段文本在不同项目下调用,缓存不跨项目共享。
动手时先把 system 的 md5 打进日志,确认每轮是否一致
python -c "import hashlib;print(hashlib.md5(open('sys.txt','rb').read()).hexdigest())"
随后对比两次请求的 usage 里 cached_tokens 字段
python -c "import json;d=json.load(open('resp.json'));print(d['usage'])"
接着把动态内容全部后移,只保留固定指令在前缀
python build_prompt.py --template prompts/base.txt --strip-dynamic
剩下的就是用同一份前缀连发两次请求验证第二次命中
for i in 1 2; do python call.py --prefix fixed.txt; done
恢复的判定其实很直接。第二次请求的 cached_tokens 大于 2000,账单里该段按缓存价计费,system 的 md5 在连续请求中保持一致。
缓存命中的判定非常死板,前缀里任何一字节变化都会整段失效,凡是时间、随机数、用户名都放到前缀之后。报错文案容易误导,真正的原因往往在相邻那一层的日志里。
