跳到主要内容

事件钩子

Hermes 有三套 hook 系统,可在关键生命周期节点执行自定义代码:

SystemRegistered viaRuns inUse case
Gateway hooks~/.hermes/hooks/ 下的 HOOK.yaml + handler.py仅 Gateway日志、告警、webhook
Plugin hooksplugin 中使用 ctx.register_hook()CLI + Gateway工具拦截、指标、护栏
Shell hooks~/.hermes/config.yaml 中的 hooks: 配置脚本CLI + Gateway阻断、自动格式化、上下文注入

三套系统都是非阻塞的,hook 报错只会记录日志,不会让智能体崩溃。

网关事件钩子

Gateway hooks 会在 网关 运行期间自动触发(Telegram、Discord、Slack、WhatsApp 等),且不会阻塞主 agent 流程。

创建 Hook

每个 hook 对应 ~/.hermes/hooks/ 下的一个目录,其中包含两个文件:

~/.hermes/hooks/
└── my-hook/
├── HOOK.yaml
└── handler.py

HOOK.yaml

name: my-hook
description: Log all agent activity to a file
events:
- agent:start
- agent:end
- agent:step

handler.py

import json
from datetime import datetime
from pathlib import Path

LOG_FILE = Path.home() / ".hermes" / "hooks" / "my-hook" / "activity.log"

async def handle(event_type: str, context: dict):
entry = {
"timestamp": datetime.now().isoformat(),
"event": event_type,
**context,
}
with open(LOG_FILE, "a") as f:
f.write(json.dumps(entry) + "
")

规则:

  • 处理函数必须命名为 handle
  • 参数为 event_typecontext
  • 可以是 async def 或普通 def
  • 所有错误都会被捕获并记日志

可用事件

包括 gateway:startupsession:startsession:endsession:resetagent:startagent:stepagent:endcommand:* 等。

示例

  • BOOT.md 内置 hook:gateway 启动时自动检查 ~/.hermes/BOOT.md
  • 长任务告警:当 agent 超过 10 步时通知 Telegram
  • 命令使用日志:追踪 slash 命令使用情况
  • 会话启动 webhook:新会话创建时 POST 到外部服务

工作方式

  1. Gateway 启动时扫描 ~/.hermes/hooks/
  2. 自动加载带 HOOK.yaml + handler.py 的目录
  3. 按声明事件注册处理函数
  4. 在对应生命周期节点触发
  5. hook 出错只会记录日志,不会影响智能体
信息

Gateway hooks 只在 gateway 中生效。CLI 不会加载它们。若要让 hooks 在 CLI 和 网关 中都工作,请使用 plugin hooks

插件钩子

Plugins 可以注册在 CLI 与 gateway 中都生效的 hooks:

def register(ctx):
ctx.register_hook("pre_tool_call", my_tool_observer)
ctx.register_hook("post_tool_call", my_tool_logger)
ctx.register_hook("pre_llm_call", my_memory_callback)
ctx.register_hook("post_llm_call", my_sync_callback)
ctx.register_hook("on_session_start", my_init_callback)
ctx.register_hook("on_session_end", my_cleanup_callback)

通用规则:

  • 回调始终接收 keyword arguments,应当接受 **kwargs
  • 回调崩溃时只会被跳过,不会影响其他 hooks 或智能体主流程
  • 只有两个 hook 的返回值会影响行为:pre_tool_call 可以阻断工具调用,pre_llm_call 可以注入上下文。其他 hooks 都是观察型的。

快速参考

HookFires whenReturns
pre_tool_call工具执行前{"action": "block", "message": str} 可阻断调用
post_tool_call工具返回后ignored
pre_llm_call每轮开始前{"context": str} 可向用户消息前追加上下文
post_llm_call每轮成功结束后ignored
on_session_start新会话创建时ignored
on_session_end会话结束时ignored
on_session_finalizeCLI / 网关 销毁活跃会话时ignored
on_session_reset网关 切换到新 session key 时ignored
subagent_stopdelegate_task 子智能体退出后ignored

pre_tool_call

在每次工具执行之前触发。适合做日志、审计、危险操作拦截、限流和按用户策略阻断。

post_tool_call

在每次工具执行之后触发。适合收集指标、记录结果、统计成功率 / 失败率。

pre_llm_call

每轮只触发一次,发生在 LLM 循环开始前。它是唯一一个可注入上下文的 hook:

return {"context": "Recalled memories:
- User likes Python"}

注入位置始终是用户消息,而不是系统提示,从而保留 prompt cache。

post_llm_call

每轮成功结束后触发一次。适合把对话同步到外部记忆系统、记录响应摘要或做后处理。

on_session_start

新会话第一次创建时触发一次。适合初始化会话级状态、预热缓存、记录会话开始。

on_session_end

每次 run_conversation() 结束时都会触发,无论成功、失败还是中断。适合刷盘、清理资源、记录持续时间。

on_session_finalize

当 CLI 或 网关 销毁当前活跃会话时触发,例如 /new、空闲回收或 CLI 退出。这是丢弃会话身份前最后一次刷状态的机会。

on_session_reset

当 网关 为某个聊天分配新的 session key 时触发,例如 /new/reset/clear。适合重建 session_id 相关缓存。

subagent_stop

每个 delegate_task 子智能体结束后触发一次。适合记录 orchestration 活动、计费、审计子任务结果。

Shell 钩子

你可以在 ~/.hermes/config.yamlhooks: 中声明脚本型 hooks。对应事件触发时,Hermes 会把它们作为子进程执行。这样无需编写 Python 插件,也能完成阻断、自动格式化、上下文注入等逻辑。

适合 Shell hooks 的场景包括:

  • 阻断工具调用:拒绝危险 terminal 命令
  • 在工具调用后运行脚本:自动格式化、触发 CI、记录日志
  • 向下一轮 LLM 注入上下文:例如追加 git status
  • 观察生命周期事件:例如子智能体结束时写日志

配置格式

hooks:
<event_name>:
- matcher: "<regex>"
command: "<shell command>"
timeout: <seconds>

hooks_auto_accept: false

JSON 协议

每次事件触发时,Hermes 会把一个 JSON payload 通过 stdin 传给脚本,并从 stdout 读取 JSON 响应。pre_tool_call 可返回阻断指令,pre_llm_call 可返回 {"context": "..."} 注入上下文。

同意模型

每个唯一 (event, command) 组合首次使用时都会提示用户批准,随后决策会保存在 ~/.hermes/shell-hooks-allowlist.json。如果是非 TTY 运行(gateway、cron、CI),需要通过 --accept-hooksHERMES_ACCEPT_HOOKS=1hooks_auto_accept: true 跳过交互确认。

hermes hooks CLI

CommandWhat it does
hermes hooks list列出已配置 hooks、matcher、timeout 和授权状态
hermes hooks test <event>用模拟 payload 测试 hooks
hermes hooks revoke <command>撤销某个命令的授权
hermes hooks doctor检查可执行位、allowlist、mtime 漂移、JSON 输出有效性等

安全性

Shell hooks 会以当前用户完整权限运行,因此应把 hooks: 视为高权限配置:

  • 只运行你自己写的或完全审查过的脚本
  • 最好把脚本集中放在 ~/.hermes/agent-hooks/
  • 拉取共享配置后先运行 hermes hooks doctor
  • 团队共用配置时,应像审查 CI 配置一样审查 hooks: 变更

顺序与优先级

Python plugin hooks 与 shell hooks 都会流经同一个 invoke_hook() 分发器。Python 插件先注册,shell hooks 后注册,因此若两者都在 pre_tool_call 中尝试阻断,Python 版本优先。