夜の作業を切り上げる前に /model を開いて、上から三つ目を選ぼうとして、また一つ下を押していました。
私が実際に触るのは二つか三つの行だけです。それでもピッカーには、自分では選ばない行が先に並んでいます。指が覚えている位置と、画面に出てくる位置が、少しずつずれていく。
Claude Code v2.1.242 で入った modelPicker は、この並び自体を自分で書けるようにする設定でした。単に見やすくなるだけの話かと思っていたのですが、実際に書いてみると、置き換えたときに何が消えるのか、どのファイルに書けば読まれるのかで、ずいぶん挙動が変わります。手を動かして分かったことを残しておきます。
既定の一覧は全員向けなので、個人の運用では長い
まず、既定のピッカーが何を並べているかを確認しておきます。Claude Code のモデルエイリアスは次のとおりです。
| エイリアス | 指すもの |
|---|---|
default | モデル指定を解除してアカウントの既定へ戻す特別な値。エイリアスそのものではありません |
best | 組織が Fable 5 を使える場合は Fable 5、そうでなければ最新の Opus |
fable | Claude Fable 5 |
opus | 最新の Opus |
sonnet | 最新の Sonnet |
haiku | 軽い作業向けの Haiku |
opus[1m] / sonnet[1m] | 100万トークンのコンテキストウィンドウ版 |
opusplan | プランモード中は opus、実行に移ると sonnet |
そして、エイリアスが実際に何へ解決されるかは、つないでいる先で変わります。
| 接続先 | opus | sonnet |
|---|---|---|
| Anthropic API | Opus 5 | Sonnet 5 |
| Claude Platform on AWS | Opus 5 | Sonnet 4.6 |
| Amazon Bedrock / Google Cloud Agent Platform | Opus 5 | Sonnet 4.5 |
| Microsoft Foundry | Opus 4.6 | Sonnet 4.5 |
網羅されているのは良いことです。ただ、個人開発でいくつかのプロジェクトを並行して回していると、日中の対話作業と夜間に投げる長い処理で使う行は、だいたい固定されます。私の場合、迷いが生じるのは「今どの行を選んだか」ではなく「今どの行が何番目にあるか」でした。
modelPicker の最小の書き方
modelPicker は options の配列と、任意の replaceBuiltInOptions を持つオブジェクトです。各行には model が必須で、label と description は任意です。
{
"modelPicker": {
"options": [
{ "model": "opus", "label": "重い設計・調査" },
{
"model": "sonnet",
"label": "日中の実装",
"description": "普段はこれで足ります"
},
{ "model": "haiku", "label": "整形・下調べ" }
]
}
}model の値はそのまま解釈されるため、--model に渡せるものは何でも書けます。opus のようなエイリアスでも、Anthropic のモデル ID でも、Bedrock や Google Cloud の Agent Platform、Microsoft Foundry、LLM ゲートウェイの表記でも通ります。
label を書かなければ、Claude Code が知っているモデルなら組み込みの名前が、そうでなければモデル ID が行の見出しになります。description を省くと二行目は汎用の説明になります。
ここで一つ、はっきりさせておきたい点があります。label は表示を変えるだけで、実際に走るモデルは変わりません。 「本番用」と書いた行が本番向けのモデルになるわけではなく、model に書いた ID がそのまま使われます。当たり前のようでいて、ラベルを整えているうちに順番と中身の対応が頭の中でずれることがあるので、書いた直後に一度 /model を開いて目で確かめる価値はあります。
足すのか、丸ごと置き換えるのか
replaceBuiltInOptions の既定値は false です。この状態では、書いた行が組み込みの一覧の後ろに足されます。組み込みが既にカバーしているモデルを書いた場合、その行は重複として飛ばされます。
true にすると、表示されるのは書いた行と、Default と、そのセッションが今使っているモデルの行だけになります。消えるものを並べると次のようになります。
| 行の出どころ | replaceBuiltInOptions: false | replaceBuiltInOptions: true |
|---|---|---|
| 組み込みの一覧 | 残る(先に並ぶ) | 消える |
availableModels が追加した行 | 残る | 消える |
| ゲートウェイのモデル探索で見つかった行 | 残る | 消える |
ANTHROPIC_CUSTOM_MODEL_OPTION の行 | 残る | 消える |
Default と現在のモデル | 残る | 残る |
私自身、一人で使う手元の設定では true にしています。三行だけが並ぶ画面は、思っていたより効きました。一方で、社内ゲートウェイや Bedrock を併用している環境では false から始めることをおすすめします。true はゲートウェイ探索が見つけた行まで隠すので、「昨日まで選べたはずの行がない」という状態を、設定を書いた本人以外が踏むことになります。
ANTHROPIC_CUSTOM_MODEL_OPTION を使っている場合も同様です。あちらで足した一行は組み込みの後ろに置かれ、modelPicker で追加した行はさらにその後ろに続きます。true にすると、その両方がまとめて消えます。
プロジェクト設定に書いても読まれません
ここが、他の設定と感覚が違うところでした。
modelPicker を読むのは、管理設定と --settings とユーザー設定の三か所だけです。プロジェクト設定とローカル設定に書いても無視されます。clone してきたリポジトリが、こちらのピッカーを勝手に書き換えられないようにするための設計です。
さらに、この三か所のうち最も優先度の高い一つが、一覧を丸ごと供給します。二つのソースの行が結合されることはありません。ユーザー設定に三行、管理設定に二行を書いた場合、出てくるのは管理設定の二行だけです。
.claude/settings.json をリポジトリに置いてチームで共有する運用に慣れていると、ここで一度つまずきます。私も最初、プロジェクト側に書いて /model を開き、何も変わらない画面を見て設定ファイルの書式を疑いました。書式は合っていて、読まれる場所が違っただけでした。
ANTHROPIC_DEFAULT_MODEL まわりにも似た「書いた場所と効く場所のずれ」があります。あわせてANTHROPIC_MODEL を消さないまま ANTHROPIC_DEFAULT_MODEL を足しても、始まるモデルは変わりませんも参考になるかもしれません。
availableModels と重ねると、選択肢が意図せず狭まります
modelPicker を書いても、availableModels の許可リストは引き続き効きます。ピッカーに並べた行も、許可リストの外にあれば表示されません。
問題は、許可リストへ行を足すときの挙動です。特定のモデルを名指しするエントリは、そのファミリのワイルドカードを無効にします。 公式の例で言えば ["sonnet", "claude-sonnet-4-5"] は「すべての Sonnet」ではなく「Sonnet 4.5 系のみ」になります。
これは modelPicker と組み合わせたときに踏みやすい形をしています。ピッカーに本番用として固定のモデル ID を並べ、それを許可リストにも足す、という自然な流れをたどると、そのファミリ全体を許可していたつもりのワイルドカードが静かに狭まります。
順番を逆にすると避けられます。
availableModelsで「何を選べる状態にしておきたいか」を先に決める- ワイルドカードと特定 ID を混ぜていないか確認する
- そのうえで
modelPickerの並びを書く /modelを開き、想定した行が想定した数だけ出ているか数える
4 は省きたくなる工程ですが、ピッカーは「出ていないこと」を教えてくれません。数えるのが一番早い確認でした。
行が出てこないときの読み方
書いた行が画面に現れない場合、Claude Code はセッションごとに各行を照合したうえで、三通りの扱いをしています。
| 状態 | 意味 |
|---|---|
| 落とされる | 提供できない行。引退したモデルや、組織にアクセス権がないモデル |
| 灰色になる | まだ選べない行。理由が添えて表示され、並びの一番下へ移動します |
| 一行も残らない | 組み込みの一覧に戻ります(許可リストによるフィルタは従来どおり効きます) |
パースできない行があった場合は、その行だけを落として残りを保ちます。設定ファイル全体が無効になるわけではないので、「一行だけ出ない」ときは、まずその行の書式を疑うのが近道です。
灰色の行は、消えるのではなく末尾へ回されます。並べた順番どおりに出ていないと感じたときは、下まで目を通してみてください。理由がそこに書かれています。
最初の一歩
modelPicker に一行だけ書いて /model を開いてみるのが、いちばん早い確かめ方だと思います。replaceBuiltInOptions は触らず、{ "model": "sonnet", "label": "日中の実装" } のような行を一つ足すだけで、組み込みの一覧の末尾に自分のラベルが現れます。そこから、置き換えるかどうかを決めれば十分です。
並びを決めたあとに次に効いてくるのは、そのモデルへ何を送り直しているかという側です。離席をはさんだときにキャッシュがどう扱われるかは、キャッシュのTTLを1時間に延ばすかは、離席の長さではなく戻る場所で決めていますに、判断の基準として書きました。
小さな設定ですが、毎日開く画面が自分の手に合うようになるのは、思っていたより気持ちのよいものでした。お読みいただきありがとうございました。