為你的 AI Agent 掛上 Hooks 吧!
文章目錄

Claude Code、Cursor、Codex,這些 AI coding agent,相信你已經耳熟能詳,甚至每天都在用了。
那你聽過 agent hooks 嗎?
本文將介紹我目前唯二使用的 agent hooks,並說明它們為何重要。
涵蓋工具包括 GitHub Copilot、Claude Code、Codex 以及 OpenCode CLI。
不過,僅限於 macOS,其餘平台,就靠大家努力了☺️
什麼是 Agent Hooks
引領風騷的 Claude Code 最早發明了 agent hooks 這個概念。因為太過實用,後來其它工具也競相模仿。
簡單說,agent hooks 是這些 AI coding agent 提供的事件機制:當 agent 完成任務、需要確認,或發生特定事件時,自動執行你指定的腳本或指令。
如果你用過 Git hooks,比如最常見的 pre-commit hooks——在 commit 前跑腳本,agent hooks 就是同樣的概念:事件發生,執行特定指令。
只是觸發點從 Git 操作變成 agent 行為。
為什麼不能只靠指令遵循
我們固然可以在 prompt 裡寫「產完程式碼要記得跑 lint」之類的要求,但 AI 不一定每次都會照做,尤其當上下文愈來愈長、指示愈來愈複雜時。
至於「做完記得通知我」就更不用說了,AI 根本沒這能力——它沒辦法「主動」播放音效或彈系統通知。
而 hooks 保證了確定性——事件發生,腳本執行,不依靠 AI 的自主判斷。甚至做到了 AI 本來不能做的事,比如播放音效🔔
我只設兩種 hook
Agent hooks 能做的事很多,基本上能變成指令、腳本的內容都行,比如自動跑 lint、formatter、把結果寫進檔案等等。
但這些並非本文重點——我自己只設兩種 hook:完成通知和權限請求通知,都是為了在 agent 停下來時即時提醒我。
為什麼「通知」是最重要的 Hook
沒有通知,AI 幹活時你只有兩種選擇:在前景盯著它,或不停切回來確認。顯然兩種都不太有效率😅
有通知,我們才好真正「非同步」使用它:把任務交給 agent,去做別的事,聽到聲音再回來。
至於 lint、formatter,另有替代方案——pre-commit 這類工具、CI/CD 都能做。但完成通知只能透過 agent hooks,沒有其他機制能在 agent 停下來的那一刻通知你。
所以,其他 hooks 可以不設,但這個必須有!
通用性的偏好
我總共幫四個 AI coding agent 設定過 hooks:GitHub Copilot、OpenAI Codex app、Claude Code、OpenCode CLI。
至於 Google 的 Antigravity 2.0 app,因為內建了通知機制,就不必設定了。
我只寫全域 hooks,不寫 project-level。這些設定放在 home 目錄,透過 yadm 在不同機器之間同步。
我的 agent skills 也是採取同樣策略——幾乎都是全域的,很少寫 project-level。關於「通用 vs 專用」,之前文章有討論過。
接下來直接看設定,腳本也一併附上。
GitHub Copilot:直接共用 Claude Code 設定
GitHub Copilot 能讀取 Claude Code 的設定檔中,有關 hooks 的設定,所以可以直接共用,不用額外寫。
不過目前 Copilot 支援的事件種類沒有 Claude Code 多——Stop 事件有支援;不支援的事件會跳過,不會出錯。
考慮到我目前已經暫時棄用 GitHub Copilot 了,這部分請容我略過😆
如有需求,可參考官方文件。
Claude Code
設定位置:~/.claude/settings.json,內容如下:
1 | "hooks": { |
Stop 是完成通知:agent 停下來了。
PermissionRequest 是權限請求通知:當 agent 執行到需要額外權限時,需要你確認才能繼續。這個很有用,因為有時候你離開太久,回來發現 agent 早就在等你,白白浪費了時間。
上面的 command 的 path 請改成你放置腳本的地方,還有檔名。
OpenAI Codex app
設定位置:~/.codex/config.toml
1 | [hooks] |
Codex app 採用 TOML 格式,和 Claude Code 的 JSON 語法不同,但結構類似。
第一次設定,重啟 Codex app 時,會需要你確認 hooks 的內容與安全性。
OpenCode CLI
OpenCode 比較特別:不能在設定檔裡寫 hooks,必須用 plugin。
而 plugin/ 目錄要放在 opencode 設定檔(opencode.json)所在的目錄底下。
我的設定位置:~/.config/opencode/plugin/notify.js,如下(內容是我用 AI Vibe 的,你可以自行調整):
1 | export const NotifyPlugin = async ({ $ }) => { |
另一個要注意的是,event type 是 session.idle,不是 Stop。不過意思差不多啦!
透過 Attention 設定
其實,OpenCode CLI 還可以透過 Attention 功能——需要另外寫 tui.json,方便你設定通知,不一定要靠 plugin。
但我不確定它是否適用於「非互動模式」(即 opencode run),而且我感覺這做法的通用性,還不如直接寫 plugin。畢竟腳本可以共用。
共用的通知腳本
上述三套工具的 hooks 都呼叫同一組 shell 腳本,程式碼如下:
notify-agent-stop.sh
1 |
|
afplay 是 macOS 內建的指令,而音效名稱 Glass 也是內建的。
可以到系統的「設定 > 聲音 > 提示聲」去聆聽每一種內建音效,換成自己喜歡的。
也可以用 afplay 播放任何路徑下的音效檔(如 mp3、wav),只要檔案存在,指令就能正常運作。
而 osascript 則能在通知中心發出文字提醒。這兩個指令搭配起來,就能在任務完成時,同時播放音效和彈出通知,讓你知道 agent 已經處理完畢。
覺得這樣有點吵的話,可以二選一就好。
notify-agent-permission-request.sh
1 |
|
我覺得 Funk 音效很適合當「確認」使用XD
工具會換,需求不會
儘管不同的工具有不同的設定,但「通知」這個需求是一樣的。
所以我在每個工具中都實作了它,讓核心行為保持一致。
如此一來,你想換工具或退掉其中一部分時,體驗上不會受到太大影響。你只需要維護一組通知腳本,所有 agent 都能共用。
畢竟,工具只是工具,不要依戀它。