! プレフィックスで shell コマンドを実行し、diff・ファイル内容・テスト結果を自動注入して Claude に曖昧な説明でなく実際の情報を渡す
ほとんどの人の slash command はこんな感じだ:
現在の変更のコード品質をレビューし、具体的な提案を出して。
これでも動くが、根本的な制約がある:Claude は「現在の変更とは何か」を自分で推測しなければならない。command が能動的にコンテキストを注入できれば、結果はまったく違ったものになる。
この記事では、command を「目を持った」指令に変える方法を扱う——トリガー時にファイルの内容、git の状態、プロジェクト情報を自動で読み取り、それらをプロンプトに埋め込むことで、Claude に推測させない。
!`コマンド` で Shell 出力を注入カスタム slash command はプロンプトの中に shell コマンドを埋め込めるようになっており、構文はバッククォートでコマンドを囲み、その前にエクスクラメーションマークを付ける:!`コマンド`。トリガー時にコマンドが先に実行され、出力がプレースホルダを置き換え、Claude が受け取るのは最終的に組み立てられたプロンプトになる。
以下が現在の git diff です:
!`git diff HEAD`
これらの変更をレビューし、ロジックエラーとセキュリティ問題に重点を置いてください。
複数行のコマンドはフェンスドコードブロック形式で、先頭に
```!と書く:```! node --version git status --short ```
/review をトリガーした時、Claude が実際に受け取る内容はこうなる:
以下が現在の git diff です:
diff --git a/app/models/user.rb b/app/models/user.rb
index 3a2f1c8..9b4e2d1 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -12,6 +12,9 @@ class User < ApplicationRecord
...
これらの変更をレビューし、ロジックエラーとセキュリティ問題に重点を置いてください。
手動でコピー&ペーストする必要はない。command がトリガーされた瞬間、diff はすでに中に入っている。
---
allowed-tools: Bash(cat:*)
---
以下が現在のファイルの完全な内容です:
!`cat $ARGUMENTS`
このファイル内の潜在的なパフォーマンス問題をすべて見つけ出し、具体的な行番号と修正方法を示してください。
使い方:/perf app/models/order.rb
$ARGUMENTS がファイルパスを受け取り、cat が内容を読み込んで注入する。Claude が受け取るのは実際のコードであって、「現在のファイルを見てください」といった曖昧な記述ではない。
allowed-toolsは frontmatter でcatコマンドを事前承認しており、トリガー時に権限確認が出ない。この行がないと、実行のたびに「許可」を手動でクリックする必要がある。以下の例も同じ方法で宣言する必要がある。
現在のブランチと変更状況:
!`git status --short`
!`git log --oneline -10`
以上の情報をもとに、変更内容と動機を含む簡潔な PR 説明を生成してください。
この /pr command は「自分が何を変えたか」を記述する必要がない。command 自身が読みに行く。
プロジェクトの技術スタック:
!`cat .claude/context/stack.md`
現在のデータベース構造(主要テーブル):
!`head -100 db/schema.rb`
以上を踏まえて、$ARGUMENTS のためにプロジェクト規約に沿ったマイグレーションスクリプトを書いてください。
プロジェクトの背景情報を事前に .claude/context/ ディレクトリに書いておき、command がトリガーされた時に必要に応じて読み取る。プロジェクトの状況を毎回繰り返し説明する必要がない。
最新のテスト実行結果:
!`bundle exec rspec --format progress 2>&1 | tail -30`
以上が失敗したテストです。根本原因を分析し、修正案を出してください。テスト自体は変更しないでください。
/fix-tests がトリガーされた時、直接テストを走らせて結果を取得する。Claude が見るのは実際のエラーメッセージだ。
ここまでを組み合わせると、/review はかなり精度の高いものになる:
---
description: 現在の変更をレビューし、diff と関連する背景を自動注入する
allowed-tools: Bash(git diff:*), Bash(cat:*)
---
## 今回の変更
!`git diff HEAD`
## 変更されたファイル一覧
!`git diff HEAD --name-only`
## プロジェクトのコーディング規約サマリー
!`cat .claude/context/coding-standards.md 2>/dev/null || echo "(規約ファイルなし)"`
---
以上の変更をレビューしてください:
1. ロジックの正しさ:未処理の境界条件やロジックエラーがないか
2. セキュリティ問題:SQL インジェクション、権限チェック、機密情報の露出
3. 規約適合性:プロジェクトのコーディング規約に沿っているか
4. 可読性:命名、コメント、構造
各問題について、ファイル名、行番号、具体的な提案を示してください。問題がなければないと言ってください、水増ししないように。
この command はこちらの準備をまったく必要としない——トリガーされた瞬間、diff、ファイル一覧、コーディング規約がすべて自動注入される。
Shell コマンドは失敗することがある(ファイルがない、コマンドが PATH にないなど)。|| でデフォルト値を用意して、command が中断しないようにする:
!`git diff HEAD 2>/dev/null || echo "(git の変更なし、または git リポジトリ内ではない)"`
!`cat .env.example 2>/dev/null || echo "(.env.example ファイルなし)"`
!`which rspec > /dev/null 2>&1 && bundle exec rspec --dry-run 2>&1 | head -20 || echo "(RSpec が検出されません)"`
コマンドが失敗した時、Claude は空白ではなく説明文を受け取り、それに応じて回答戦略を調整できる。
! コマンドの出力はすべて context window に入る。よくある落とし穴をいくつか:
大きなファイル全体を cat しない
# 危険:数万行注入される可能性がある
!`cat db/schema.rb`
# より良い:必要な部分だけ取る
!`grep -A 5 "create_table \"orders\"" db/schema.rb`
ログファイルには行数制限を
!`tail -50 log/development.log`
テスト出力の切り詰め
!`bundle exec rspec 2>&1 | tail -40`
context が精密であるほど、Claude の回答は良くなる。コードベース全体を詰め込んでも賢くなるわけではなく、ノイズの中で迷うだけだ。
よくある質問:プロジェクトの背景情報は CLAUDE.md に置くべきか、それとも ! で動的注入すべきか?
判断基準:
| 情報の種類 | どこに置くか |
|---|---|
| 毎回必要なプロジェクト背景(技術スタック、ディレクトリ構造、規約) | CLAUDE.md |
| 時間とともに変化する状態(現在の diff、テスト結果、ファイル内容) | ! で動的注入 |
| 特定タスクでのみ必要な背景(あるモジュールの設計説明) | !cat で必要に応じて読む |
CLAUDE.md は永続的な背景知識、! はタスク時の即時スナップショット。両者は補完関係にあり、重複させないこと。
.claude/commands/ ディレクトリ.claude/
├── commands/
│ ├── review.md # レビュー:diff + 規約を注入
│ ├── test.md # テスト作成:対象ファイルを注入
│ ├── fix-tests.md # テスト修正:失敗結果を注入
│ ├── pr.md # PR 説明:git log + status を注入
│ ├── explain.md # コード解説:ファイル内容を注入
│ └── migrate.md # マイグレーション作成:schema の断片を注入
├── context/
│ ├── stack.md # 技術スタックの説明
│ └── coding-standards.md # コーディング規約
└── settings.json
context/ ディレクトリには静的な背景ファイルを置き、各 command が必要に応じて読み込む。この構造はそのまま git にコミットして、チームで共有できる。
静的な command:
現在のコード変更をレビューしてください。
Claude は「変更はどこですか」と聞き返すか、自分で探しに行くことになり、結果は安定しない。
コンテキスト対応の command:
これが diff(実際の内容付き)、これが関連規約(実際の内容付き)です、レビューしてください。
Claude はそのまま分析を始める。回答は精密で、無駄話がなく、やり取りも要らない。
差が出るのは Claude の能力ではなく、こちらがどれだけ実際の情報を渡したかだ。