この記事の要点
- Claude Codeでセッション中に
/modelでモデルを切り替えると、キャッシュが引き継がれず直後のターンだけ入力トークンが全量再計算されます。 - キャッシュはモデルごとに分かれているため、切り替え直後のターンはキャッシュ読み取りの割引(通常価格の約1割)が使えず、通常より高額になります(出典: https://docs.claude.com/en/docs/build-with-claude/prompt-caching)。
- 影響の大きさはセッションの文脈量とキャッシュ利用率に依存するため、長時間・大規模コンテキストのセッションほど切り替え直後の跳ね上がりが大きくなります。
Claude Codeを使っていて「途中でモデルを切り替えたら急に重くなった」と感じたことはないでしょうか。SNSやQiitaでも、モデル切り替え直後のターンだけコストや処理量が跳ね上がるという報告が出ています(参考: https://qiita.com/suwa_nobu/items/5fe930eb46d064b3da06)。この記事では、なぜそのターンだけ「書き直し」が起きるのかをキャッシュの仕組みから整理します。
Claude Codeのモデル切り替えとは
Claude Codeでは /model コマンドで、セッション中でも使用モデルを変更できます。設計フェーズはOpusで深く考え、実装フェーズはSonnetで手早く進める、といった使い分けをする人は多いはずです。サブエージェントに軽量なHaikuを割り当ててコストを抑える構成もよく見られます。
問題は、この切り替えを会話の途中、つまり長く積み上がったコンテキストの中で行ったときに起きます。
モデル切り替え直後だけコストが跳ね上がる仕組み
Claude Codeは長い会話やコード探索を効率化するため、プロンプトキャッシュを使っています。一度送った長いコンテキストをキャッシュしておき、次のターンでは差分だけを新規トークンとして送る仕組みです。
このキャッシュにはいくつか押さえておくべき特性があります。
| 項目 | 内容 |
|---|---|
| キャッシュ書き込み | 通常価格の約1.25倍(5分TTL)〜2倍(1時間TTL) |
| キャッシュ読み取り | 通常価格の約0.1倍 |
| キャッシュの有効期限 | 5分、または1時間(延長オプション) |
| キャッシュの適用範囲 | 同一モデル・同一システムプロンプト・同一ツール定義に限定 |
出典: https://docs.claude.com/en/docs/build-with-claude/prompt-caching
ポイントは最後の行です。キャッシュはモデルをまたいで共有されません。SonnetからOpusに切り替えた瞬間、それまで積み上げたキャッシュは無効になります。次のターンでは、蓄積されたコンテキスト全体を通常価格(フル単価)で再送信することになります。
普段はキャッシュ読み取りで約1割の単価に抑えられていたコンテキストが、切り替え直後だけフル単価で処理される。この差が「そのターンだけ重い」と感じる正体です。
参考記事が報告した「287倍」の中身
普段のターンがキャッシュ読み取り中心で軽く処理されている場合、そこからキャッシュなしの全量再処理に戻ると、単価差だけでも数倍から十数倍の開きが出ます。さらにコンテキスト量自体が大きい長時間セッションでは、桁が変わるほどの差になっても不思議ではありません。ただし倍率はセッションごとの文脈量やキャッシュ命中率に左右されるため、常に287倍になるわけではない点は補足しておきます。
実際に調べてみた所感
今回、Anthropicのプロンプトキャッシュに関する公式ドキュメントを読み直してみると、キャッシュの適用条件に「モデル」が明記されていることを再確認できました。システムプロンプトやツール定義が同一でも、モデルIDが変われば別のキャッシュ扱いになる、という記述です。
実際に手元のセッションで /cost コマンドを使うと、そのセッション内でのトークン使用量の内訳を確認できます。モデルを切り替える運用をしている人は、切り替え直後のターンだけ入力トークンが目立って増えていないか、一度見てみる価値はありそうです。
書き直しコストを避けるための対策
モデル切り替えのタイミングを工夫するだけで、影響はかなり抑えられます。
-
フェーズの節目で切り替える: 調査や設計が一段落し、コンテキストが軽いタイミングで
/modelを実行する - 長時間セッションの途中では避ける: コンテキストが大きく積み上がった状態での切り替えは、最も割高になりやすい
-
/costで定期的に確認する: 切り替え前後のトークン量を見比べる習慣をつける - サブエージェントで役割分担する: 同一セッション内で頻繁に往復するより、Task機能で最初からモデルを固定した別セッションに分ける
- 新しいセッションとして開始する: どうしても大きく方針転換したい場合は、キャッシュを引き継ぐこと自体を諦めて新規セッションにする方が結果的に安く済むこともある
デメリット・向いていないケース
モデル切り替えの影響を過度に警戒する必要はありません。以下のようなケースでは、対策を意識しすぎるとかえって非効率です。
- コンテキストが短いセッション: そもそもキャッシュされる量が少ないため、切り替えによる差はわずかです
- 切り替え頻度が低い運用: セッションの最初に一度だけモデルを決めて最後まで使う場合、この問題はほぼ関係ありません
- 品質優先で多少のコスト増を許容できる場面: 難しいバグ調査などでOpusに切り替える価値がコスト増を上回るなら、気にせず切り替えた方がよいはずです
コストを抑えることだけを目的にモデル切り替えのタイミングを細かく管理し始めると、開発の流れを止めてしまい本末転倒になりかねません。
よくある質問
Q. Claude Codeでモデルを切り替えるとキャッシュは本当に消えますか?
A. 消えるというより、モデルごとに別枠として管理されるため、切り替え先のモデルでは未使用扱いになります。切り替え前のモデルに戻せば再びキャッシュが効く可能性はあります。
Q. コスト増は次のターンだけですか?
A. 切り替え直後の1ターンでコンテキスト全体が再送信されるため、影響が大きいのはそのターンです。以降は新しいモデルでのキャッシュが再び蓄積されていきます。
Q. SonnetとOpusを頻繁に往復すると料金はどれくらい変わりますか?
A. 具体的な倍率はセッションの文脈量とキャッシュ命中率次第で変動します。往復のたびにフル単価での再処理が発生する点は共通しています。
Q. プロンプトキャッシュの有効期限は何分ですか?
A. デフォルトは5分で、延長オプションを使うと1時間まで保持できます(出典: https://docs.claude.com/en/docs/build-with-claude/prompt-caching)。
Q. サブエージェントごとに別モデルを使うとキャッシュはどうなりますか?
A. Task機能で別モデルのサブエージェントを呼び出す場合、それぞれが独立したコンテキストとキャッシュを持つため、メインセッションのキャッシュ切り替え問題とは別の話になります。
Q. コスト増を確認する方法はありますか?
A. Claude Codeの /cost コマンドで、セッション内のトークン使用量の内訳を確認できます。
Q. モデル切り替えを避けたほうがいいタイミングはありますか?
A. コンテキストが大きく積み上がった長時間セッションの途中は、切り替えによる影響が最も大きくなりやすいタイミングです。
自分の開発セッションでも、モデルを切り替える前に一度 /cost の数字を確認してみると、思わぬコストの偏りに気づけるかもしれません。