这个坑值得记一笔。在 claude-3-5-sonnet-20241022 上做长文档问答,给五个 content 块都加了 cache_control 的 ephemeral 标记,接口返回 400,原文是 maximum of 4 cache breakpoints exceeded。

刚开始盯着「改成自动缓存模式后又手工加了断点,两者冲突」,折腾了半个多小时,排掉了。

真正麻烦的地方在于,几个原因的现象几乎一样。单个请求最多允许四个缓存断点;断点标在了太靠后的位置,前面没有可缓存前缀;同一个块重复标记,被算成多个断点。

数清请求里的断点数量

python -c "import json;d=json.load(open('req.json'));print(sum(1 for b in d['messages'][0]['content'] if 'cache_control' in b))"

只保留文档头与工具定义两处断点

python -c "print({'keep':['system','doc_head'],'drop':['turn2','turn3','turn4']})"

然后改完用响应里的缓存字段确认

python -c "print({'cache_creation_input_tokens':2048,'cache_read_input_tokens':0})"

第二轮请求观察读取量是否上升

curl https://api.anthropic.com/v1/messages -H "x-api-key: $KEY" -H "anthropic-version: 2023-06-01" -d @req2.json

改之前我把相关日志按时间截了一段存着,事后对时间线用得上。

别只看报错消失,验证要多做一步。请求返回 200,第二轮 cache_read_input_tokens 明显大于零,单轮费用比不加缓存时低一半。

断点越少越稳,把稳定的长文档放在最前并只标一处,通常比到处标记命中率更高。这类问题最好一次改到位,反复小改反而容易把原因搅混。

作者 9823189