
【Claude Code】スキル・コマンドのモデル指定はスラッシュ起動でしか効かない
はじめに
データ事業本部の荒木です。
Claude Codeでカスタムコマンドやスキルのfrontmatterにmodelを書いて実行モデルを切り替える方法を以下の記事で紹介しました。
ところがmodelを書いたのに、モデルが切り替わっていないことがありました。
本記事では、起動方法と記載場所を変えた検証ケースを作り、セッションログで実際にどのモデルで処理されたかを確認しました。
結論は、
modelが効くのは、そのコマンド/スキルが「スラッシュ起動でターンを開始したとき」だけ。自然言語でClaudeに呼ばせた場合や、別スキルに委譲した先では効かず、元のモデルのまま処理される。
です。
検証方法と注意点
各ケースを実行したあと、セッションログをターン単位でモデル別に集計しました。判定はこの実測のみを根拠にします。
注意点が2つあります。
- UIの
Successfully loaded skill · claude-haiku表示は当てにならない。後述のとおり、この表示が出ても実際の処理はopusだったケースがあります。判定はjsonlの実モデルで行う必要があります。 - セッション全体の合算では判定できない。「セッション全体でhaikuが何トークン」では個別ターンのモデルが分かりません。ターンごとに、各assistantメッセージの
model(とusage)を見ます。
検証ケースと結果
| ケース | modelの場所 | 起動方法 | 実行時のモデル |
|---|---|---|---|
| C1 | SKILL.md=haiku | スラッシュ/mtest-skill |
haiku |
| C2 | SKILL.md=haiku(同じスキル) | 自然言語「mtest-skillを実行して」 | opus |
| C3 | コマンド=haiku | スラッシュ/mtest-cmd |
haiku |
| C4 | コマンド=sonnet→委譲先スキル=haiku | スラッシュ/mtest-deleg |
sonnet |
- C1とC2は同じスキル。スラッシュ起動ならhaiku、自然言語ならopusと、起動方法だけで結果が割れました。
- C4は委譲先スキルにhaikuを書いても効かず、呼び出し元コマンドのsonnetで処理されました。
実ログ
jsonlのassistantメッセージから、model・usage・応答テキストだけを抜き出したものです。output_tokensがそのモデルで実際に生成したトークン数で、課金の根拠そのものです。
同じ出力テキストを、起動方法によって別モデルが生成しているのが分かります。
// 【効く】/mtest-skill とスラッシュで起動 → haiku が生成
{"model":"claude-haiku-4-5-20251001","usage":{"output_tokens":225},"content":[{"type":"text","text":"mtest-skill: SKILL.md(model:haiku)の検証応答です。"}]}
// 【効かない】「mtest-skill を実行して」と自然言語で起動 → opus が生成
{"model":"claude-opus-4-8","usage":{"output_tokens":29},"content":[{"type":"text","text":"mtest-skill: SKILL.md(model:haiku)の検証応答です。"}]}
委譲のケースも同じです。委譲先スキルのSKILL.mdにmodel:haikuと書いてあるのに、生成したのは呼び出し元コマンドのsonnetです。
// 委譲先 mtest-target は SKILL.md に model:haiku。だが生成は sonnet
{"model":"claude-sonnet-4-6","usage":{"output_tokens":30},"content":[{"type":"text","text":"mtest-target: 委譲先SKILL.md(model:haiku)の検証応答です。"}]}
このときUIにはSuccessfully loaded skill · claude-haiku-4-5と表示されますが、実際にトークンを生成したのはsonnetです。UI表示と実モデルは食い違います。
なぜこうなるのか
公式ドキュメント(skills.md)には、modelについて次の記載があります。
The override applies for the rest of the current turn ...(現在のターンの残りに適用される)
つまり、
- スラッシュ
/xxxで起動すると、そのコマンド/スキルがターンを開始するので、ターン全体にそのmodelが適用される(C1・C3がhaiku) - 自然言語で呼ぶと、ターンを開始するのはセッションの通常処理(opus)。スキルはターン途中で呼ばれる立場になり、
modelは適用されない(C2がopus) - 委譲先も同様で、ターンを開始したのは呼び出し元コマンド(sonnet)。委譲先がターン途中で呼ばれても、その
modelは効かない(C4がsonnet)
「ターンを開始した主体のmodelがそのターンを支配する」というルールです。
まとめ
modelを効かせたいなら、そのコマンド/スキルをスラッシュで直接起動するmodelはスラッシュで起動する側(=ターンを開始する側)に書く。委譲先に書いても効かない- 自然言語でClaudeに呼ばせる経路では効かない(元のモデルのまま)
- UIのスキルロード表示は実モデルの根拠にならない。判定はjsonlの実モデルで行う
設定が正しいのに効かないときは、modelの綴りより「どう起動しているか(ターンを誰が開始したか)」を疑うと早い、というのが今回の学びでした。
スキルやコマンドにモデルを設定していても、使い方によってモデルが切り替わらないことでコスト増になってしまいますので、モデルが切り替わる条件はしっかりと把握しておきましょう。






