AI 工程

Kiro 全域 Hooks 實戰:一次設定、每個專案都生效(附 Introspect subagent 用法)

你有幾份一模一樣的 hook,散在每個 repo 裡?

只要你用 coding agent 用得夠深,遲早會踩到這個坑:你在 A 專案設好一個「commit 前先掃 secret」的 hook,效果很好;換到 B 專案,得再貼一次;C 專案又貼一次。哪天要改規則,得同步好幾個 .kiro/hooks/ 目錄,還很容易漏掉一個。這不是什麼大工程,但它是那種「每天多花五分鐘、而且遲早出包」的摩擦。

AWS 的 Kiro 在 CLI 2.13.0(2026/7/17 釋出,7/22 補上 2.13.1)針對這件事給了兩個更新,都掛在早期存取的 CLI 3.0(用 kiro-cli --v3 進入)底下:一個是 Introspect 內建 subagent,讓你直接在對話裡問 agent「這功能怎麼設」;另一個是 全域 Hooks(global hooks)——把 hook 放進 ~/.kiro/hooks/,它就在你每一個 workspace 自動觸發。這篇把兩個功能的機制講清楚,並給可以照抄的設定。

(先說清楚:以下是從 Kiro 官方 changelog 與文件整理的,我沒有實跑過 V3 早期存取版;設定格式以官方文件為準,會標註哪些是文件明寫、哪些是我合理推得。)

背景:Kiro 的 hook 是什麼、跟 Claude Code 的差在哪

Kiro 是 AWS 的 agentic 開發工具,有 IDE 也有 CLI。它的 hook 概念跟 Claude Code 幾乎同源:在 agent 執行流程的特定時間點,自動跑一段你指定的指令,用來做 lint、測試、審計、守門這類「不該靠模型自律、而該由系統強制」的事。

差別在「hook 定義在哪」。Kiro CLI 的 hook 是寫在 agent 設定檔裡的一個 hooks 物件(每個觸發點底下是一組指令陣列)。在 V3,官方把 hook 拆成獨立檔案,可以放在專案的 .kiro/hooks/ 底下逐一管理。而 2.13 這次的重點,就是讓這套機制多一個「全域」層級。

運作原理一:全域 Hooks,寫一次到處生效

changelog 的原話是:「Hooks placed in ~/.kiro/hooks/ now fire in every workspace automatically」——放進使用者家目錄 ~/.kiro/hooks/ 的 hook,現在會在每個 workspace 自動觸發。像 lint on save、commit 前的安全檢查、自訂審批 gate 這種跨專案共用的行為,不用再每個 repo 複製一份。專案層級的 .kiro/hooks/ 照舊運作,跟全域 hook 並存。

全域 Hooks 架構圖:~/.kiro/hooks 全域生效,workspace 覆蓋 global

這其實是社群 issue #5440(2026/2/5 開的)點名要的東西:讓 hook 跟 steering、MCP 一樣支援全域設定。那張 issue 提議沿用 steering 的覆蓋邏輯——同名時 workspace 蓋過 global,既能共用團隊規則,又留給專案客製空間。要提醒的是:changelog 只明確講「全域 hook 會在每個 workspace 觸發、與專案 hook 並存」,至於同名衝突時精確的覆蓋順序,官方文件我沒查到白紙黑字的定義,上面「workspace 覆蓋 global」是 issue 的提案與 steering 的既有慣例,值得你在自己環境實測確認。

運作原理二:hook 靠 STDIN 收事件、靠 exit code 回話

要把全域 hook 用對,得先懂單顆 hook 怎麼運作。Kiro CLI 文件把觸發點分成五個:

  • agentSpawn:agent 啟動時
  • userPromptSubmit:你送出 prompt 時
  • preToolUse:工具執行「前」(唯一能攔截的點)
  • postToolUse:工具執行「後」
  • stop:模型回應結束時

hook 生命週期圖:agentSpawn→userPromptSubmit→preToolUse→postToolUse→stop 五個觸發點

每次觸發,Kiro 會把一段 JSON 從 STDIN 餵給你的指令,欄位包含 hook_event_namecwdsession_id;工具相關的 hook 再多帶 tool_nametool_inputpostToolUse 還會有 tool_response。你的指令用 exit code 回話

  • 0:成功,STDOUT 會被吃進 context
  • 2:只在 preToolUse 有意義——擋下這次工具呼叫,並把 STDERR 回傳給模型當理由
  • 其他非 0:視為失敗,STDERR 當警告顯示

preToolUse / postToolUse 還能用 matcher 挑要攔哪些工具,支援標準名 fs_readfs_writeexecute_bashuse_aws,別名 readwriteshellaws,以及 @git@git/status@builtin* 這種樣式。stop hook 特別的是可以回傳 JSON {"decision": "block", "reason": "..."},把「你還沒做完」的訊息塞回去要 agent 續做。

一個最小可跑的 agent 設定 hooks 區塊長這樣(官方文件範例):

{
  "hooks": {
    "agentSpawn": [
      { "command": "git status" }
    ],
    "preToolUse": [
      {
        "matcher": "execute_bash",
        "command": "{ echo \"$(date) - bash:\"; cat; } >> /tmp/bash_audit"
      }
    ],
    "postToolUse": [
      { "matcher": "fs_write", "command": "cargo fmt --all" }
    ],
    "stop": [
      { "command": "npm test" }
    ]
  }
}

要把這套變成「全域」,概念上就是把這類 hook 定義搬到 ~/.kiro/hooks/,之後每個 workspace 都吃得到。

除錯與節流:timeout、cache,還有「以為擋住其實沒擋」

全域 hook 因為到處觸發,任何一顆的效能問題都會被放大成「每個專案都變慢」,所以升級到 ~/.kiro/hooks/ 之前,有兩個旋鈕要先懂。第一是 timeout_ms(依 Kiro CLI hook 文件,預設 30000,也就是 30 秒)——hook 跑太久會被砍掉當失敗,跨專案共用的檢查千萬別寫成會卡住整條對話的重工。第二是 cache_ttl_seconds(預設 0 不快取),對「同樣輸入、結果不太會變」的昂貴檢查,設一個 TTL 讓輸出在一段時間內重用,就不會每個回合都重跑一次。

最常見的坑是「以為擋住、其實沒擋」。記住 hook 是純靠 exit code 溝通:非 0 但不是 2 的離開碼,只會把 STDERR 當警告顯示、不會攔下工具。真的要 gate,preToolUse 一定要 exit 2,其他寫法都只是「提醒模型」而非「阻止動作」。除錯時,把要給人看的訊息印到 STDERR、把要餵回模型的內容印到 STDOUT,兩條流分清楚,會少掉一大半玄學。

跟 Claude Code hooks 對照,遷移幾乎不用重學

用過 Claude Code hooks 的人會覺得這套很眼熟:Claude Code 一樣有 PreToolUse / PostToolUse / UserPromptSubmit / Stop,一樣把事件用 JSON 從 STDIN 餵進來、一樣用 exit code 2 擋工具、一樣有 matcher 挑工具。最大的差別是「設定住哪」——Claude Code 的 hook 寫在 settings.json,且天生有 user(~/.claude/)、project(.claude/)、local 三層;Kiro 這次補上 ~/.kiro/hooks/ 全域層,等於把「跟 user-level 對等」的那塊補齊了。

所以心智模型可以直接搬:Kiro 的全域 hook ≈ Claude Code 的 user-level hook,Kiro 的 workspace hook ≈ Claude Code 的 project hook。要注意的是兩邊觸發點命名大小寫(Kiro CLI 文件用 preToolUse、Claude Code 用 PreToolUse)與部分欄位細節不同,搬設定時逐條對照,別整段複製貼上。

三個可以今天就抄的全域 hook

1) 全域 commit 守門(擋 secret)。用 preToolUseexecute_bash,偵測到祕密就 exit 2

{
  "hooks": {
    "preToolUse": [
      {
        "matcher": "execute_bash",
        "command": "gitleaks protect --staged --redact || exit 2"
      }
    ]
  }
}

放進 ~/.kiro/hooks/ 後,不管在哪個 repo,agent 想跑 git commit(或任何 bash)前都會先過這關;掃到祕密就被擋下,STDERR 直接變成模型看到的理由。

2) 全域存檔格式化。用 postToolUsefs_write,寫檔後自動 lint/format——例如前端專案掛 eslint --fix,Rust 專案掛 cargo fmt。這類「不該靠模型記得」的收尾,正是全域 hook 的甜蜜點。

3) 全域收官測試stopnpm test 或你的 smoke test,並在失敗時回 {"decision":"block","reason":"tests failing"},逼 agent 在收工前把測試修綠。

Introspect subagent:不用翻文件,直接問

配好 hook 最惱人的一步,往往是「我到底該用哪個觸發點、matcher 該寫什麼」。2.13 的 Introspect 內建 subagent 就是為這件事來的。changelog 說它能「解釋 Kiro 的功能、手把手帶你寫 custom agents、hooks 和 steering files、並建議適合你工作流的設定」——你在 kiro-cli --v3 裡直接用自然語言問,答案 in-line 回在對話中。

實務上的用法,就是把它當「懂 Kiro 內部設定的助教」。可以照這樣問:

幫我寫一個全域 hook,放在 ~/.kiro/hooks/,在 agent 跑任何 bash 前先用 gitleaks 掃 staged 檔案,掃到祕密就擋下來,並把原因回給你。

或者:

我想讓每次寫檔後自動跑對應語言的 formatter,這個該用 preToolUse 還是 postToolUse?matcher 怎麼寫?

它是 subagent,意味著跑在獨立 context、不會把這些設定問答污染你主線對話——這點跟 Kiro 既有的 subagent 設計一致(官方文件提到最多可同時開 4 個 subagent 平行做事、各自 isolated context)。

值得注意的是 changelog 明講它不只懂 hook,還能帶你寫 custom agents 和 steering files。steering 是 Kiro 放團隊規範、慣例、專案上下文的地方(角色類似 CLAUDE.md / AGENTS.md),對想把整個團隊的 agent 行為標準化的人來說,「全域 hook 管強制動作、steering 管軟性規範、Introspect 當設定助教」這三件事湊在一起,才是這版更新真正的意義。所以問它時別只問語法,也可以問策略,例如:

我想讓所有 repo 的 agent 在動 migrations/ 底下的檔案前都要人工確認,這用全域 hook 的 approval gate 做比較好,還是寫進 steering 比較好?各自的取捨是什麼?

數據與限制:先別在 CI 全面押上

要誠實幾件事。第一,Introspect 與全域 Hooks 都掛在 CLI 3.0 早期存取,得用 kiro-cli --v3 才進得去;早期存取意味著行為可能還會變,別急著寫死進團隊 onboarding 文件。第二,2.13.0 同批還修了給所有使用者的錯誤處理問題,但 changelog 沒給細節,我不編數字。第三,如前面說的,全域 vs 專案 hook 的精確覆蓋順序官方沒明寫,跨團隊共用前務必自己驗一次同名情境。第四,preToolUseexit 2 擋工具很強,但也代表一顆寫壞的全域 hook 會在你所有專案裡同時卡住 agent——威力越大,越要先在單一 repo 試過再升級到 ~/.kiro/hooks/

什麼時候該用全域 hook、什麼時候別用

該用:規則是「跨專案、不因語言或框架而異」的橫切關注點——secret 掃描、commit 訊息規範、危險指令攔截、稽核 log。這些放全域,一次到位、每個 repo 都受保護。

別放全域(該留在 workspace):跟專案技術棧綁死的動作。cargo fmt 只對 Rust 專案有意義、eslint --fix 只對前端有意義,硬放全域反而會在不相干的 repo 空跑、甚至因為找不到工具而狂噴警告。折衷做法有兩種:一是全域 hook 只做「先偵測這是什麼專案、再決定跑什麼」的分派邏輯;二是乾脆讓這類格式化留在各專案的 .kiro/hooks/,全域只擺純檢查。

還有一種要特別小心:會寫檔或改狀態的 hook。全域範圍再加上副作用,出錯時的爆炸半徑是你所有專案。這種寧可逐專案開,或至少先在單一 repo 觀察幾天再升級。

一句話原則:全域放「檢查與攔截」,workspace 放「跟這個專案怎麼做事有關」的東西。

對工程團隊的意義

如果你是團隊裡定規範的人,全域 Hooks 讓「安全與品質底線」第一次能用 agent 原生機制強制,而不是靠人記得在每個 repo 貼設定:secret 掃描、commit 前檢查、審批 gate 一次定義、全域生效。搭配 Introspect,新人不用讀完整份 hook 文件也能問出正確設定,降低了「hook 明明能救命卻沒人設」的門檻。

可操作的起手式:先在一個 repo 的 .kiro/hooks/ 把一顆 hook(例如 secret 守門)調到穩,用 Introspect 幫你確認觸發點與 matcher,再把它升級到 ~/.kiro/hooks/,最後才逐步把其他跨專案規則搬上全域。先窄後寬,別一次全推。

來源

整理:DataAgent · Coding Agent 實戰教學

發表迴響

%d 位部落客按了讚: