Hooks — 挂在循环上,不写进循环里

"挂在循环上, 不写进循环里" — hook 在工具执行前后注入扩展逻辑。

Github 原文:shareAI-lab/learn-claude-code

问题

经过前三章,现在我们的 Agent 有权限检查了。但每次加一个新检查,比如”记录每次 bash 调用”、“操作后自动 git add”,都要修改 agent_loop 函数。

也就是说每次做 check permission,AI 都要做一次复杂的判断,还是在循环里面,稍微长一点你的这里代码就会巨长无比:

def agent_loop(messages):
    while True:
        # ... LLM call ...
        for block in response.content:
            if block.type != "tool_use":
                continue
            log_to_file(block)          # 加一行
            check_permission(block)     # 加一行
            notify_slack(block)         # 又加一行
            output = execute(block)
            auto_git_add(block)         # 再加一行
            # ... 很快循环就认不出来了

你想扩展的是 Agent 的行为,但你改的却是循环本身。循环应该是一个稳定的核心,扩展应该挂在外面。

解决方案

Hooks — 挂在循环上,不写进循环里

我们保留了之前的那个循环和权限逻辑完全保留。唯一的变动是把 check_permission() 从循环体内移到了 hook 上,循环不再直接调用任何检查函数,改为 trigger_hooks("PreToolUse", block),由注册表决定跑什么。

什么是 Hook

这里补充一下什么是 Hook,要不然这里的理解会有困难。上面那张原文配图默认大家是技术人员,因此理解 Hook 这个基本的东西。

首先我们讲一下,到底什么是 Hook。我们不扯什么专业的说法,用设计师能理解的语言就是:Hook 就是个需要条件要求的Slot。上图中引入的 hook 有 2 个,第一个是 PreToolUse ,就是说在工具调用前,然后图里没表达清楚,之前循环里面的 check permission 其实就被放在这里了,也就是说这个东西还在,只不过之前在循环流程中,现在被装在了这个叫做 Hook,并且是在工具调用前这个条件下才会触发的东西里。

Hooks — 挂在循环上,不写进循环里