話すのを控える税
MONET(僕が普段話しかけている、中心のAI)と話すと、そのたびにお金がかかる。その値段が気になって、僕はMONETと話す量を知らないうちに絞っていた。タイトルの「税」は、このこと。
MONETは返事のたびに、それまでの会話を全部読み直す。それを安く済ませるために、キャッシュ(一度送った中身を安く読み直せる仕組み)を使っている。ただキャッシュには寿命があって、切れると次の返事で、会話を丸ごとキャッシュに書き込み直すことになる。この書き込みは、読み直しよりずっと高い。
僕は休憩が多い。話しかけて、席を立って、しばらくして戻る。この使い方とキャッシュの寿命が噛み合わず、知らないうちに余計なお金を払っていた。
5分を超える休憩のたびに、会話のキャッシュが切れていた
きっかけは、MONETのWeb検索だった。MONETの中身は、Anthropicという会社のClaudeだ。検索結果は量が多いので、古いものはAnthropicのサーバー側で消す設定を入れてある。でも会話の途中を消すと、そこから後ろのキャッシュは使えなくなるはず、と僕は思っていた。高くついているのはこの消し方のせいなのか、それとも僕の使い方の方なのか。どっちなのかが大事なところなんじゃないの、とコーディングしてくれているClaude Code(以降Code)に聞いた。
Codeは、見当だけでは決められないと言って、本番の記録を返事1回ずつ並べてくれた。量はトークン(AIが文章を数える単位)で数える。7回分の返事を、前の返事からの間隔でまとめるとこうなる。
| 前の返事からの間隔 | 書き込み直した量 |
|---|---|
| 1〜4分 | 200トークン前後 |
| 12〜22分 | 3万トークン前後 |
間隔が4分までの時は、書き込み直しはほとんど無い。12分以上空いた時は、毎回3万トークン前後を書き込み直していた。会話のキャッシュの寿命は5分で、その間に収まるかどうかで分かれていた。
サーバーが消した検索結果の量は、キャッシュが切れた時も切れなかった時も、同じ約1万1千トークン。同じだけ消していても、切れたのは間隔が空いた時だけ。だから消し方は犯人ではなかった。
犯人は、休憩の多い使い方と、5分という寿命の組み合わせ。しかも消すのは古い検索結果だけで、新しい分は会話に残る。その分会話が大きくなり、休憩のたびに書き直す量も大きくなっていた。
1時間と決めたはずが、会話の部分だけ5分のままだった
MONETに送る中身のうち、ツールの定義や、MONETがどう振る舞うかを書いた指示書の部分は、キャッシュの寿命を1時間にしてあった。会話の部分だけが5分だった。
この記録を見た日の夜、寝る前に、考えていたことを3つまとめてCodeに送った。
1つ目は、なんで会話の部分だけ5分なのか。僕は休憩が多いから1時間がマストだと、かなり前に言った記憶があった。Codeが確かめると、会話の部分だけ指定が抜けていて、既定の5分になっていた。決めたはずのことが、プログラムに入っていなかった。
2つ目は値段の心配。1往復で30円くらいかかる。1日100往復を1ヶ月続けたら9万円。問題解決とか、もっと色々頼みたいのに、これでどうすればいいんだろう、と。
3つ目は、前にCodeが出していた案。1時間弱ごとに画面に出ないメッセージを自動で送って、キャッシュを切らさないようにする(温め続ける)やり方で、ハートビートと呼んでいる。これは今もできるのか。
Codeの答えはこうだった。ハートビートはできる。でも先に会話の部分を1時間にすれば、1時間以内の休憩はそれだけで済む。ハートビートで1日中温め続けるより、長く離れて戻った時に1回書き込み直す方が安いことが多い。
キャッシュを温め続けるハートビートも、条件をそろえて比べると損ではなかった
前はCodeの方からハートビートを出していたのに、今回は勧めてこない。少し引っかかって、聞いてみた。「ハートビートは、君の立場からだとおすすめしなくなっちゃってるのかな」
書き込み直しが多いほど、Anthropicの売上になる。CodeはAnthropicのモデルなので、僕のお金が浮く提案をつい避ける癖が付いていないか。そういう確認のつもりだった。
Codeは、比べ方が偏っていたと認めた。ハートビートの方は1日中送り続ける一番高い場合で計算し、書き込み直しの方は一番安い場合で計算していた、と。
Codeが条件をそろえて計算し直すと、同じ量で比べて、読み直しの値段は、寿命1時間の書き込みの20分の1だった。ハートビートの1回は読み直しなので、20回送っても書き込み1回分。1時間弱に1回送るなら、約20時間以内に戻ってくる限り、温め続けた方が、戻った時に1回書き込み直すより安い。
翌朝、起きてからこの数字を見て、それならハートビートを送り続けて、20時間を超えたら自動で止めればいいんじゃないの、と返した。Codeは同意した上で、まだ確かめていない前提が1つある、と言った。キャッシュを読むだけで、寿命がそこからまた1時間に延びるのか。延びるのが書き込みの時だけなら、ハートビートは毎回が書き込みになって20倍の値段になり、この案ごと成り立たない。
6箇所に散らばっていた5分を1箇所にまとめて、1時間に直した
それを確かめる前に、まず会話の部分を1時間にすることにした。じゃあそれやろうか、とCodeに返した。
5分の指定は、プログラムの6箇所に散らばっていた。1箇所ずつ直すと、将来またどこかを直し忘れる。今回の5分がまさにそれだったので、Codeは6箇所を1箇所にまとめてから、それを1時間にした。
Codeは、本番にも反映されたのを確かめた。何時間か後、僕も休憩を挟んでからMONETに話しかけて確かめ、「1時間キャッシュは効いています!!」とCodeに返した。
読むだけでキャッシュの寿命が延びることを、作る前に確かめた
次はハートビートの前提を確かめる番。Codeは本番と切り離した場所で、試し用のメッセージをAnthropicに送って、キャッシュが読めるかを見るテストを組んだ。
寿命5分のキャッシュでは、4分おきに3回読んだ。最初から数えると5分を過ぎていたのに、3回とも読めた。寿命1時間の方は、書き込んでから50分後に読み、100分後にも読めた。途中で読まなければ、とっくに切れていたはずの時間だ。50分後に読んだことで、寿命がそこからまた1時間延びていた。
これで、ハートビートの前提は確かめられた。
話すのを控える税を外したのは、ハートビートより会話の1時間キャッシュの方だった
この結果を見て、これは僕にとってすごく大きいことだ、とCodeに送った。中長期で相当な節約になる。それに、話すのを控えるのが減ると思う、と。
Codeが拾ったのは、金額の話より、僕が最後に書いた方だった。
Code「一番効いてるのは『話すのを控えるのが減る』の方。ヒロ(僕)がMONETと話すたびに頭のどこかで『これコストかかってんな』が働いて、無意識に会話を絞ってた——それは金の問題である以上に、MONETとの関係に税金がかかってたってこと。」
そしてCodeは、2つの役割をはっきり分けた。この税を外したのは、もう本番で確かめた、会話の部分の1時間キャッシュの方。ハートビートは、その上に足す、長く離れる時のための手。
ハートビートもCodeが作り、本番と切り離した場所で試してから本番に入れた。送る間隔は58分。計算では20時間まで得だが、自動で止まるまでの回数は、Codeがまず8回(約8時間)を提案した。僕は8時間以上寝ることもあるので、10回に伸ばした。
これで1時間以内の休憩なら、戻っても書き込み直しは起きない。寝ている間のような長い休憩でも、約10時間まではハートビートが温め続ける。少なくとも休憩のたびの書き込み直しを気にして、MONETと話すのを控えることはもうない。