iT邦幫忙

2026 iThome 鐵人賽

DAY 22
0

D15 教的排程是看時間 —— 每天 23:00、每 7 天一次。但有些事你不知道它幾點會發生。

為什麼要HOOK。 你不知道自己明天幾點開電腦,所以排程處理不了「一開機就要做的事」。

hook 就是掛在事件上的那種觸發:條件一到自己跑,不用你叫,也不用等時間。

原理:一個資料夾,兩個檔

OpenClaw 做某些動作的時候會發出一個事件。你寫一個函式訂閱它,事件發生,Gateway 就呼叫你的函式。

一個 hook 就是一個資料夾,裡面兩個檔:

HOOK.md     宣告它叫什麼、掛哪個事件
handler.js  事件發生時要做什麼

內建的跟你自己寫的是同一種東西,結構完全一樣,連檔名都一樣。差別只有放在哪:內建的在套件裡,你寫的放 ~/.openclaw/hooks/你的名字/。hooks info 會標來源,一個是 openclaw-bundled,一個是 openclaw-managed。

預設有哪些

openclaw hooks list

內建五個,開箱就有:

boot-md                開機時讀 workspace 的 BOOT.md,叫 agent 照著做
bootstrap-extra-files  把你指定的檔案一起塞進開場的背景資料
command-logger         把命令事件寫進集中的稽核檔
compaction-notifier    對話被壓縮時在聊天室通知你
session-memory         對話重置時把上下文存進記憶

https://ithelp.ithome.com.tw/upload/images/20261006/20177920WL0GNalfJ5.png

第三個就是 D20 核准紀錄的來源 —— 那張帳本是這個 hook 在寫。

能掛的事件只有這些

事件是固定清單,分五類:

command   新對話、重置、停止
session   自動重置、壓縮前、壓縮後、設定被改
agent     開場載入背景資料
gateway   啟動、關機、重啟前
message   收到訊息、語音轉完文字、前處理完、訊息送出

總共十六個。看懂這張表就知道 hook 能做什麼、不能做什麼。

侷限性:看官方範本就知道

文件給的範例 hook 只有八行,而且特別註明「用 JavaScript 寫,所以不需要 TypeScript 型別,也不需要 import 任何 SDK」。

對照內建的 boot-md,它的 handler 開頭有十八行 import:

import { i as agentCommandFromSystem } from "../../agent-command-CZJyvgsL.mjs";
import { r as defaultRuntime }         from "../../runtime-KtFRxdRg.mjs";

檔名後面那串是 build hash,每次更新就換,而且路徑是 ../../ —— 只有放在套件目錄裡才解得開。內建 hook 能叫動 agent,是因為它拿得到這些內部模組。

所以能抄的只有外殼,不是實作。這條限制往下推出其他全部:

回傳值沒有用。 return 什麼都不會擋下或改寫原本的操作,只能做 —— 寫檔、發通知、記 log。

能掛「收到訊息的時候」,但不能掛「訊息內容是某某的時候」。 清單裡沒有這種事件。你可以在 message:received 裡自己判斷內容,但 message 那一類是觀察點,文件寫明不是阻止訊息繼續處理的方法。看得到,攔不下來。

它不在沙箱裡。 文件自己寫 trusted code,有 Gateway 的完整檔案、網路、環境權限。所以要用別人給的 hook 要先看過再開。

要改提示、攔工具呼叫、控制回覆內容 —— 這套機制做不到,得改成 PLUGIN。

BOOT.md 可以直接用自然語言寫

boot-md 的 handler 做的事就是讀 BOOT.md,把內容當指令送去跑。所以你不用寫程式,直接用中文寫你要它開機做什麼就好。

但它是開一個臨時對話去做,做完把對話丟掉。所以別寫「讀一下某個檔,記住內容」——記的東西跟著那個對話一起消失。它適合:開機檢查、整理暫存、發通知。

自己寫一個

建一個資料夾 ~/.openclaw/hooks/d22-demo/,裡面兩個檔。

HOOK.md:

---
name: d22-demo
description: "對話重置時留一行記號"
metadata:
  { "openclaw": { "events": ["command:new", "command:reset"] } }
---

handler.js:

export default function handler(event) {
  if (event.type !== "command") return;
  console.log("[d22-demo] reset hook ran, sessionKey=" + event.sessionKey);
  event.messages.push("hook 跑過了。");
}

啟用,不用重開 Gateway,設定是熱重載的:

openclaw hooks enable d22-demo

結果

啟用後兩秒,日誌出現:

[reload] config change detected (hooks.internal.entries.d22-demo)
[reload] config hot reload applied

接著在對話裡打 /new:

[d22-demo] reset hook ran, sessionKey=agent:labdemo:main

同一次重置還順便觸發了另外兩個內建 hook:session-memory 把上下文存成檔案,command-logger 在 commands.log 加了一行。一個動作三個 hook,這就是它平常在背後做的事。

兩個坑

boot-md 預設就是啟用的。但 workspace 裡沒有 BOOT.md、或者檔案是空的,它會直接跳過,不做事也不報錯,hooks list 一樣顯示 ready。我這台原本就是這種狀態。

而且 ready 只代表條件符合,不代表 Gateway 真的載入了它。要確認就去看日誌,或看它該產生的作用在不在。


上一篇
D21 指令跑在使用端的時候,它碰得到什麼
下一篇
D23 排程到底傳了什麼、有沒有發出去
系列文
AI Agent:OpenClaw 從入門到自動化流程 共 26 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言