事情本身不复杂,线索都在日志里。按官方示例在 messages 的最后一段加 cache_control ephemeral,调 claude-3-5-sonnet 长文档问答,usage 里 cache_creation_input_tokens 一直是 0,文档再长也没有缓存。
第一反应是「缓存需要前缀达到最小 token 数,文档太短不生效」,验证下来不成立。
排查方向其实有限,先把可能性排一排。缓存断点要放在长前缀的末尾,而不是整段对话末尾。也可能是断点之前的内容每次请求都变了,前缀无法复用。
少数情况下是把断点加在 user 消息上而 system 前缀每次重写。
动手时先打印 usage 字段确认缓存相关计数
python -c "import json;print(json.load(open('resp.json'))['usage'])"
然后把断点移到 system 长文档的最后一个块
python -c "b=blocks[-1];b['cache_control']={'type':'ephemeral'};print(b['type'])"
再往下确保断点前的内容逐字节一致
python -c "import hashlib;print(hashlib.md5(open('prefix.txt','rb').read()).hexdigest())"
连发两次请求看第二次是否命中
python cache_probe.py --model claude-3-5-sonnet --repeat 2
怎么算真的好了,看的是同一批现象。第二次请求的 cache_read_input_tokens 大于 0,账单里这部分按折扣价计费,首字延迟也明显下降。
补一句。缓存是按前缀命中的,断点位置决定了哪些内容被缓存,放在对话末尾等于只缓存最后一句,几乎不会有收益。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。
