代码讲解.md 2.3 KB

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 是一个字典:

HOOKS: dict[str, list[function]] = {
    "UserPromptSubmit": [],
    "PreToolUse": [],
    "PostToolUse": [],
    "Stop": []
}

每个 key 是一个生命周期事件,每个 value 是一组回调函数。

比如:

HOOKS["PreToolUse"] = [
    permission_hook,
    log_hook
]

意思是:每次工具执行前,依次运行权限检查和日志记录。


3. register_hook(event, callback)

作用:把某个函数挂到某个事件上。

register_hook("PreToolUse", permission_hook)

可以理解成:

工具执行前,请自动运行 permission_hook

4. trigger_hooks(event, *args)

作用:触发某个事件下的所有 Hook。

blocked = trigger_hooks("PreToolUse", block)

这里的 block 是模型返回的 tool_use

如果某个 Hook 返回了非空值,就表示它想拦截本次流程:

if result is not None:
    return result

所以 permission_hook() 可以通过返回字符串来阻止工具执行。


5. Agent Loop 中的变化

S03 是硬编码:

if not check_permission(block):
    continue

S04 改成:

blocked = trigger_hooks("PreToolUse", block)
if blocked:
    results.append(tool_result)
    continue

区别是:

Agent Loop 不再关心具体有哪些扩展逻辑
只负责在合适的生命周期点触发 Hook

6. 本节课堂重点

Hooks 让 Agent Harness 变得可扩展。

后面要加日志、权限、审计、上下文注入、输出过滤,都不需要把主循环越改越乱。