01Bread Agent · 第 7 章
总进度 7 / 33事件钩子系统
可以把同一段确认代码复制到 write file ,但以后修改提示语或确认规则,就得同时改好几处。工具越多,这类重复越难维护。
2026-09-28约 45 分钟410 行代码难度 ★★★
如果想获取全套课程资料,请关注微信公众号 「AI面包君」,回复 「课程资料」 即可领取。
1. 让多个工具共用确认逻辑
ch03 我们在 run_shell 函数里直接写了一段:
print(f"[!] Agent 想执行命令: {command}")
if input("y/N? ") != "y":
return "用户拒绝执行此命令。"
# 真正执行...
现在问题来了:如果 write_file 也要询问怎么办?
可以把同一段确认代码复制到 write_file,但以后修改提示语或确认规则,就得同时改好几处。工具越多,这类重复越难维护。
这里把确认逻辑单独取出来,放到工具执行前统一调用。这个预留给外部函数的位置,就叫钩子(hook)。
Agent 工作流程:
用户输入 → on_user_msg → ... → before_tool → 真正执行 → after_tool → ... → on_assistant
│ │
可以否决执行 可以读结果/改结果
程序在指定位置发出事件,事先注册的回调函数就会依次执行。例如:
- 注册一个
before_tool回调,做权限确认 - 再注册一个
before_tool回调,做日志 - 再注册一个
on_assistant回调,统计 token 用量
只要 Agent 已经在合适的位置发出事件,就能通过注册回调增加相应行为,不必每次改动工具函数。若要观察新的执行阶段,仍需要先在 Agent 中补上事件。
<!-- bread-visual:start -->
<!-- bread-visual:end -->图解: before_tool 可以拦截;after_tool 观察执行结果。 本章 after_tool 只触发回调;并未使用其返回值改写工具结果。
2. 跑起来
cd ch06_hooks
python main.py
启动消息:
Bread Agent · v6(钩子化)
注:write_file 和 run_shell 是危险工具,调用前会询问。
注意:这次 write_file 也被拦截了——因为我们把它加进了"危险工具列表",钩子统一处理。
试这一组:
你 > 把 hello 写到 a.txt
AI > 我来写入文件。
[切换到非流式模式获取工具调用...]
[hook:log] 即将调用 write_file 参数={'path': 'a.txt', 'content': 'hello'}
[!] Agent 想调用 write_file({'path': 'a.txt', 'content': 'hello'})
[!] 允许执行吗?(y/N): N
[blocked] 用户拒绝执行 write_file。
AI > 好的,已取消写入。如果你想换个文件名或路径,告诉我即可。
[hook:log] 模型回答了 28 个字符

观察 3 件事:
[hook:log]—— 日志钩子自动打印了工具调用[!]—— 权限钩子触发了 y/N 询问- 按 n 后查看回复,确认模型收到了拒绝原因,实际工具没有执行
<!-- bread-practice:start -->
试读到这里 · 后续内容已封存
关注公众号,继续把这章学完
在「AI面包君」发送关键词「学习AI」拿到口令。验证一次,这个浏览器就能继续阅读全部课程。