$ play ep20 — だい20かい の授業
#20 「お願い」じゃなくて「必ずやらせる」には?— フック入門

まず結論
フックは、**「決まった場面が来たら、決まった処理を、必ず走らせる」**仕組みです。Claude Codeくんの仕事の流れの決まったところに仕掛けを置いておき、「ここを通ったら、これが動く」ようにしておきます。
貼り紙(CLAUDE.md)との一番の違いは、ここです。貼り紙は、Claude Codeくんが読んで、理解して、守ろうとしてくれるお願いなので、100回やったら99回は守ってくれても、1回は抜けるかもしれません(確率的)。フックは、Claude Codeくんの気分や理解に関係なく機械が勝手に動くので、100回やったら100回、同じように動きます(決定論的)。お願いは確率、フックは機械です。
使いどころは大きく3つ。
- 実行前に止める: Claude Codeくんが道具(ファイルの書き換え、コマンドの実行など)を使おうとした瞬間に、条件を見て止める
- 実行後に整える: 何かを書き換えたあとに、チェックや整える処理を必ず走らせる
- 終わりを認めない: Claude Codeくんが「できました」と言ったあとに確認を走らせて、通らなければ作業を続けさせる
フックを書く場所は、第17回の権限設定と同じ設定ファイルです。
よくある3つの誤解
- 「フックって、どうせプログラムを書く人のためだけの機能でしょ?」 — フックの中身は「この場面が来たら、これを動かす」だけです。公式が「最初の1個」としておすすめしているのも、Claude Codeくんが返事を待って止まっていたら、パソコンの画面に通知を出す、という身近なフック。作るのに自分でプログラムを書く必要はなく、「Claude Codeくんが返事待ちになったら通知を出すフックを作って」と頼めば作ってくれます。フックは、プログラムを書けなくても使える。最初の1個は、通知から。
- 「貼り紙に『絶対に』とか『必ず』って強く書けば、フックと同じことでしょ?」 — 強く書いても、お願いはお願い止まりです。しかも「絶対」「必ず」のような強調の言葉は、増やすほど1つ1つの重みが薄まります。全部の行に「絶対」があると、どれが本当に絶対なのか、Claude Codeくんには分からなくなります。強調語は特に大事な2つか3つだけに使うのが、貼り紙の書き方の基本です。1回でも抜けたら困ることは、貼り紙の中で強調するのではなく、貼り紙から出して、フックか権限設定という「仕組み」の側に移します。
- 「じゃあ、フックで全部縛っておけば、何も心配いらないんでしょ?」 — フックにはできることの範囲があります。「実行後」のフックは作業が終わったあとに動くので、その作業を取り消すことはできません。また、フックで「この操作は許可」と書いても、権限設定の拒否リストで「ダメ」になっている操作は止まったままです。フックは安全の仕組みを足すことはできても、外すことはできない。そして、フックは自分で決めた条件しか見ないので、条件に書いていないことは素通りします。
ステップ1: フックを仕掛けられる場面
身近なもので言うと、フックは自動ドアのセンサーのようなものです。手で開け閉めする普通のドアに「ドアは閉めてください」と貼り紙をしても、閉めない人は閉めません。自動ドアは、センサーが「人が来た」と分かったら勝手に開いて、通り過ぎたら勝手に閉まります。100回中100回、誰も「開けよう」「閉めよう」と思っていないのに。貼り紙は守るかどうかが相手次第の「お願い」、自動ドアのセンサーは相手の気持ちに関係なく動く「機械」です。
センサーを仕掛けられる「場面」はたくさんありますが、本編では代表的な5つを紹介しました。
- 道具を使う前: ファイルを書き換えたり、コマンドを実行したりする直前。ここで「止める」ことができます
- 道具を使った後: 書き換えた直後。ここで「整える」「チェックする」ことができます
- 返事を終えるとき: Claude Codeくんの「できました」という返事が表示されてから、こちらが次の指示を打ち込めるようになるまでの、ほんの一瞬のすき間。ここで「終わりを認めない」ことができます
- 会話を始めるとき: Claude Codeくんを起動して会話が始まった瞬間。「毎回、最初にこれを準備しておく」ことができます
- お知らせを出すとき: 「確認したいことがあります」「返事を待ってます」というお知らせの場面。ここに「パソコンに通知を出す」処理を仕掛けると、返事待ちの通知が作れます
フックは、こうした「場面」と、そこで動かす「処理」をセットにしたものです。「道具を使う前」と「道具を使った後」の場面には、「ファイルを書き換える道具のときだけ」「コマンドを実行する道具のときだけ」のように、どの道具のときに反応するかの絞り込みも書けます。
ステップ2: 実行前に止める、実行後に整える
実行前に止める。たとえば「原本フォルダの中のファイルは、絶対に書き換えないで」という決まり。第17回の拒否リストでも止められますが、フックなら「書き換えようとしているファイルの場所を見て、原本フォルダの中だったら止める」という条件つきの止め方ができます。止めたときは「原本フォルダの中なので止めました」という理由をClaude Codeくんに返せるので、Claude Codeくんは「じゃあコピーを作ってそっちを直そう」と方針を変えて作業を続けてくれます。
実行後に整える。公式の定番は、プログラムのファイルを書き換えたあとに見た目を整えるツールを必ず走らせる例ですが、プログラム以外なら「書類を書き換えたら表記のチェックを必ず走らせる」「表のデータを書き換えたら合計の確認を必ず走らせる」といった使い方ができます。手洗い場の「使ったら水を止めてください」の貼り紙ではなく、手を離したら勝手に水が止まる蛇口のようなもの。Claude Codeくんが確認を忘れても、ファイルを書き換えたら必ずチェックが走ります。ただし、実行後のフックは作業が終わったあとに動くので、その作業自体を取り消すことはできません。作業前に止めたいなら実行前、作業後に必ずチェックしたいなら実行後です。
実行前に止めるフックは、第17回のどのモードにしていても有効です。素通しモードでも、フックで止めたものは止まります。逆に、フックで「許可」と書いても、拒否リストで「ダメ」になっている操作は止まったままです。
ステップ3: 終わりを認めない。そして、判断つきのフック
返事を終えるときに仕掛けるフックは、今回いちばん覚えておいてほしいものです。Claude Codeくんが「できました!」という返事を表示したあと、こちらが指示をする番になる前のすき間に、「本当にできてる?」という確認を必ず走らせます。確認が通らなければ「まだできてないよ、ここが直ってないよ」という理由を返して、作業を続けさせます。
第17回で、自動モードの見張り役は「危なくないかどうか」は見るけれど、「正しいかどうか」は見ない、というお話をしました。その「正しいかどうか」を見る係が、この終わりのフックです。Anthropicの公式の講座でも、自動モードは確認を走らせる終わりのフックとペアで使う、と説明しています。**危なくないかどうかは自動モードの見張り役、正しいかどうかは終わりのフック。**この2つが揃うと、いちいち聞かれないのに、危ないことは止まるし、壊れたまま終わらない状態になります。
例えば、こういうことが起こりがちです。「作業が終わったら、必ず合計が合っているか確認して」と貼り紙に書いていても、たまに確認が抜けるので、「必ず」「絶対」「毎回」と言葉がだんだん強くなっていく。それでも、たまに確認なしで「できました」が返ってくる。こういうときは、合計の確認を貼り紙から出して、「返事を終えるとき」のフックに移します。貼り紙からは「必ず確認してね」の行を消せるので、貼り紙は短くなって、確認は毎回走るようになります。
もう1つ、判断つきのフックもあります。ここまでのフックは機械的な条件で動きますが、「頼まれたことは全部終わってる?」のように判断が要る場面のために、小さなAIにその場で判断させるフックです。中身は今後、別の回で扱います。
フックの場面の一覧表(本編では読まなかった分)
本編で紹介した5つと、その他の代表的な場面です。名前は覚えなくて大丈夫。「返事を終えるときに、表の合計を確認するフックを作って」のように、場面と処理を言葉で頼めば、Claude Codeくんが正しい名前で書いてくれます。場面は公式に30種類以上あり、版によって増えます(2026年9月時点)。
| 場面 | いつ動くか・何ができるか |
|---|---|
| 本編で紹介した5つまずはこれだけ | |
| 道具を使う前PreToolUse | 道具を使う直前。止められる(止める合図を返すと、その道具は使われない) |
| 道具を使った後PostToolUse | 道具がうまく使えた直後。チェックや整える処理を走らせる。取り消しはできない |
| 返事を終えるときStop | Claude Codeくんが返事を終えたとき。止める合図を返すと、作業を続けさせられる。こちらが途中で中断したときは動かない |
| 会話を始めるときSessionStart | 会話が始まったとき・再開したとき。最初に準備しておきたいことを走らせる |
| お知らせを出すときNotification | Claude Codeくんがお知らせを出すとき。許可の確認を約6秒待っているとき、返事を終えて約60秒こちらが何も打っていないとき、など |
| その他の代表例参考 | |
| お願いを送ったときUserPromptSubmit | こちらがお願いを送った直後、Claude Codeくんが読む前 |
| 道具が失敗した後PostToolUseFailure | 道具を使ったけど失敗したとき |
| 部下が終わったときSubagentStop | 部下(サブエージェント)が作業を終えたとき |
| 会話をまとめる前PreCompact | 長くなった会話を要約して圧縮する前 |
| 会話が終わるときSessionEnd | 会話を終えるとき |
設定ファイルへの書き方の実例(本編では読まなかった分)
フックは、第17回の権限設定と同じ設定ファイル(自分用は ~/.claude/settings.json、プロジェクト用は 作業フォルダ/.claude/settings.json)の hooks の欄に書きます。どれも「〜するフックを作って」と頼めば、Claude Codeくんが書いてくれます。
実例1: 返事待ちのときに通知を出す(Mac)
公式が「最初の1個」として紹介している例です。
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"
}
]
}
]
}
}
- 通知が出ないときは、Macの「システム設定 > 通知」で「スクリプトエディタ」の通知を許可します(
osascriptはスクリプトエディタ経由で通知を出すため)
実例2: 原本フォルダの中は書き換えさせない(実行前に止める)
書き換えの道具(Edit・Write)を使う前に、書き換え先が 原本/ の中なら止める例です。止める処理は別のファイル(.claude/hooks/protect-originals.sh)に書きます。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-originals.sh" }
]
}
]
}
}
#!/bin/bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
if [[ "$FILE_PATH" == *"/原本/"* ]]; then
echo "原本フォルダの中なので止めました。コピーを作って、そちらを直してください" >&2
exit 2
fi
exit 0
matcherが対象の絞り込みです。"Edit|Write"は「書き換えの道具のときだけ」の意味。大文字・小文字は区別されます- 処理のファイルには実行の許可が要ります(Claude Codeくんに作ってもらえば、そこまでやってくれます)
実例3: 書き換えたら、表記のチェックを必ず走らせる(実行後に整える)
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/check-notation.sh" }
]
}
]
}
}
- チェックの中身(どの表記をどう直すか)は
check-notation.shに書きます。「書類を書き換えたら、表記のチェックを走らせるフックを作って。チェックの中身はこれ」と頼むのが早いです
実例4: 合計が合うまで終わらせない(終わりを認めない)
{
"hooks": {
"Stop": [
{
"hooks": [
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/check-total.sh" }
]
}
]
}
}
check-total.shが合計を確認し、合っていなければ理由を書いて止める合図(下の「2」)を返します。Claude Codeくんはその理由を次の指示として受け取り、作業を続けます- 「終わりを認めない」が続きすぎないように、連続8回止めると、いったん終わりが認められます(2026年9月時点。設定で変えられます)。処理の中で「すでにフックのせいで続けている最中か」を見て、同じ理由で止め続けないようにするのが公式のおすすめです
参考: 判断つきのフック
「頼まれたことは全部終わってる?」を小さなAI(既定はHaiku)に判断させる例です。
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "prompt",
"prompt": "Check if all tasks are complete. If not, respond with {\"ok\": false, \"reason\": \"what remains to be done\"}."
}
]
}
]
}
}
止める合図の細かい書き方(本編では読まなかった分)
フックの処理は、終わるときに番号(終了コード)を1つ返します。
| 番号 | 意味 |
|---|---|
| 本編で話した2つ0は進む・2は止める | |
| 0exit 0 | 問題なし。そのまま進む。道具を使う前の場面では「許可」の意味ではなく、いつもの権限設定どおりに進む |
| 2exit 2 | 止める。理由はエラー出力(stderr)に書く。道具を使う前・返事を終えるときなどは、その理由がClaude Codeくんに渡る。場面によっては止められないものもある(会話を始めるとき など) |
| 落とし穴止まらないときに疑う | |
| それ以外(1 など)exit 1 | 止まらない。多くの場面では「フックのエラー」と表示されるだけで、作業はそのまま進む。「止めるつもりが1を返していた」が、止まらないときによくある原因 |
- 番号の代わりに、決まった形の文章(JSON)で「止める」「理由」を返す書き方もあります。どちらか一方にそろえます
- 作ったフックで止まらないときは、「止める合図、ちゃんと2で返してる?」とClaude Codeくんに聞いてみてください
フックが動いてるかを確認する方法(本編では読まなかった分)
/hooksと打つ: フックの一覧が開き、場面ごとに設定されているフックの数が出ます。場面を選ぶと、絞り込み・種類・どの設定ファイルに書いてあるか・中身が見られます。この画面は見るだけで、追加や変更は「〜するフックを作って」と頼むか、設定ファイルを直します- 一覧に出てこないとき: 設定ファイルの書き方(JSON)が崩れていないか(最後のカンマ、コメントは書けません)、置き場所が合っているかを確認します。それでも出なければ、Claude Codeを起動し直します
- 一覧には出るのに動かないとき: 絞り込み(
matcher)が道具の名前と大文字・小文字まで一致しているか、仕掛けた場面が合っているか(道具を使う前か、使った後か)を確認します - 「フックのエラー」と表示されるとき: 処理のファイルに実行の許可がない、処理の中で使っている道具(
jqなど)が入っていない、などが原因です。表示された内容をそのままClaude Codeくんに渡せば、直し方を教えてくれます