CodeCraft Lab

Skillsでカスタムコマンドを作る

SKILL.mdの構造から複数ステップ・引数処理・条件分岐を含む複雑なSkillの設計、チーム配布とバージョン管理の運用パターンまでを実践的に学びます

応用18分で読了
Skillsスラッシュコマンドカスタマイズチーム運用

このレッスンで学ぶこと

  • SKILL.mdのフロントマター項目を体系的に理解し、用途に応じて使い分ける
  • 複数ステップ・引数処理・条件分岐を含む、実務レベルのSkillを設計する
  • サブエージェント実行(context: fork)や動的コンテキスト注入を使い、Skillの表現力を広げる
  • Skillをチームで配布し、バージョン管理・更新フローを運用に乗せる

前提条件

このレッスンの立ち位置

実践レシピでは「よく使うプロンプトをスラッシュコマンド化する」という入口を扱いました。このレッスンでは一段進めて、Skillの仕組みそのもの(フロントマターの全体像、コンテキストのライフサイクル、サブエージェント実行)を体系的に理解し、チームで運用に耐えるSkillを設計・配布するところまでをカバーします。

Skillsの仕組みをもう一段深く理解する

Skillは「SKILL.mdに書いた指示を、必要なときだけコンテキストに読み込む」仕組みです。CLAUDE.mdとの決定的な違いは読み込みタイミングにあります。CLAUDE.mdは毎ターン保持され続けるのに対し、Skillは呼び出された瞬間に1つのメッセージとしてコンテキストに挿入され、以後はセッションが終わるかコンパクションが起きるまでそこに留まります。

この性質は、Skillに何を書くべきかという設計判断に直結します。

コンテンツの種類向いている内容
リファレンス型規約・ドメイン知識など、会話の流れにそのまま乗せたいもの「このAPIはRESTfulな命名規則に従う」
タスク型明示的に実行したい一連の手順「テストを実行し、ビルドし、デプロイする」

タスク型のSkillは多くの場合、ユーザーが意図的にタイミングを選んで実行したいものです。disable-model-invocation: trueを設定すると、Claudeが会話の流れから勝手に呼び出すことを防ぎ、/skill-nameでの明示的な呼び出しのみに限定できます。

本体は簡潔に保つ

Skillが読み込まれると、その内容はターンをまたいでコンテキストに残り続けます。すべての行がトークンコストになるため、「何をするか」を簡潔に書き、「なぜそうするか」の説明はサポートファイルに逃がす設計を意識しましょう。

フロントマターを体系的に押さえる

実践レシピではdescriptionargument-hintdisable-model-invocationに触れました。複雑なSkillを設計するうえで知っておきたい主要フィールドを整理します。

フィールド役割
descriptionClaudeが自動呼び出しを判断する根拠。ユーザーが自然に使う言葉を含める
argument-hintオートコンプリート時に表示される引数のヒント
arguments名前付き引数のリスト。$name形式でスキル本文から参照できる
disable-model-invocationtrueにするとユーザーのみが呼び出せる(副作用のある操作向け)
user-invocablefalseにすると/メニューから隠れる(Claude専用のバックグラウンド知識向け)
allowed-toolsこのSkillがアクティブな間、確認なしで使えるツール
contextforkを指定すると、サブエージェントとして分離実行される
modelこのSkill実行中だけ使うモデルを上書きする

argumentsを使うと、位置引数に名前を付けて可読性を上げられます。

---
name: migrate-component
description: コンポーネントを別のフレームワークに移行する
arguments: [component, from, to]
---
 
$component コンポーネントを $from から $to に移行してください。
既存の挙動とテストをすべて維持すること。

/migrate-component SearchBar React Vueと呼び出すと、$componentSearchBar$fromReact$toVueに展開されます。複数単語を1つの引数として渡したい場合はクォートで囲みます(/my-skill "hello world" second)。

複雑なSkillを設計する: 複数ステップ・条件分岐・引数処理

ここからは、PRレビューを依頼する前のチェックを自動化する/pr-precheckというSkillを例に、複数ステップ・条件分岐・引数処理を組み合わせた実践的な設計を見ていきます。

要件を分解する

このSkillに求める動作を箇条書きにします。

  • 引数でPR番号を受け取る(省略時は現在のブランチのPRを対象にする)
  • 変更ファイル一覧を取得し、テストファイルが含まれているか確認する
  • 含まれていなければ「テスト追加を検討してください」という警告を出す
  • lintとtypecheckを実行し、結果をまとめて報告する

要件を先に言語化しておくと、後述するステップ構成・条件分岐の設計がぶれません。

動的コンテキスト注入でデータを集める

Skill本文内で !`command` 構文を使うと、Claudeがスキル内容を見る前にシェルコマンドが実行され、その出力がプレースホルダーに差し込まれます。コマンド自体ではなく実データがClaudeに渡るため、「PRの内容を調べて」と指示するより確実です。

---
description: PRレビュー依頼前のセルフチェックを実行する。レビュー依頼前やPR作成前に使用する。
argument-hint: "[PR番号(省略可)]"
allowed-tools: Bash(gh *), Bash(npm run lint), Bash(npm run typecheck)
---
 
## 対象PRの情報
- 変更ファイル一覧: !`gh pr diff $ARGUMENTS --name-only`
- PRステータス: !`gh pr view $ARGUMENTS --json state,mergeable`
 
## 指示
(次のステップで追記)

$ARGUMENTSが空でもgh pr diff --name-onlyはカレントブランチのPRを対象にするため、「省略時は現在のブランチ」という要件が自然に満たされます。

条件分岐を指示として書き下す

Skillに「条件分岐」を実装するといっても、プログラムのif文を書くわけではありません。Claudeへの指示として、判断基準と分岐後の行動を明記します。

## 指示
 
上記の変更ファイル一覧を確認し、以下のルールでチェックしてください。
 
1. **テストファイルの有無**
   - `src/`配下の実装ファイルに変更があるのに、対応する`.test.`ファイルの変更が一覧にない場合、
     「テストの追加・更新を検討してください」と警告する
   - すでにテストファイルが含まれている場合は、この項目はスキップする
 
2. **lint・typecheckの実行**
   - `npm run lint``npm run typecheck`を実行する
   - エラーがあれば、ファイル・行番号付きで報告する
   - 両方パスした場合は「lint/typecheck: OK」とだけ報告する
 
3. **マージ可否の確認**
   - PRステータスの`mergeable``false`の場合、コンフリクトの解消が必要である旨を最優先で報告する
 
最終的な報告は「ブロッカー(必ず対処)」「推奨(できれば対処)」「OK項目」の3区分でまとめてください。

曖昧な「チェックして」ではなく、判断基準(テストファイルの有無の確認方法)と出力フォーマット(3区分でのまとめ)まで明記することで、毎回安定した結果が得られます。

サブエージェント実行で隔離する(任意)

lintやtypecheckの出力が長くなる場合、context: forkを追加してサブエージェントとして実行すると、詳細な出力はサブエージェント側に留まり、メイン会話には要約だけが返ります。

---
description: PRレビュー依頼前のセルフチェックを実行する
argument-hint: "[PR番号(省略可)]"
allowed-tools: Bash(gh *), Bash(npm run lint), Bash(npm run typecheck)
context: fork
agent: general-purpose
---

context: forkはタスク型のSkill(明確な手順がある)に向いています。「このプロジェクトの規約はこうだ」のような知識提供型のSkillにforkを付けても、実行すべきタスクがないため意味のある出力が返りません。

サポートファイルでSKILL.mdを軽量に保つ

チェック項目が増えてSKILL.mdが長くなってきたら、詳細なルールをchecklist.mdのような別ファイルに切り出し、SKILL.mdからは「詳細はchecklist.mdを参照」と参照するだけにしましょう。SKILL.mdは500行以内を目安に保つと、読み込みコストと保守性のバランスが取れます。

.claude/skills/pr-precheck/
├── SKILL.md          # 概要と手順の骨子
└── checklist.md       # 詳細なチェックルール

チーム配布の本格的な運用パターン

実践レシピでは「.claude/skills/をコミットすれば共有できる」という最小限の流れを紹介しました。チーム規模が大きくなると、それだけでは運用が回らなくなる場面が出てきます。ここでは3つの典型的な配布パターンを整理します。

配布パターン配置場所向いている状況
プロジェクト直接コミット.claude/skills/単一リポジトリのチームで、Skill数が少ない
プラグイン化<plugin>/skills/複数リポジトリで同じSkill群を再利用したい
管理設定(Enterprise)管理設定ディレクトリ組織全体に強制的に配布・統制したい

プラグイン化による横断配布

複数のプロジェクトで同じSkillセットを使い回したい場合、.claude/skills/への直接コミットだと、Skillを更新するたびに全リポジトリへの個別反映が必要になります。Skillフォルダに.claude-plugin/plugin.jsonを追加してプラグイン化すると、<plugin-name>@skills-dirという名前のプラグインとして1か所からインストール・更新できるようになります。

team-skills-plugin/
├── .claude-plugin/
│   └── plugin.json
└── skills/
    ├── pr-precheck/
    │   └── SKILL.md
    └── test-gen/
        └── SKILL.md

プラグイン経由のSkillはmy-plugin:pr-precheckのように名前空間化されるため、他のプロジェクト固有Skillと名前が衝突する心配もありません。

組織全体への強制配布(Enterprise)

セキュリティレビューや禁止事項チェックのように「全プロジェクトで必ず使われてほしい」Skillは、管理設定の.claude/skills/に配置します。これはユーザー・プロジェクトレベルの同名Skillより優先されるため、現場で勝手に上書きされる心配がありません。導入計画や権限設計の詳細は組織導入コースで扱いますが、「個人・プロジェクト・Enterprise」という3階層の優先順位(Enterpriseが最優先)は覚えておくとよいでしょう。

バージョン管理・更新フロー

SkillはプレーンテキストのSKILL.mdなので、コードと同じGitフローに乗せられます。チーム運用で機能させるための実践的なポイントを3つ紹介します。

1. 変更はPRレビューを通す

Skillのallowed-toolsは、そのSkillがアクティブな間ツールを確認なしで実行できる権限を付与します。これはコードと同じくらい実害のある変更になりうるため、CLAUDE.mdに書かれている「PRレビュー必須」のルールをSkillにも適用しましょう。特にallowed-toolsBash系を追加する変更は、レビュー時に必ず内容を確認します。

2. 変更履歴をSKILL.md自体に残す

SKILL.mdの末尾にコメント形式で簡単な変更履歴を残しておくと、「いつ・なぜこの指示を追加したか」が後から追いやすくなります。

<!--
## 変更履歴
- 2026-06-30: テストファイル有無チェックを追加(テスト漏れのPRが続いたため)
- 2026-06-15: 初版作成
-->

3. 動作確認をルーチン化する

Skillの指示文を変更すると、意図せず既存の挙動が壊れることがあります。変更のたびに、想定する入力で実際に呼び出して結果を確認する習慣をつけましょう。複数のテストケースを継続的に管理したい場合は、公式のskill-creatorプラグインのようなツールでテストケースと期待動作をevals.json的な形で保存し、新旧バージョンを比較する運用も可能です。チーム全体で使うSkillほど、この検証コストを惜しまないことが重要です。

ライブ変更検出の落とし穴

.claude/skills/配下のファイルを編集すると、再起動なしで現在のセッションに反映されます。これは開発中は便利ですが、「変更したつもりがまだ古い内容で動いている」という勘違いを防ぐためにも、重要な変更後は一度新しいセッションで動作確認することをおすすめします。

まとめ

このレッスンでは、Skillsの仕組みを一段深く理解し、実務で通用する複雑なSkillの設計と、チームでの配布・運用フローを学びました。

  • Skillはリファレンス型・タスク型で書き方の方針が変わり、タスク型はdisable-model-invocationで呼び出しを制御する
  • 動的コンテキスト注入(!`command`)と条件分岐の指示を組み合わせると、複数ステップの実務的なSkillを設計できる
  • context: forkでサブエージェント実行に分離すると、詳細な出力をメイン会話から切り離せる
  • チーム配布は「プロジェクト直接コミット → プラグイン化 → Enterprise管理配布」と規模に応じて段階を上げていく
  • Skillの変更もコードと同様にPRレビュー・変更履歴・動作確認のサイクルに乗せる

Skillが「よく使うプロンプトの省略形」から「チームの作業標準を体現する資産」に育ってきたら、次は別の委譲先であるサブエージェントの出番です。Lesson 7: サブエージェントの設計と活用では、Skillと組み合わせてさらに高度なワークフローを構築する方法を学びます。