PreModelSwitch hookとPostModelSwitch hookでモデル切り替えを制御する
v2.1.251で追加されたPreModelSwitch/PostModelSwitchフックは、モデル切り替えの直前・直後に反応できるイベントです。確定している仕様と未確定の点、switchModelsOnFlagとの違いを扱います。
Claude Code v2.1.251は、モデルが切り替わる直前と直後にフックを差し込めるPreModelSwitch・PostModelSwitchという2つのイベントを追加しました。CHANGELOGの表現では、モデル切り替えを「ブロックする・確認を挟む・記録する」の3通りで扱えるようになります。これまでhooksの仕組みは、ツール呼び出しやセッションの開始・終了には反応できても、セッション途中でモデルが入れ替わる瞬間そのものには一切反応できませんでした。
Claude Codeでモデルが切り替わる経路は1つではない
モデルの切り替えは/modelコマンドの手動操作だけで起きるわけではありません。少なくとも4つの経路があります。
もっとも分かりやすいのは/modelによる手動切り替えです。ユーザー自身がコマンドを打った結果、そのまま切り替わります。
これに対してfallbackModelチェーンは、primaryモデルが過負荷や利用不可のときに設定済みの候補を順に試す経路です。切り替わりはそのターン限りで、次のメッセージではまたprimaryモデルから試行が始まります。
3つ目の経路はコンテンツ安全性分類器によるフォールバックです。Fable 5とOpus 5はサイバーセキュリティ・生物学関連のコンテンツを検知する分類器を持ち、リクエストがフラグされると別モデルへ自動で再実行します。この経路にだけ、既存のswitchModelsOnFlagという設定があります。オフにすると、フラグされるたびにセッションが一時停止し、「フォールバックモデルへ切り替える」か「プロンプトを編集して同じモデルでリトライする」かを選べます。
最後の経路はサブエージェントのモデル上書きです。サブエージェントのモデルは、セッション本体と別に指定できます。指定方法はCLAUDE_CODE_SUBAGENT_MODEL環境変数、frontmatterのmodel:フィールド、起動時の個別指定の3通りです。この経路はv2.1.251で優先順位が変わりました。以前はCLAUDE_CODE_SUBAGENT_MODELを設定すると、個々のサブエージェント定義の指定を一律に上書きしていました。v2.1.251以降はこの変数が既定値の役割に後退します。エージェント定義のmodel:や起動時の個別指定のほうが優先されるようになりました。組織全体のデフォルトと、個々のサブエージェントの意図的な指定がぶつかったとき、後者が勝つように変わったことになります。
この4つのうち、v2.1.251より前に何らかの制御点を持っていたのは3つ目だけです。しかもその制御点は「切り替えるかどうかをセッション全体でオン・オフする」設定であり、切り替えごとに独自のロジックを走らせたり、記録を残したりする手段ではありませんでした。残り3つの経路には制御点そのものがありませんでした。
v2.1.251でPreModelSwitch/PostModelSwitchフックが追加された
CHANGELOGの該当行は次のとおりです。
Added
PreModelSwitchandPostModelSwitchhook events (block, confirm, or annotate a model switch)
Claude Codeのhooksには、「起きる前」と「起きた後」をペアで持つイベントがいくつかあります。PreToolUseとPostToolUse、PreCompactとPostCompactが例です。PreModelSwitch/PostModelSwitchもこの設計に沿った追加で、v2.1.251以降で利用できます。
設定の書き方はどうなると考えられるか
hooksの設定は、どのイベントであってもsettings.jsonのhooksブロックに、イベント名をキーにしたエントリを追加する形が共通です。各エントリはmatcher(対象を絞る条件、対応イベントのみ)を持てます。実際に走らせるhooks配列にはcommand・http・mcp_tool・prompt・agentのいずれかの型を指定します。この形式に沿うなら、PreModelSwitchは次のように登録する形になります(専用セクションが無いため、他イベントの共通形式からの類推です)。
{
"hooks": {
"PreModelSwitch": [
{
"hooks": [
{
"type": "command",
"command": "./check-model-switch.sh"
}
]
}
]
}
}session_id・cwd・transcript_path・hook_event_nameは全イベント共通のフィールドです。PreModelSwitch/PostModelSwitchでも同じく受け取れると見て間違いありません(全イベント共通のフィールドとして仕様に明記されているため)。一方、切り替え元・切り替え先のモデル名をどのフィールド名で渡すか、どの経路(手動・フォールバックチェーン・分類器・サブエージェント)で発火するかは、CHANGELOGの一文だけでは分かりません。
ブロック・確認・記録 — 3つの使い道
CHANGELOGが挙げる3つの動詞は、Pre/Postの2イベントにどう割り振られるでしょうか。
ブロックはPreModelSwitch側の機能だと考えられます。PreToolUseやUserPromptSubmitなど、Claude Codeの「起きる前」イベントの多くは同じ決定モデルに従っています。exit code 2でアクションそのものを止める標準的な仕組みです。ただしPreModelSwitchが同じexit code 2の規約に従うかどうかは専用セクションが無く未確定で、ここは既存イベントの設計からの類推にとどまります。仕組みとして実現すれば、監査対応セッションで承認済みモデル以外への切り替えを一切許さない、コスト管理の都合でOpusへの自動切り替えを止める、といった使い方ができます。
確認はCHANGELOGにしか出てこない語で、具体的な入出力は分かりません。既存のswitchModelsOnFlagは「切り替えるか、プロンプトを編集してリトライするか」という一時停止の体験を提供します。確認がこれをコンテンツ分類器以外の切り替え経路にも広げる機能を指すのか、専用の入出力フィールドは公開されておらず判断できません。
記録はPostModelSwitch側で使う機能です。切り替えがすでに確定した後に発火するイベントなので、ブロックはできず、ログへの記録やコスト集計のトリガーとして使う形になります。
switchModelsOnFlagとの違いは何か
既存のswitchModelsOnFlag設定と、新しい2つのフックは重なりつつも役割が違います。
| switchModelsOnFlag | PreModelSwitch/PostModelSwitchフック | |
|---|---|---|
| 対象の切り替え経路 | switchModelsOnFlagコンテンツ安全性分類器のフォールバックのみ | PreModelSwitch/PostModelSwitchフック経路を問わず発火する可能性(未確定) |
| 制御の粒度 | switchModelsOnFlagセッション全体でオン・オフの1択 | PreModelSwitch/PostModelSwitchフックフックスクリプトで任意のロジックを実行 |
| 記録の残し方 | switchModelsOnFlag一時停止ダイアログが出るのみ | PreModelSwitch/PostModelSwitchフックannotateでログに残せる(仕様の詳細は未公開) |
switchModelsOnFlagは2択のトグルであるのに対し、新しいフックはスクリプトを書ける分だけ表現力が広がります。ただし対象範囲が経路を問わず発火するかどうかは前節で述べたとおり未確定で、この表もその推測を反映したものです。
PreModelSwitchフックはモデル選択の主導権をどこへ動かすか
fallbackModelチェーン、コンテンツ分類器のフォールバック、組織向けのavailableModelsallowlist、そして今回のフック。これらを並べると、Claude Codeにおけるモデル選択は、ユーザーが/modelで選ぶ単純な操作から、複数のポリシーが重なって決まる仕組みへ変わってきています。PreModelSwitchフックは、この流れの中でもっとも自由度の高い制御点です。他の仕組みは「許可リストに入っているか」「フラグが立ったか」という固定条件で判定します。フックは任意のスクリプトやプロンプト評価を挟めるため、社内ポリシーのような固定条件化しにくい判断もモデル切り替えの前に差し込めます。
一方で、この自由度は運用側の実装コストと表裏一体です。switchModelsOnFlagはチェックボックス1つで完結しましたが、PreModelSwitchで同等のことをするにはスクリプトを書いて保守する必要があります。個人利用では過剰な仕組みになりやすく、組織でモデル利用のガバナンスを敷きたいチーム向けの機能だといえます。
よくある質問
PreModelSwitch/PostModelSwitchフックはいつから使えますか
Claude Code v2.1.251以降です。CHANGELOGで初めて言及されました。
サブエージェントのモデル上書きでもこのフックは発火しますか
公式ドキュメントに経路ごとの発火有無を明記した記述はなく、確認できていません。
既存のswitchModelsOnFlag設定は今後も使えますか
CHANGELOGにも公式ドキュメントにも廃止の記述はなく、独立した設定として引き続き存在します。
PreModelSwitchでブロックした場合、セッションはどうなりますか
公式に明記された挙動はありません。PreToolUseなど他の「起きる前」イベントでは、ブロック時にアクションが取り消され元の状態のまま処理が続きます。PreModelSwitchも同じ設計に沿うなら同様の挙動になりますが、これはあくまで類推であり確定情報ではありません。
CLAUDE_CODE_SUBAGENT_MODELとエージェント定義のmodel:が競合したらどちらが勝ちますか
v2.1.251以降はエージェント定義のmodel:と起動時の個別指定が優先されます。CLAUDE_CODE_SUBAGENT_MODELは、それらが指定されていないときに使われる既定値という位置づけに変わりました。
まとめ
PreModelSwitch/PostModelSwitchフックは、これまでhooksからは見えなかったモデル切り替えの瞬間に初めて反応できるようにする追加です。モデルの切り替えには/modelの手動切り替え・fallbackModelチェーン・コンテンツ分類器のフォールバック・サブエージェントのモデル上書きの4つの経路がありますが、このうちどの経路で実際に発火するかはCHANGELOGの一文からは分かりません。ブロック・確認・記録という3つの動詞のうち、ブロックと記録は既存イベントの設計から挙動を類推できます。確認の具体的な入出力と、イベントが発火する経路の範囲は、CHANGELOGの一文以外に情報がありません。個人開発での常用機能というより、モデル利用のガバナンスを敷きたい組織向けの制御点として捉えるのが実態に近いといえます。
hooksの全体像と他のイベント一覧はClaude Code Hooks完全ガイド、コピペで使えるレシピはClaude Code Hooks実例カタログで確認できます。可用性起因のフォールバックだけを扱いたい場合はClaude Code fallbackModelで過負荷に備えるを参照してください。同じv2.1.24x台では、コマンド実行そのものを封じるClaude Codeの制限モード(--restricted)の使い方も追加されました。どちらもClaude Codeの動作範囲を運用側が締める方向の機能です。