Skip to main content
钩子是一些小型脚本,当代理事件触发时,它们会在网关内部运行:例如 /new/reset/stop 等命令、会话压缩、网关生命周期以及消息流。钩子从目录中发现,并通过 openclaw hooks 进行管理。只有在启用钩子,或配置至少一个钩子条目、钩子包或额外钩子目录后,网关才会加载内部钩子。 OpenClaw 中有两种钩子:
  • 内部钩子(本页):在代理事件触发时在网关内部运行。
  • Webhooks:外部 HTTP 端点,让其他系统触发 OpenClaw 中的工作。参见 Webhooks
钩子也可以打包在插件中。openclaw hooks list 会同时显示独立钩子和由插件管理的钩子(显示为 plugin:<id>)。

选择合适的扩展面

OpenClaw 有几个看起来相似但用途不同的扩展面: 当你需要像小型已安装集成一样运行的自动化时,使用内部钩子。当你需要运行时生命周期控制时,使用类型化插件钩子。 内部钩子处理程序是请求/事件处理程序。它们不得持有长生命周期的计时器、监视器、套接字或客户端;插件应注册服务,或改用类型化的 gateway_start / gateway_stop 生命周期。

快速开始

事件类型

钩子订阅此表中的特定键,或订阅一个裸的家族名称 (command, session, agent, gateway, message) 来接收该家族中的每个动作。 OpenClaw 核心不会发出任何其他事件,因此任何其他名称几乎 总是一个拼写错误,会让钩子悄无声息地失效(只有发出自定义事件的插件才可能触发它)。 钩子加载器会对这类名称记录警告 (例如 command:nwe),并且 openclaw hooks info <name> 会将它们标记出来,因此 从未运行过的钩子是可以诊断的。

编写钩子

钩子结构

每个钩子都是一个包含两个文件的目录:
处理器文件可以是 handler.tshandler.jsindex.tsindex.js

HOOK.md 格式

元数据字段metadata.openclaw):

处理器实现

每个事件都包含:typeactionsessionKeytimestampmessagescontext(事件特定数据)。面向 agent 和 tool 钩子的类型化插件 hook 上下文还可以包含 trace,这是一个只读、兼容 W3C 的诊断 trace 上下文,插件可以将其传递给结构化日志用于 OTEL 关联。 推送到 event.messages 的字符串只会在以下情况下回传到聊天: command:newcommand:reset(作为对原始 会话的回复路由),以及 session:compact:before / session:compact:after (作为紧凑化状态通知发送)。其他所有事件,包括 command:stopmessage:*agent:bootstrapsession:patchgateway:*,都会忽略推送的消息。

事件上下文要点

命令事件command:newcommand:reset):context.sessionEntrycontext.previousSessionEntrycontext.commandSourcecontext.senderIdcontext.workspaceDircontext.cfg 命令事件command:stop):context.sessionEntrycontext.sessionIdcontext.commandSourcecontext.senderId 自动重置事件session:auto-reset):context.sessionEntrycontext.reasondailyidle)、context.transcriptArchivedcontext.nextSessionIdcontext.nextSessionKeycontext.agentIdcontext.workspaceDircontext.storePathcontext.cfg 消息事件message:received):context.fromcontext.contentcontext.channelIdcontext.media(按顺序排列的暂存附件信息)、远程媒体尚未在本地暂存时的 context.originalMedia 以及 context.mediaStagingPending,还有 context.metadata(包括 senderIdsenderNameguildId 等提供商特定数据)。对于类似命令的消息,context.content 优先使用非空的命令正文,然后回退到原始入站正文和通用正文;它不包含仅供 agent 使用的增强内容,例如线程历史或链接摘要。metadata 中的旧版媒体别名已弃用。 消息事件message:sent):context.tocontext.contentcontext.successcontext.channelId,发送失败时还包括 context.error 消息事件message:transcribed):context.transcriptcontext.fromcontext.channelIdcontext.mediacontext.mediaPathcontext.mediaType 仍然是第一个事实的弃用别名。 消息事件message:preprocessed):context.bodyForAgent(最终增强后的正文)、context.fromcontext.channelId 启动事件agent:bootstrap):context.bootstrapFiles(可变数组)、context.agentId 会话补丁事件session:patch):context.sessionEntrycontext.patch(仅更改的字段)、context.cfg。只有有特权的客户端才能触发补丁事件;该上下文是一个克隆,因此处理器无法修改实时会话条目。 紧凑化事件session:compact:before 包含 messageCounttokenCountsession:compact:after 增加 compactedCountsummaryLengthtokensBeforetokensAfter command:stop 反映用户发出了 /stop;它属于取消/命令生命周期,而不是代理最终完成的门控。需要检查自然最终答案并要求代理再次执行一次的插件,应使用类型化插件 hook before_agent_finalize。参见 插件钩子

Gateway 生命周期事件

gateway:shutdown 包含 reasonrestartExpectedMs,并在 gateway 开始关闭时触发。gateway:pre-restart 包含相同的上下文,但仅在关闭是预期重启的一部分且提供了有限的 restartExpectedMs 值时触发。在关闭期间,每个生命周期 hook 的等待都是尽力而为且有上限的,因此即使某个处理器卡住,关闭仍会继续。默认等待预算为:gateway:shutdown 5 秒,gateway:pre-restart 10 秒。 当通道仍然可用时,请使用 gateway:pre-restart 发送简短的重启通知:
gateway:shutdown(或 gateway:pre-restart)事件与后续关闭流程之间,gateway 还会为进程停止时仍处于活动状态的每个会话触发一个类型化的 session_end 插件 hook。对于普通的 SIGTERM/SIGINT 停止,事件的 reasonshutdown;当关闭是预期重启的一部分时,reasonrestart。此清理过程有上限,因此较慢的 session_end 处理器不会阻塞进程退出;已经通过 replace / reset / delete / compaction 完成终结的会话也会被跳过,以避免重复触发。

钩子发现

钩子来自四个来源:
  1. 捆绑钩子:随 OpenClaw 一起发布
  2. 插件钩子:捆绑在已安装的插件中;可以覆盖同名的捆绑钩子
  3. 托管钩子~/.openclaw/hooks/(用户安装,在不同工作区之间共享);可以覆盖捆绑钩子和插件钩子。来自 hooks.internal.load.extraDirs 的额外目录共享此优先级。
  4. 工作区钩子<workspace>/hooks/(按代理隔离,默认禁用,直到显式启用)
工作区钩子可以添加新的 hook 名称,但不能覆盖同名的捆绑、托管或插件提供的钩子。 网关在内部钩子完成配置之前,会在启动时跳过内部钩子发现。使用 openclaw hooks enable <name> 启用捆绑钩子或托管钩子,安装钩子包,或设置 hooks.internal.enabled=true 以选择启用。即使主开关为 true,指定的条目仍然会作为允许列表。仅设置 hooks.internal.enabled=true 且不包含任何指定条目时,会启用广泛发现;不包含钩子名称声明的非空额外钩子目录和钩子包安装也会采用开放式发现。

Hook 包

Hook 包是通过 package.json 中的 openclaw.hooks 导出钩子的 npm 包。使用以下命令安装:
Npm 规格仅限注册表(包名 + 可选的精确版本或 dist-tag)。Git/URL/file 规格和 semver 范围都会被拒绝。较旧的 openclaw hooks installopenclaw hooks update 命令是 openclaw plugins install / openclaw plugins update 的弃用别名。

捆绑钩子

启用任意捆绑钩子:

session-memory 详情

在执行 /new/reset、每日重置或闲置过期时,提取最近的用户/助手消息(默认为 15 条,可通过 hooks.internal.entries.session-memory.messages 配置),并使用 agents.defaults.userTimezone 将其保存到 <workspace>/memory/YYYY-MM-DD-HHMM.md。未配置用户时区时,将回退到主机时区。记忆捕获在后台运行,因此重置处理和替换会话不会因读取转录或生成可选 slug 而延迟。设置 hooks.internal.entries.session-memory.llmSlug: true 可生成描述性文件名 slug,还可以选择将 hooks.internal.entries.session-memory.model 设置为已配置的别名(例如 sonnet)、代理默认提供商上的裸模型 ID,或 provider/model 引用。如果省略 model,slug 生成会使用代理的默认模型;当默认模型不可用时,则回退到时间戳 slug。要求配置 workspace.dir
memory 源已经会为此钩子保存的对话摘录建立索引。如果同时启用了 会话转录索引, 同一对话可能会同时出现在 memorysessions 中,从而产生重叠的搜索结果并增加额外的嵌入计算。 若只使用钩子进行召回,请设置 memory.search.sources: ["memory"]memory.search.rememberAcrossConversations: false;仅设置 sources 并不能阻止跨对话召回添加 sessions。 若要召回完整转录,则运行 openclaw hooks disable session-memory。仅当你确实希望同时使用这两种表示形式时,才启用两者。

bootstrap-extra-files 配置

patternsfiles 可作为 paths 的别名使用。路径将相对于工作区解析,且必须保持在工作区内部。只会加载可识别的 bootstrap 基本文件名(AGENTS.mdSOUL.mdIDENTITY.mdUSER.mdBOOTSTRAP.mdMEMORY.md)。 TOOLS.md 不再被识别为 bootstrap 基本文件名,也不会加载到运行时上下文中。openclaw doctor --fix 会将工作区根目录下的 TOOLS.md 迁移到 AGENTS.md## Tools 部分;命名其他 TOOLS.md 文件的模式不会被迁移,应改指向 AGENTS.md

command-logger 详情

将每个斜杠命令作为 JSON 行(时间戳、操作、会话键、发送者 ID、来源)记录到 ~/.openclaw/logs/commands.log

compaction-notifier 详情

在 OpenClaw 开始和结束紧凑化会话转录时,向当前对话发送简短状态消息。这会让长轮次在聊天界面上不那么令人困惑,因为用户可以看到助手正在总结上下文,并会在紧凑化后继续。

boot-md 详情

如果文件存在于该代理解析后的工作区中,则在网关启动时为每个已配置的代理作用域运行 BOOT.md

插件钩子

插件可以通过插件 SDK 注册类型化钩子,以实现更深度的集成: 拦截工具调用、修改提示词、控制消息流等。 当你需要 before_tool_callbefore_agent_replybefore_install 或其他进程内生命周期钩子时,请使用插件钩子。 插件管理的内部钩子是不同的:它们参与此页面的 粗粒度命令/生命周期事件系统,并在 openclaw hooks list 中显示为 plugin:<id>。请将它们用于副作用和与钩子包的兼容性,而不是用于 有序中间件或策略门控。 旧版插件 SDK 的 api.registerHook 仅注册到内部事件系统 (command:newgateway:startupmessage:received 等)。 诸如 before_tool_callmessage_receivedsession_start 之类的类型化 生命周期事件名称,只由类型化钩子运行器分发,不会通过 registerHook 调用。使用 registerHook 注册类型化名称时,会发出注册警告, 并指向作为替代方案的公共 api.on(...) API;它绝不会静默地不执行任何操作。 如需完整的插件钩子参考,请参阅插件钩子

配置

每个钩子的环境变量值与进程环境一起满足该钩子的 requires.env 资格检查,处理器可以从其钩子配置项中读取这些值:
额外的钩子目录:
hooks.internal.handlers 已停用,正常的配置验证不再加载或接受该配置项。在运行 openclaw doctor --fix 之前,请将每个已注册的模块移入托管钩子目录或工作区钩子目录,并为其添加 HOOK.md 和处理器文件。Doctor 会移除已停用的注册项,但不会创建可执行的钩子文件。对于仅包含旧版配置且 hooks.internal.enabled: true 的配置,Doctor 还会移除 enabled,以避免启用其他已发现的钩子。规范条目、非空的额外目录以及显式设置为 enabled: false 的配置项都会保留。

CLI 参考

最佳实践

  • 保持处理程序快速。 钩子会在命令处理期间运行。对于较繁重的工作,请使用 void processInBackground(event) 进行即发即弃式处理。
  • 优雅地处理错误。 将有风险的操作包装在 try/catch 中;不要抛出异常,以便其他处理程序能够继续运行。
  • 尽早过滤事件。 如果事件类型/操作不相关,请立即返回。
  • 使用具体的事件键。"events": ["command"] 相比,建议使用 "events": ["command:new"],以减少开销。

故障排查

未发现 Hook

Hook 不符合条件

检查是否缺少二进制文件(PATH)、环境变量、配置值或 OS 兼容性问题。

Hook 未执行

  1. 验证 hook 是否已启用:openclaw hooks list
  2. 重启你的 gateway 进程,以便重新加载 hooks。
  3. 检查 gateway 日志:openclaw logs --follow | grep -i hook

相关内容