Hooks:Agent 的生命线监控器
本章摘要:
Hooks 是 Agent 的"确定性约束"——挂在生命周期节点上的回调,让某些规则无论模型怎么想都必须执行。多个 Hook 并行触发,最严格决策获胜(deny > ask > allow)——一个 hook 拒绝即全局拒绝,安全底线不被宽松 hook 绕过。
Agent Loop 中,LLM 自主决定下一步做什么、调用什么工具、传什么参数。用户能影响的只有初始提示和中间的权限弹窗。这意味着:
- 拦截操作靠提示词约束(软约束)
- 审批操作靠手动弹窗(低效率)
- 事后追溯靠手动翻日志
Hooks 在软件领域是一套很成熟的概念,指软件生命周期循环的一系列"钩子"——外部代码可以挂在"钩子"上,参与到生命周期中。在 Agent 领域,Hooks 让用户自由介入 Agent Loop 的不同节点。
Hooks 的设计哲学
挂在循环上,不写进循环里。
Agent Loop 本身保持稳定——它只负责"思考 → 调用 → 观察"的核心循环。Hooks 是挂在这个循环外部的回调,在特定生命周期事件发生时被触发。循环体只管调用触发函数,具体逻辑全在 hook 回调里。扩展行为不需要修改循环本身——这是开闭原则的直接体现。
Hooks 在系统中的定位
核心定位:Hooks 提供确定性控制。
在一个由 LLM 驱动的系统中,模型的每次决策都带有概率性。Hooks 提供了一条确定性路径:无论模型怎么想,某些规则必须被执行。"概率性推理 + 确定性约束"的组合,是构建可信 Agent 系统的关键模式。
如果把 Agent Loop 比作一个自动驾驶系统:模型是"驾驶员",工具是"方向盘和油门",上下文是"导航地图",Hooks 则是"行车记录仪 + 电子围栏 + 自动报警器"——它不驾驶车辆,但确保驾驶行为符合规则,记录每一步操作,并在偏离时发出警报。
Hooks 的全貌:一张生命周期地图
Hooks 系统覆盖 Agent 运行的完整生命周期,按功能自然形成几个层次:
会话层:SessionStart → 用户交互 → SessionEnd
↓
用户交互层:UserPromptSubmit → Agent 处理 → Stop
↓
工具调用层:PreToolUse → 工具执行 → PostToolUse
↓
子代理层:SubagentStart → 子代理执行 → SubagentStop
↓
压缩层:PreCompact → 上下文压缩 → PostCompact设计要点:能否拦截。 一些事件可以拦截(hook 可阻止当前操作),一些只能观察(操作已发生、不可逆)。比如 PreToolUse 可拦截工具执行,PostToolUse 只能记录已发生的结果。
Hook 类型:两大类
按"是否需要 LLM 推理"分两类:
| 类别 | 包含类型 | 特点 | 典型场景 |
|---|---|---|---|
| 快速回调 | Command、HTTP | 毫秒级,外部进程执行 | 格式检查、文件操作、CI 集成 |
| LLM 推理 | Prompt、Agent | 秒到分钟级,调用 LLM 判断 | 内容审核、复杂审批、深度分析 |
Command 和 HTTP 通过进程间通信(stdin/stdout + 退出码)传决策;Prompt 和 Agent 通过 LLM 调用传决策。两种方式最终都被统一为相同的内部结果。
执行管线
当一个生命周期事件触发时,Hooks 系统按以下步骤运行:
事件发生
↓
1. 构造输入:收集事件上下文
↓
2. 匹配过滤:遍历注册的 hook 配置
↓
3. 并行执行:所有匹配的 hook 同时启动
↓
4. 收集结果:等待所有 hook 完成
↓
5. 执行最终决策:按最严决策合并几个关键设计决策:
并行执行——多个 hook 同时运行,总延迟取决于最慢的那个,而非延迟之和。
最严格决策获胜——三个 hook 中两个返回 allow、一个返回 deny,最终结果是 deny。优先级为 deny > ask > allow。
默认放行——hook 崩溃、输出无效 JSON、或因超时被杀掉时,操作默认继续。一个 hook 的故障不应阻塞正常工作流。但显式 deny 依然生效——只有"没说话"才放行。
通信协议(概念性)
hook 通过约定的输入/输出格式与 Agent 通讯。Agent 在事件发生时把上下文传过去,hook 给出三种响应之一:
- 放行:操作继续
- 阻止:操作中断,理由反馈给模型
- 修改输入:极少数场景下,hook 还能改写工具调用的参数
协议细节因 hook 类型而异(Command 用 stdin/stdout + 退出码,HTTP 用 POST 请求,Prompt/Agent 用 LLM 调用)。但对外的决策语义是统一的——无论哪种 hook,最终都给出"放行/阻止"两种结果之一。
安全纵深
hook 是一种可执行代码,来源必须受信。
Hook 以用户权限执行,恶意 hook 理论上可做任何事。系统设计了纵深防御模型:
- 工作区信任检查:包含 hook 配置的仓库需要先被确认为受信
- 托管模式:企业管理员可限制系统只执行企业 IT 策略配置的 hook
- 全局禁用开关:紧急情况下可一键关闭所有 hook
贯穿始终的安全不变式:hook 的 allow 不能覆盖其他配置的 deny。hook 可以收紧安全策略,但不能放松——这是权限系统的铁律。
本章要点
- Hooks 是 Agent 的确定性约束——挂在生命周期上的回调
- 两大类:快速回调(Command/HTTP)和LLM 推理(Prompt/Agent)
- 并行执行 + 最严格决策获胜——一个 hook 拒绝即全局拒绝
- 默认放行——hook 故障不应阻塞工作流
- hook 是可执行代码——来源必须受信
- "概率性推理 + 确定性约束"是构建可信 Agent 系统的关键模式