Claude Codeのコスト、実は自動でキャッシュが効いている話

Claude Codeを使い始めると、しばらく経ってからAPIの請求額が気になってくる。長いセッションを繰り返す日が続くと「このペースで使い続けて大丈夫か」と思う瞬間がある。しかし、その心配の半分はすでに対処されている。Claude Codeは最初から prompt caching を使う前提で設計されており、ユーザーが何も設定しなくても自動的にキャッシュが効いている。

問題は「キャッシュを使っているかどうか」ではなく「知らないうちにキャッシュを壊す操作をしていないか」だ。Anthropicの公式ブログには「prompt cache hit rate を uptime monitoring のように扱い、アラート対象にしている」と書かれている。それほど重要な指標として扱われているものを、ユーザー側が気にしないのはもったいない。

この記事では、prompt cachingの仕組みと価格構造を確認したうえで、Claude Codeが内部でどう使っているかを公式ブログの記述をもとに読んでいく。「気づかないうちにキャッシュを壊している」典型パターンも後半でまとめた。

Prompt Cachingの仕組みと価格

Anthropic APIのprompt cachingは、プロンプトの先頭部分(プレフィックス)をサーバーサイドでキャッシュし、次回以降のリクエストで再利用する機能だ。仕組みはシンプルで、ブレークポイントまでのトークンがキャッシュに存在すれば「キャッシュ読み込み」として処理され、通常の入力料金より大幅に安くなる。

価格の比率を見ると、キャッシュ読み込みの割引幅がわかる。

モデル通常入力キャッシュ書き込み(5分)キャッシュ書き込み(1時間)キャッシュ読み込み
Opus 4.7$5.00 / 1M$6.25 / 1M$10.00 / 1M$0.50 / 1M
Sonnet 4.6$3.00 / 1M$3.75 / 1M$6.00 / 1M$0.30 / 1M
Haiku 4.5$1.00 / 1M$1.25 / 1M$2.00 / 1M$0.10 / 1M

キャッシュ読み込みは通常入力の10分の1、つまり90%引きで再利用できる。書き込み時は通常より高くなる(5分キャッシュなら1.25倍、1時間なら2倍)が、セッション内で繰り返し参照するプロンプトであれば書き込みコストは十分に回収できる。

TTLはデフォルト5分。"ttl": "1h" を指定すると1時間に延長できる。ただし1リクエストあたりのブレークポイントは最大4個という制限がある。

もう一点、見落としがちな制約がある。最小キャッシュサイズだ。

モデルキャッシュ有効の最小トークン数
Opus 4.7 / Opus 4.6 / Opus 4.5 / Haiku 4.54,096トークン
Sonnet 4.6 / Sonnet 4.5 / Opus 4.11,024トークン
Haiku 3.52,048トークン

cache_control を付けてもこのサイズ未満ならキャッシュされない。エラーは出ないので「効いていると思っていたが実は効いていなかった」という状態になりやすい。usage.cache_creation_input_tokens が返ってきているかどうか、レスポンスで確認しておくといい。

Claude Codeは最初から自動で使っている

Anthropicの公式ブログにはっきりと書かれている。

> Claude Code's entire infrastructure is built around prompt caching from inception. The team structures prompts deliberately to maximize cache hits by organizing content from most static to most dynamic: system prompt and tools first, then project context, session data, and finally conversation messages.

(要約: Claude Codeのインフラはprompt cachingを前提に設計されている。プロンプトは「静的なものを先頭に、動的なものを後ろに」という順で意図的に構成され、キャッシュヒット率を最大化している)

具体的にはキャッシュ階層が tools → system → messages の順に設計されていて、変化しにくいコンテンツほど前に来る。ユーザーが特別な設定をしなくても、Claude Codeを立ち上げてセッションを進めるだけでキャッシュが積み上がっていく。

このブログで使っている blog-agents も Claude Code 上で動いており、prompt cachingの恩恵を自然に受けている。CLAUDE.md の設計について書いた記事でも触れているが、CLAUDE.md が小さくシンプルであるほどキャッシュに乗りやすいという構造的な関係がある。また1M Contextとコストの記事で取り上げたように、コンテキストウィンドウが大きくなるほどキャッシュ効果も大きくなる。

キャッシュが壊れるルール

prompt cachingの階層を理解すると、何が壊れやすいかも見えてくる。

操作toolssystemmessages影響範囲
Tool定義の変更無効無効無効全キャッシュ消滅
Web searchのトグル維持無効無効system以降が消える
Citationsのトグル維持無効無効system以降が消える
Tool choiceの変更維持維持無効messagesのみ消える
画像の追加・削除維持維持無効messagesのみ消える
Thinking parametersの変更維持維持無効messagesのみ消える

最も影響が大きいのはtool定義の変更で、これをやると全キャッシュが消える。階層の上位ほど「一度変えると下流が全滅する」という構造になっている。

効率を最大化するための設計判断

Anthropicの公式ブログは、Claude Code内部でどう設計しているかをまとめている。これはClaude Codeを使う側にとっても「壊さないための指針」として読める。

セッション中にツールを追加・削除しない

tools はキャッシュプレフィックスの一部だ。セッション途中で --add-dir によるMCPサーバー追加やSkillの動的切り替えをすると、tools層が変わってキャッシュが全滅する。Claude Code内部では defer_loading: true という軽量スタブで対処しているが、ユーザー側で意図せずこれを破る操作をすることがある。

システムプロンプトを書き換えない

状態の変化(プランモードへの移行など)をシステムプロンプトの書き換えで表現すると、キャッシュが壊れる。Claude Codeの内部設計では、こういった状態変化を「ツール呼び出し」として表現することでシステムプロンプトを固定し、キャッシュプレフィックスを維持している。

モデルをセッション中に切り替えない

キャッシュはモデルごとに分かれている。/model コマンドでSonnetからOpusに切り替えると、それまで積み上げたキャッシュは捨てることになる。特定のタスクだけ別モデルで実行したい場合は、新しいセッションを立ち上げるかサブエージェントで処理する方が合理的だ。

Compactionの際にキャッシュを引き継ぐ

コンテキストが長くなって圧縮(Compaction)が走るとき、Claude Codeは親会話と同じsystem prompt + tool定義でforkすることでキャッシュヒットを維持する。この設計があるから、長いセッションでも効率が落ちにくい。

新しい情報はメッセージとして渡す

情報を更新したいときにシステムプロンプトを書き換えるのではなく、 のようなタグを使ってメッセージとして渡す。これはキャッシュ階層の下位(messages)への変更なので、上位のキャッシュには影響しない。CLAUDE.md を頻繁に書き換えるのではなく、インライン指示でその場の調整をするという運用方針にも通じる。

やりがちな失敗パターン

仕様を理解していても、実装や運用の細部で踏みやすい落とし穴がある。

タイムスタンプやユーザーIDのような毎回変わる値をブレークポイントより前に置くと、毎回キャッシュミスになる。動的な部分はブレークポイントの後ろに配置するのが基本だ。

モデルごとに最小サイズの制限がある点も見落としやすい。短いシステムプロンプトに cache_control を付けても無意味で、エラーも出ないため「効いているつもりで効いていない」状態になる。

ツールの説明文にユーザー名やセッションIDを埋め込むと、セッションごとにtool定義が変わる。tools層が変化すると全キャッシュが消えるので、ツール定義は静的に保つ。

もう一点、SwiftやGoではJSONのキー順序がランダム化されることがある。同じ内容でもキー順が違えばハッシュが一致せずキャッシュミスになる。シリアライズ時に正規化が必要だ。

まとめ

Claude Codeのコスト最適化において、prompt cachingは「設定する機能」ではなく「最初から動いているもの」だ。それを壊す操作をしないことと、壊れているかどうかを確認できる状態にしておくこと。この2点だけ意識すれば、余計なコスト増は防げる。

セッション中のモデル切り替えやMCPサーバーの追加がキャッシュに与える影響は、この記事を読むまで気にしていなかった人も多いと思う。コスト最適化の一般的な考え方については以前書いたコスト最適化の記事も合わせて読んでほしい。

usage.cache_creation_input_tokenscache_read_input_tokens は毎回返ってくる。まずそこを眺めてみることが、今日できる一番小さな確認だ。

参考リンク

コメント

タイトルとURLをコピーしました