claude-code-notifier
運作方式 指南 常見問題
◐繁體中文
English العربية Deutsch Español Français עברית Italiano 日本語 한국어 Nederlands Polski Português (Brasil) Русский Türkçe Tiếng Việt 简体中文 繁體中文
開始使用
所有指南

Claude Code 的 Stop hook:在 Claude 完成時執行指令

更新於 2026年10月31日 · 閱讀時間 6 分鐘
本頁內容 01Stop 何時會觸發、何時不會 02最簡單的 Stop hook 03hook 會收到什麼 04在通知中顯示 Claude 的最後一則訊息 05讓 Claude 繼續工作 06失敗時也發通知 07Claude Code Notifier 的角色 08常見問題

每當 Claude 主 agent 完成回應,Claude Code 的 Stop hook 就會執行一個指令,因此很適合用來發送「完成」通知、記錄結果或執行檢查。你中斷 Claude 時它不會執行;若某個回合因 API 錯誤而結束,則會改為觸發 StopFailure。hook 會在 last_assistant_message 中收到 Claude 的最後一則訊息,也可以回傳 decision: "block" 並附上 reason,讓 Claude 繼續而不停止。

01Stop 何時會觸發、何時不會

Stop 會在每個回合結束時觸發,而不只是在整個任務完成時。Claude Code 並沒有「任務」的概念,它只知道 Claude 已停止回應、正在等你。一個簡短的問題會觸發一次 Stop,兩小時的重構也一樣只觸發一次。

以下情況不會觸發:

  • 你按下 Esc 或以其他方式中斷該回合時;
  • 回合因 API 錯誤(例如速率限制、過載或驗證失敗)而結束時。這些情況下 Claude Code 會觸發 StopFailure,並附上可供比對的 error 欄位(rate_limit、overloaded、server_error 等);
  • subagent 完成時。那是 SubagentStop。

Stop 不支援 matcher,因此你加上的任何 matcher 都會被忽略,hook 會在每個回合執行。

02最簡單的 Stop hook

將以下內容加入 ~/.claude/settings.json,即可在 Claude 每次完成時執行指令。這個範例會在 macOS 上播放音效:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "afplay /System/Library/Sounds/Glass.aiff"
          }
        ]
      }
    ]
  }
}

Mac、Windows 和 Linux 的桌面通知指令,請參閱如何在 Claude Code 完成時收到通知。本指南其餘部分將說明如何運用 hook 的輸入與輸出。

03hook 會收到什麼

除了共通欄位(session_id、transcript_path、cwd、permission_mode、hook_event_name)之外,Stop hook 還會收到:

欄位內容
last_assistant_messageClaude 在此回合最後一則回覆的文字
stop_hook_active若 Claude 已因 Stop hook 阻擋而在繼續執行,則為 true
background_tasks仍在執行中的任務,例如背景 shell 或 subagent
session_crons此工作階段中已排定的喚醒,例如來自 /loop

請使用 last_assistant_message,不要去讀 transcript 檔案。transcript 是非同步寫入的,hook 執行時可能還沒寫入最後一則訊息。

background_tasks 和 session_crons 能告訴你工作階段是真的結束了,還是只是暫停、等背景工作再次喚醒。通知腳本可以先確認兩者皆為空,再顯示「完成」。

04在通知中顯示 Claude 的最後一則訊息

這個腳本(適用 macOS 和 Linux,需要 jq)會顯示 Claude 回覆的開頭,若仍有背景工作在執行則不發出通知:

#!/bin/bash
# ~/.claude/hooks/notify-done.sh
input=$(cat)

# Skip if background tasks are still in flight
busy=$(jq '(.background_tasks // []) | length' <<<"$input")
[ "$busy" -gt 0 ] && exit 0

msg=$(jq -r '(.last_assistant_message // "Claude has finished")
             | gsub("\\s+"; " ") | .[0:140]' <<<"$input")

if command -v osascript >/dev/null 2>&1; then
  osascript -e 'on run argv' \
            -e 'display notification (item 1 of argv) with title "Claude has finished"' \
            -e 'end run' "$msg"
elif command -v notify-send >/dev/null 2>&1; then
  notify-send "Claude has finished" "$msg"
fi
exit 0

存檔後執行 chmod +x ~/.claude/hooks/notify-done.sh,再讓 hook 指向它:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [{ "type": "command", "command": "~/.claude/hooks/notify-done.sh" }]
      }
    ]
  }
}

這個腳本一律以 0 結束。這點很重要:在 Stop 上,結束代碼 2 代表「不要停止」,所以通知腳本若意外以 2 結束,就會讓 Claude 一直工作下去。

05讓 Claude 繼續工作

Stop 是可以阻擋的事件之一。阻擋停止代表 Claude 會繼續這個回合,並把你提供的原因當作下一個指示。有兩種做法:

  • 以 2 結束,Claude 會將你的 stderr 當作原因;或
  • 以 0 結束並輸出 JSON:
{
  "decision": "block",
  "reason": "The test suite is failing. Run npm test, fix the failures, then finish."
}

如果 hook 是在提供指引而非回報錯誤,hookSpecificOutput.additionalContext 同樣能讓對話繼續,而 transcript 會將其標示為 Stop hook 回饋,而不是 hook 錯誤:

{
  "hookSpecificOutput": {
    "hookEventName": "Stop",
    "additionalContext": "Please run the test suite before finishing"
  }
}

避免無限迴圈

一個總是阻擋的 Stop hook 會讓 Claude 永遠停不下來。有兩道防線:

  1. 一旦 Claude 已因 Stop hook 而繼續執行,stop_hook_active 就會是 true。檢查它並提早結束即可。
  2. 若 Stop hook 連續阻擋八次且中間沒有任何工具呼叫,Claude Code 仍會結束該回合。可透過 CLAUDE_CODE_STOP_HOOK_BLOCK_CAP 環境變數提高這個上限。

以下這個 hook 會讓 Claude 修正失敗的測試一次,然後讓它停止:

#!/bin/bash
# ~/.claude/hooks/tests-must-pass.sh
input=$(cat)
[ "$(jq -r '.stop_hook_active' <<<"$input")" = "true" ] && exit 0

if ! npm test --silent >/dev/null 2>&1; then
  jq -nc '{decision: "block", reason: "npm test is failing. Fix the failures, then finish."}'
fi
exit 0

Hook 會在 session 的工作目錄中執行,所以 npm test 會在你的專案裡跑。檢查要盡量快:command hook 預設最多可執行 600 秒,而 Claude 會一直等它跑完。

如果你只是想讓 Claude 朝某個目標持續工作、又不想寫腳本,Claude Code 內建的 /goal 指令會自動幫你設定一個僅限該 session 的 Stop hook。

06失敗時也發通知

由於 API 錯誤不會觸發 Stop,「完成」通知不會告訴你 Claude 因為 rate limit 而放棄了。如果想收到這類通知,就把同一支腳本也加到 StopFailure 底下。它的輸出和 exit code 都會被忽略,所以只能用來通知或記錄。在 StopFailure 中,last_assistant_message 會是錯誤訊息,例如 "API Error: Rate limit reached"。

07Claude Code Notifier 的角色

用 Stop hook 呼叫推播服務,是在你離開座位時得知 Claude 已完成的好方法。如果想自己動手做,可以從 ntfy 指南開始。

Claude Code Notifier 使用同樣的 Stop hook,差別只有一個:它可以回傳內容。它的免費命令列工具 ccn 可在 Mac、Windows 和 Linux 上執行,本身就能顯示桌面通知。配對 iPhone 或 Android App 後,每個回合一結束你就會收到「Claude 已完成」的推播,還能直接在手機上輸入下一個指令。ccn 會從 Stop hook 把它回傳為 Claude 的下一個指令,讓 session 在你不在鍵盤前時也能繼續。如果你在最近 30 秒內有打字,就不會等待手機。這是獨立開發的工具,並非 Anthropic 出品。這套流程請參考離開長時間任務,安裝方式請見 ccn 頁面。

08常見問題

Stop hook 是在 Claude 完成整個任務時執行,還是每次回覆後都會執行?

每次回覆後都會執行。只要主 agent 回應結束,不論請求大小,Stop 都會觸發。若需要知道是否還有排定的工作,可以檢查輸入中的 background_tasks 和 session_crons。

為什麼我的 Stop hook 沒有觸發?

可能是你中斷了該回合,這會略過 Stop;或是回合因 API 錯誤結束,這時觸發的是 StopFailure。除此之外,請確認 /hooks 有列出你的 hook,且腳本具有執行權限。其他情況請參考疑難排解清單。

為什麼我的 Stop hook 執行後 Claude 還在繼續工作?

你的 hook 擋下了停止動作,可能是以 exit code 2 結束,或輸出了 decision: "block"。請確保只負責通知的 hook 一律以 0 結束,而任何會阻擋的 hook 都要先檢查 stop_hook_active。

如何在 hook 中取得 Claude 的最終回答?

從 stdin 的 JSON 讀取 last_assistant_message,例如使用 jq -r '.last_assistant_message'。不要依賴 transcript_path:Stop 觸發時,該檔案可能還沒寫入最後一則訊息。

Stop 和 SubagentStop 有什麼差別?

Stop 針對主 agent。SubagentStop 會在 subagent 完成時觸發,依 agent 類型比對,並支援相同的阻擋欄位。「Claude 已完成」的通知應該放在 Stop。

Claude Code Notifier Claude Code 完成或需要你處理時,手機會收到 push 通知,並可直接在手機上核准、拒絕或回覆。ccn 命令列工具在 Mac、Windows 和 Linux 上皆可免費使用。
下載 iOS 版 下載 Android 版 安裝 ccn

相關指南

  • 如何在 Claude Code 完成時收到通知用 Stop hook 處理「已完成」,用 Notification hook 處理「需要輸入」。提供 Mac、Windows 和 Linux 可直接複製貼上的設定,還有手機通知。
  • Claude Code hook 完整解析:每個事件及其用途介紹 Claude Code hook 是什麼、要寫在 settings.json 的哪裡、matcher、輸入與 exit code 如何運作,以及每個 hook 事件的用途。
  • Claude Code 的 Notification hook:觸發時機與使用方式Claude Code 的 Notification hook 何時觸發、permission_prompt 和 idle_prompt 代表什麼、它收到的輸入,以及為何會延遲觸發。
  • 讓 Claude Code 繼續跑,人先離開:一套工作流程處理長時間 Claude Code 任務的實用流程:讓電腦保持喚醒、減少不必要的 prompt、在手機上收到通知並直接回覆。
claude-code-notifier

Claude Code Notifier 為獨立的第三方應用程式,與 Anthropic, PBC 並無關聯,亦未獲其背書或贊助。「Claude」及「Claude Code」為 Anthropic, PBC 之商標。

App iOS App Android App ccn(macOS、Windows、Linux) 所有指南
法律資訊 隱私權政策 服務條款 其他語言 © 2026 touchtap. 保留所有權利。 TouchTap Ltd 註冊於英格蘭和威爾斯,公司編號 13942589。