$ — 聴く教室、開講中 —
~/episodes/ep20 — now playing

$ play ep20 — だい20かい の授業

#20 「お願い」じゃなくて「必ずやらせる」には?— フック入門

2026.10.03 | 25:20

#20 エピソードアート
きょうの持ち帰りフックは、決まった場面が来たら決まった処理を必ず走らせる仕組み。貼り紙はお願い止まりで確率的、フックは機械で決定論的。使いどころは、実行前に止める・実行後に整える・終わりを認めない、の3つ。

まず結論

フックは、**「決まった場面が来たら、決まった処理を、必ず走らせる」**仕組みです。Claude Codeくんの仕事の流れの決まったところに仕掛けを置いておき、「ここを通ったら、これが動く」ようにしておきます。

貼り紙(CLAUDE.md)との一番の違いは、ここです。貼り紙は、Claude Codeくんが読んで、理解して、守ろうとしてくれるお願いなので、100回やったら99回は守ってくれても、1回は抜けるかもしれません(確率的)。フックは、Claude Codeくんの気分や理解に関係なく機械が勝手に動くので、100回やったら100回、同じように動きます(決定論的)。お願いは確率、フックは機械です。

使いどころは大きく3つ。

  1. 実行前に止める: Claude Codeくんが道具(ファイルの書き換え、コマンドの実行など)を使おうとした瞬間に、条件を見て止める
  2. 実行後に整える: 何かを書き換えたあとに、チェックや整える処理を必ず走らせる
  3. 終わりを認めない: Claude Codeくんが「できました」と言ったあとに確認を走らせて、通らなければ作業を続けさせる

フックを書く場所は、第17回の権限設定と同じ設定ファイルです。

よくある3つの誤解

  1. 「フックって、どうせプログラムを書く人のためだけの機能でしょ?」 — フックの中身は「この場面が来たら、これを動かす」だけです。公式が「最初の1個」としておすすめしているのも、Claude Codeくんが返事を待って止まっていたら、パソコンの画面に通知を出す、という身近なフック。作るのに自分でプログラムを書く必要はなく、「Claude Codeくんが返事待ちになったら通知を出すフックを作って」と頼めば作ってくれます。フックは、プログラムを書けなくても使える。最初の1個は、通知から。
  2. 「貼り紙に『絶対に』とか『必ず』って強く書けば、フックと同じことでしょ?」 — 強く書いても、お願いはお願い止まりです。しかも「絶対」「必ず」のような強調の言葉は、増やすほど1つ1つの重みが薄まります。全部の行に「絶対」があると、どれが本当に絶対なのか、Claude Codeくんには分からなくなります。強調語は特に大事な2つか3つだけに使うのが、貼り紙の書き方の基本です。1回でも抜けたら困ることは、貼り紙の中で強調するのではなく、貼り紙から出して、フックか権限設定という「仕組み」の側に移します。
  3. 「じゃあ、フックで全部縛っておけば、何も心配いらないんでしょ?」 — フックにはできることの範囲があります。「実行後」のフックは作業が終わったあとに動くので、その作業を取り消すことはできません。また、フックで「この操作は許可」と書いても、権限設定の拒否リストで「ダメ」になっている操作は止まったままです。フックは安全の仕組みを足すことはできても、外すことはできない。そして、フックは自分で決めた条件しか見ないので、条件に書いていないことは素通りします。

ステップ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道具がうまく使えた直後。チェックや整える処理を走らせる。取り消しはできない
返事を終えるときStopClaude Codeくんが返事を終えたとき。止める合図を返すと、作業を続けさせられる。こちらが途中で中断したときは動かない
会話を始めるときSessionStart会話が始まったとき・再開したとき。最初に準備しておきたいことを走らせる
お知らせを出すときNotificationClaude 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くんに聞いてみてください

フックが動いてるかを確認する方法(本編では読まなかった分)

  1. /hooks と打つ: フックの一覧が開き、場面ごとに設定されているフックの数が出ます。場面を選ぶと、絞り込み・種類・どの設定ファイルに書いてあるか・中身が見られます。この画面は見るだけで、追加や変更は「〜するフックを作って」と頼むか、設定ファイルを直します
  2. 一覧に出てこないとき: 設定ファイルの書き方(JSON)が崩れていないか(最後のカンマ、コメントは書けません)、置き場所が合っているかを確認します。それでも出なければ、Claude Codeを起動し直します
  3. 一覧には出るのに動かないとき: 絞り込み(matcher)が道具の名前と大文字・小文字まで一致しているか、仕掛けた場面が合っているか(道具を使う前か、使った後か)を確認します
  4. 「フックのエラー」と表示されるとき: 処理のファイルに実行の許可がない、処理の中で使っている道具(jq など)が入っていない、などが原因です。表示された内容をそのままClaude Codeくんに渡せば、直し方を教えてくれます
~/next-steps