Claude Code にコード変更を依頼する際、内容に応じて 「まずは方針だけ提示してほしい」「差分を提示してほしい」「直接変更してほしい」といったようにチェックポイントを切り替えたくなると思います。なので、カスタムスラッシュコマンドでチェックポイントを明示する仕組みを作りました。
参考文献
背景
Claude Code にコード変更をお手伝いいただくにあたり、コード変更を許可するといってもやはり予め変更内容を確認したいと思いました。なので、ユーザスコープのシステムプロンプト ~/.claude/CLAUDE.md に、「直接ファイルを編集せず、まずはファイル差分を提示して確認を仰いでください」のように記述していました。
しかし、いざお手伝いいただき始めてみると、ロジックに踏み込まないのでわざわざファイル差分の確認を促されるとうっとうしい場合もあれば、逆に設計を伴うのでファイル差分以前に方針を相談してほしいと感じられる場合もありました。
個人的には、「ここまでやったら確認を仰いでください」というチェックポイントのレベルに以下の 3 段階がありそうに思いました。
- まずは変更方針だけを提示してください (設計レベルの手戻りリスクがある時)
- まずはファイル差分だけを提示してください (実装レベルの手戻りリスクがある時)
- ファイル差分を提示し、ファイルも変更してください (手戻りリスクがほぼない時)
実施内容
なので、システムプロンプトの記述は削除し、その代わり都度チェックポイントのレベルを手軽に伝えられるようにしました。
この運用では、変更依頼は常に prj_root/.claude/ask.input.md (以下、インプットファイルと呼ぶ) に記述し、これをチャットから /ask 1 のように呼び出します。すると、数字に応じたチェックポイントを示す文が付加されて Claude に届きます。
+ 以下の変更を依頼したいです。
+ まずは変更方針だけを提示してください。
+
## 変更依頼内容
現在、以下のテストエラーが出る状態です。これが解消されるよう、クラス Xxx を変更してください。
- FAILED tests/test_xxx.py::test_xxx - XxxError: ...
- FAILED tests/test_xxx.py::test_xxx - XxxError: ...
仕組み
カスタムスラッシュコマンド ~/.claude/commands/ask.md を用意し、そこから引数で渡したチェックポイントのレベルに応じたメッセージと共に、インプットファイルの内容を提示するシェルスクリプト ~/.claude_tools/ask.sh を呼び出すようにします。
## 変更依頼内容
現在、以下のテストエラーが出る状態です。これが解消されるよう、クラス Xxx を変更してください。
- FAILED tests/test_xxx.py::test_xxx - XxxError: ...
- FAILED tests/test_xxx.py::test_xxx - XxxError: ...
---
allowed-tools: Bash(bash -c 'source ~/.claude_tools/ask.sh':*)
---
!`bash -c 'source ~/.claude_tools/ask.sh' _ $ARGUMENTS`
#!/usr/bin/bash
input_file="$(pwd)/.claude/ask.input.md" # インプットファイル
if [ ! -f "$input_file" ] || [ ! -s "$input_file" ]; then
# インプットファイルがないか空なら以下のメッセージで終わる
printf '\n%s' "今は依頼はないです。"
exit 0
fi
# 引数がただ 1 つで 1, 2, 3 のどれかならチェックポイントを示すメッセージを付加
message=""
newline=$'\n'
if [ "$#" -eq 1 ] && { [ "$1" = "1" ] || [ "$1" = "2" ] || [ "$1" = "3" ]; }; then
message="以下の変更を依頼したいです。"
if [ "$1" = "1" ]; then
message="${message}${newline}まずは変更方針だけを提示してください。"
elif [ "$1" = "2" ]; then
message="${message}${newline}まずはファイル差分だけを提示してください。"
elif [ "$1" = "3" ]; then
message="${message}${newline}ファイル差分を提示し、ファイルも変更してください。"
fi
fi
# メッセージ出力
printf '\n'
if [ -n "$message" ]; then
printf '%s\n\n' "$message"
fi
cat "$input_file"
上記のファイルを整備した上で、Claude とのチャット内で /ask 1 とすると、以下のように Claude に届く文にチェックポイントを示す箇所が追加されます (この文はチャットには表示されないので、確認したい場合は Claude に「どんな文が届きましたか」と訊く必要があります)。引数を省略して /ask とすると単にインプットファイルの内容が Claude に届くので、常にインプットファイルを窓口にしても構いません。
+ 以下の変更を依頼したいです。
+ まずは変更方針だけを提示してください。
+
## 変更依頼内容
現在、以下のテストエラーが出る状態です。これが解消されるよう、クラス Xxx を変更してください。
- FAILED tests/test_xxx.py::test_xxx - XxxError: ...
- FAILED tests/test_xxx.py::test_xxx - XxxError: ...
備考
備考1. シェルスクリプトの呼び出し方について
スラッシュコマンド内でシェルスクリプトを bash -c で新しいプロセスで実行していますが、これは少なくとも私の環境 (Windows マシンで、普段の作業環境はシステム上の Git Bash です) ではこうしなければ上手くいかなかったためです。例えばパスの通った場所に ask.sh を置いて以下のようにしても動きませんでした。エラーにもならないが Claude に何も届かなかったようです。
---
allowed-tools: Bash(ask.sh:*)
---
!`ask.sh $ARGUMENTS`
Claude 自身にこれを調査してもらった結果、Claude が色々と試行し出し、先の呼び出し方でメッセージが表示されたのを見て Claude の調査を打ち切ってこれを採用しました。
あとさらにいえば、スラッシュコマンドはドキュメントによると 1 つ目の引数を $1 で取れるはずですが、これも手元では $ARGUMENTS で取らなければ上手くいきませんでした。
備考2. シェルスクリプトを使わない方法について
シェルスクリプトを使いたくないという場合は、以下のように /ask1 /ask2 /ask3 を別個に用意すれば、メッセージを追加してインプットファイルの内容を届けられます。ただ、シェルスクリプト式ならメンテナンス対象をシェルスクリプト 1 ファイルにはできます。
まずは変更方針だけを提示してください。
@.claude/ask.input.md
まずはファイル差分だけを提示してください。
@.claude/ask.input.md
ファイル差分を提示し、ファイルも変更してください。
@.claude/ask.input.md