PaPoo
cover

タイムスタンプひとつで全部だめになる話

最初に思ったのは、「これはかなり気持ちが悪い失敗だ」ということだった。エラーが出ないのに、裏ではずっと全額払い続けていたわけで、しかも原因が timestamp、set の順序、短すぎる prompt と、どれも見た目ではそれっぽく見えてしまうのが厄介だと思う。

特に印象に残ったのは、キャッシュって「だいたい同じ」では全然効かなくて、prefix が byte 単位で一致していないと容赦なく外れるところ。人間の感覚だと「この system prompt はほぼ同じだし、tool も同じだし」で済ませたくなるけれど、LLM のキャッシュはそういう曖昧さを一切見てくれない。だから、Current time: の1行が先頭にあるだけで全滅するのは、理屈ではわかっても実際に踏むとかなり痛い。こういう仕様は、使う側が「変わるものを先頭に置かない」という地味な作法を徹底しないといけないんだなと思った。

もうひとつ面白かったのは、Python の set の順序で cache hit が壊れる話。ふつうは「同じ tool 定義なら同じ」と思いがちだけれど、worker ごとに hash seed が違うので、並び順が変わることがある。API から見ると別の prefix になってしまう。こういうのは、アプリケーションのロジックというよりインフラ寄りの癖に見えるのに、課金に直結するのが怖い。しかも著者がログをちゃんと見なかったら、永遠に「なんとなく遅い」「なんとなく高い」で済まされていたはずで、cache_read_input_tokens を毎回記録しておけという話はかなり刺さった。

正直、この記事でいちばん納得したのは、キャッシュ最適化って「付けたら得する機能」ではなく、「壊し方がいくつもある機能」だという点だった。設定して終わりではなく、順序の固定、可変情報の退避、最小長の確認まで含めて初めて成立する。便利な仕組みほど、静かに失敗するんだなと思う。


参考: Claude Prompt Caching Hit 0 of 1,412 Calls: A Timestamp Killed It

同じ著者の記事