# S04 Hooks 代码讲解 这一节只讲相对 S03 新增的内容: **把权限检查、日志、上下文注入、结束摘要从 Agent Loop 里拆出去,挂到生命周期事件上。** --- ## 1. 本节新增内容 - `HOOKS`:事件名到回调函数列表的映射。 - `register_hook()`:注册 Hook。 - `trigger_hooks()`:触发某类 Hook。 - `permission_hook()`:把 S03 的权限检查迁移成 Hook。 - `log_hook()`:工具调用前打印日志。 - `large_output_hook()`:工具执行后检查大输出。 - `context_inject_hook()`:用户输入提交前触发。 - `summary_hook()`:Agent 停止时触发。 --- ## 2. HOOKS 数据结构 `HOOKS` 是一个字典: ```python HOOKS: dict[str, list[function]] = { "UserPromptSubmit": [], "PreToolUse": [], "PostToolUse": [], "Stop": [] } ``` 每个 key 是一个生命周期事件,每个 value 是一组回调函数。 比如: ```python HOOKS["PreToolUse"] = [ permission_hook, log_hook ] ``` 意思是:每次工具执行前,依次运行权限检查和日志记录。 --- ## 3. `register_hook(event, callback)` 作用:把某个函数挂到某个事件上。 ```python register_hook("PreToolUse", permission_hook) ``` 可以理解成: ```python 工具执行前,请自动运行 permission_hook ``` --- ## 4. `trigger_hooks(event, *args)` 作用:触发某个事件下的所有 Hook。 ```python blocked = trigger_hooks("PreToolUse", block) ``` 这里的 `block` 是模型返回的 `tool_use`。 如果某个 Hook 返回了非空值,就表示它想拦截本次流程: ```python if result is not None: return result ``` 所以 `permission_hook()` 可以通过返回字符串来阻止工具执行。 --- ## 5. Agent Loop 中的变化 S03 是硬编码: ```python if not check_permission(block): continue ``` S04 改成: ```python blocked = trigger_hooks("PreToolUse", block) if blocked: results.append(tool_result) continue ``` 区别是: ```python Agent Loop 不再关心具体有哪些扩展逻辑 只负责在合适的生命周期点触发 Hook ``` --- ## 6. 本节课堂重点 Hooks 让 Agent Harness 变得可扩展。 后面要加日志、权限、审计、上下文注入、输出过滤,都不需要把主循环越改越乱。