これは、なにをしたくて書いたもの?
Claude Code 2.1.3でカスタムスラッシュコマンドがスキルに統合されたようなので、この視点で少し
見ておこうかなと思いまして。
スキルに統合された(カスタム)スラッシュコマンド
Claude Code 2.1.3でスラッシュコマンドがスキルに統合されました。
Merged slash commands and skills, simplifying the mental model with no change in behavior
https://github.com/anthropics/claude-code/blob/v2.1.3/CHANGELOG.md
ドキュメントでは、スラッシュコマンドのページのURLは健在ですが、中身はスキルが表示されるように
なっています。
Extend Claude with skills - Claude Code Docs
こちらのページにも、カスタムスラッシュコマンドがスキルに統合されたことが書かれています。
Custom slash commands have been merged into skills. A file at .claude/commands/review.md and a skill at .claude/skills/review/SKILL.md both create /review and work the same way. Your existing .claude/commands/ files keep working.
たとえば/reviewというカスタムスラッシュコマンドの場合は.claude/commands/review.mdでも.claude/skills/review/SKILL.mdでも
機能し、既存のカスタムスラッシュコマンドとして置かれたファイルの動作は変わらないことが書かれています。
一方で、スキルではサポートファイルやFrontmatterによる制御などのオプション機能が追加されます。
Skills add optional features: a directory for supporting files, frontmatter to control whether you or Claude invokes them, and the ability for Claude to load them automatically when relevant.
またカスタムスラッシュコマンドとスキルの違いとして、ユーザーが明示的に(/[command-name])呼び出すのか、
Claudeが自ら呼び出すのかという違いがあったかと思います。
これはFrontmatterでコントロールします。
- disable-model-invocation … trueにするとスキルを呼び出せるのはユーザーだけになり、
/[スキル名]で呼び出す- デプロイを行うなど、副作用がありClaudeが自動的に使用して欲しくないスキルに使用する
- デフォルトはfalse
- trueにした時はスキルのプロンプトは呼び出すまでコンテキストにロードされなくなる
- user-invocable … falseにするとスキルを呼び出せるのはClaudeだけになる
- 特定の知識をロードするなど、Claudeにとっては意味があるが、ユーザーには意味のないスキルに使用する
- デフォルトはtrue
Extend Claude with skills / Configure skills / Control who invokes a skill
つまり、デフォルトではスキルはユーザーが明示的に呼び出すことができ、Claudeが自動で呼び出すことも
できるわけですね。
以前に書いたこちらのエントリーは、早速用語としては使われなくなるものになりましたね(笑)。
Claude Codeのカスタムスラッシュコマンドってなんだ? - CLOVER🍀
ところで、前にスキルについて書いた時にカスタムスラッシュコマンドとスキルの使い分けをまとめました。
Claude Codeのエージェントスキルってなんだ? - CLOVER🍀
こちらのブログエントリーを参考にして、以下のまとめをしています。
- スキルかプロンプトか?
- 繰り返し必要となる手順や専門知識が必要な場合はスキル
- プロンプトは1度限りの指示(カスタムスラッシュコマンドは繰り返し使える)
- ユーザーのプロンプトによりエージェントがスキルを利用するので、排他的な関係ではない
Skills explained: How Skills compares to prompts, Projects, MCP, and subagents | Claude
結局、プロンプト(指示)としてもスキルが使えるのでしょうね。
Claude Codeのスキルのドキュメント自体を見返した方がよい感じがするのですが、今回はそこは見送って
カスタムスラッシュコマンドとの統合に関する話を見ていきます。
つまり、それぞれの置き場所とdisable-model-invocation、user-invocableです。
それでは、Claude Code+Claude Code Router(Gemini)で試していきましょう。
環境
今回の環境はこちら。
$ claude --version 2.1.27 (Claude Code) $ ccr version claude-code-router version: 2.0.0
Claude Code RouterはGeminiを使うように設定しています。
$HOME/.claude-code-router/config.json
{ "Providers": [ { "name": "gemini", "api_base_url": "https://generativelanguage.googleapis.com/v1beta/models/", "api_key": "xxxxx", "models": ["gemini-2.5-flash", "gemini-2.5-flash-lite", "gemini-2.5-pro"], "transformer": { "use": ["gemini"] } } ], "Router": { "default": "gemini,gemini-2.5-flash", "think": "gemini,gemini-2.5-flash", "webSearch": "gemini,gemini-2.5-flash" } }
起動はこちら。
$ ccr code
旧カスタムスラッシュコマンドとスキルの関係を確認してみる
これまでのカスタムスラッシュコマンドとスキルの違いや関係について見ていこうと思います。
randomという、ランダムな値を生成するカスタムスラッシュコマンドまたはスキルをテーマにして試して
いこうと思います。
カスタムスラッシュコマンドのディレクトリーに置いても使えることを確認する
まずは、これまでのカスタムスラッシュコマンド向けのディレクトリーに置いても動作することを確認します。
こんな感じのカスタムスラッシュコマンドを作成。
.claude/commands/random.md
--- description: ランダムな値を生成します allowed-tools: Bash(uuidgen) --- `uuidgen`コマンドを使って、ランダムな値を生成して返してください。
実行。
❯ /random ● Bash(uuidgen) ⎿ 58bea396-5feb-490e-b014-ec64b873d065
できましたね。
そして、disable-model-invocation、user-invocableのデフォルト値の説明から考えると、/[スキル名]の形式で
なくても呼び出せるはずです。
試してみましょう。
❯ ランダムな値をください ● Skill(/random) ⎿ Successfully loaded skill · 1 tool allowed ● Bash(uuidgen) ⎿ 94302446-b6c2-4af4-8682-cc9ef2267b0c ● uuidgen コマンドで生成されたランダムな値は次のとおりです。 94302446-b6c2-4af4-8682-cc9ef2267b0c
呼び出せましたね。つまりカスタムスラッシュコマンドをそのまま移行すると、Claudeが自動的に使うことが あるかもしれないということになりますね。
これが嫌な場合はdisable-model-invocationをtrueにすることになります。
カスタムスラッシュコマンドと同じ名前のスキルを置いてみる
同じ名前のカスタムスラッシュコマンドとスキルがあった場合はどうなるのでしょう?
先ほどのカスタムスラッシュコマンドとは違う中身で用意。
.claude/skills/random/SKILL.md
--- name: random description: $RANDOMを使ってランダムな値を生成します allowed-tools: Bash(echo:*) --- `echo $RANDOM`コマンドを使って、ランダムな値を生成して返してください。
カスタムスラッシュコマンドの方は、descriptionを少し変えておきました。
.claude/commands/random.md
--- description: uuidgenを使ってランダムな値を生成します allowed-tools: Bash(uuidgen) --- `uuidgen`コマンドを使って、ランダムな値を生成して返してください。
確認してみます。
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ❯ /rando ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── /random $RANDOMを使ってランダムな値を生成します (project) /random uuidgenを使ってランダムな値を生成します (project) /rewind Restore the code and/or conversation to a previous point
両方見えますね…。
実行すると、スキルとして配置した方が優先されました。
❯ /random ● Bash(echo $RANDOM) ⎿ 12249 ● 12249
Claudeに呼び出しを判断してもらっても同じですね。
❯ ランダムな値をください ● Skill(random) ⎿ Successfully loaded skill · 1 tool allowed ● Bash(echo $RANDOM) ⎿ 17365 ● ランダムな値: 17365
なお、このことはドキュメントにも書かれていました。
name:skill-name namespace, so they cannot conflict with other levels. If you have files in .claude/commands/, those work the same way, but if a skill and a command share the same name, the skill takes precedence.
Extend Claude with skills - Claude Code Docs
user-invocableを確認する
ここからは、スキルのディレクトリーだけを使うことにしましょう。
.claude/skills/random/SKILL.md
--- description: uuidgenを使ってランダムな値を生成します allowed-tools: Bash(uuidgen) --- `uuidgen`コマンドを使って、ランダムな値を生成して返してください。
uuidgenを使う方を残すことにしました。
user-invocableをfalseにしてみます。これでユーザーから明示的な呼び出しができなくなるはずです。
--- name: random description: uuidgenを使ってランダムな値を生成します allowed-tools: Bash(uuidgen) user-invocable: false --- `uuidgen`コマンドを使って、ランダムな値を生成して返してください。
すると、/randomで一覧に表示されなくなりました。
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ❯ /rando ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── /rewind Restore the code and/or conversation to a previous point
ムリヤリ実行すると、「このスキルはClaudeだけから呼び出せる」と返ってきます。
❯ /random ❯ This skill can only be invoked by Claude, not directly by users. Ask Claude to use the "random" skill for you.
では、Claudeに呼び出してもらいましょう。
❯ ランダムな値をください ● Skill(random) ⎿ Successfully loaded skill · 1 tool allowed ● Bash(uuidgen) ⎿ efb1cb00-0bf8-4131-b6a1-5c7560a6c6b4 ● efb1cb00-0bf8-4131-b6a1-5c7560a6c6b4
こちらはできましたね。
disable-model-invocationを確認する
最後はdisable-model-invocationです。trueに設定してみます。これでClaudeからは呼び出せなくなるはずです。
.claude/skills/random/SKILL.md
--- name: random description: uuidgenを使ってランダムな値を生成します allowed-tools: Bash(uuidgen) disable-model-invocation: true --- `uuidgen`コマンドを使って、ランダムな値を生成して返してください。
Claudeに指示してみます。
❯ ランダムな値をください ● Task(Generate a random value) ⎿ Done (1 tool use · 0 tokens · 5s)
スキルを使わなくなりました。
/randomとしては呼び出せます。
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ❯ /rando ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── /random uuidgenを使ってランダムな値を生成します (project) /rewind Restore the code and/or conversation to a previous point
こんなところでしょうか。
おわりに
Claude Codeのカスタムスラッシュコマンドがスキルに統合されたということで、
カスタムスラッシュコマンドからの移行という目線で気になるところをちょっと見てみました。
不要にClaudeに使われないように、カスタムスラッシュコマンドとして作ったものは
disable-model-invocationをtrueにするかどうかは考えた方がよいかもですね。