权限、日志、指标和输入增强如果全写进 Agent Loop,循环很快会充满条件分支。Hooks 把横切逻辑挂到稳定的生命周期节点,让主循环继续只负责模型调用、工具分发和消息回传。

四个生命周期节点

Hook触发位置典型用途
UserPromptSubmit用户输入进入循环记录;可作为输入扩展点
PreToolUsehandler 执行前权限、参数策略、阻断
PostToolUsehandler 返回后日志、指标、大输出提醒
Stop本轮没有工具调用审计、完成判断、继续执行

s03 的权限判断可注册为 PreToolUse,让当前和未来工具走同一个拦截点。

这里的四类事件只是课程中的最小抽象,不是 Claude Code 产品的完整 Hooks API。当前示例的 UserPromptSubmit callback 只打印记录,CLI 也没有使用返回值改写用户输入;“补充上下文”是可扩展方向,不是这份代码已经实现的行为。

返回值必须有明确语义

课程按注册顺序调用 callback,第一个非空结果会短路:

  • PreToolUse 的非空结果阻止工具并作为结果返回;
  • Stop 的非空结果注入对话并继续;
  • UserPromptSubmitPostToolUse 当前主要用于观察,其返回值不控制流程。

教学约定足够简洁,生产系统则应为每类事件定义稳定类型,避免一个字符串同时承担修改、拒绝和继续提示。

顺序本身就是行为

短路意味着注册顺序影响结果。可靠系统通常会区分:全部执行的观察者、按序更新的变换器、任一拒绝即可阻断的守卫,以及按优先级决定结束或继续的 Stop 决策器。

这些顺序应成为显式契约和测试,而不是依赖导入顺序。

异常不能悄悄改变安全策略

权限 Hook 抛异常后若默认继续,会形成 fail-open。安全守卫应默认拒绝并记录错误;日志类 Hook 可以隔离失败,避免遥测故障拖垮 Agent。

Hook 还应有超时和重入边界。阻塞 callback 会阻塞模型循环;Hook 内再次触发同类事件可能递归。

Hooks 提供扩展点,但与宿主同进程的 callback 通常拥有同等代码权限,不能隔离不可信插件,也不能替代权限系统。

建议覆盖的测试

  • 四类 Hook 在正确生命周期触发;
  • PreToolUse 阻止后 handler 未执行;
  • Stop 注入消息后循环继续;
  • 注册顺序和短路行为稳定;
  • 安全 Hook 异常不会放行;
  • 观察 Hook 失败不破坏工具协议。

小结

Hooks 让权限、审计、提示增强和停止判断接入同一循环。可靠 Hook 系统需要明确事件类型、执行顺序、短路语义、异常策略与可信边界。

参考资料