Agent Zero 中 notify_user 工具深度解析:Agent 如何向用户发送带优先级的实时通知
【免费下载链接】agent-zeroAgent Zero AI framework项目地址: https://gitcode.com/GitHub_Trending/ag/agent-zero
导读
notify_user是 Agent Zero AI 框架中一个职责单一但功能关键的 Agent 工具:它允许运行中的 Agent 在不结束当前任务循环(break_loop=False)的前提下,向用户推送一条「带外(out-of-band)」通知。本文以 tools/notify_user.py.dox.md 为骨架,结合 tools/notify_user.py 实现、helpers/notification.py 通知管理器、prompts/agent.system.tool.notify_user.md 工具指令以及相关 API 与测试,完整讲解它的参数契约、类型/优先级体系、运行流程、底层实现与 WebUI 联动方式。读完本文,你将掌握如何调用、校验、扩展与验证这一通知通道,并理解它与helpers.tool.Tool/Response框架的集成契约。
一、工具定位与设计意图
1.1 职责边界:out-of-band 通知
根据 DOX 文档(tools/notify_user.py.dox.md)的定义,notify_user模块的职责是:
Own the
notify_user.pyagent tool — This module sends a user-facing notification from the agent.
翻译成工程语言就是:Agent 主动向用户发出可见通知。它的关键设计点是「不打断主线任务」——工具执行完毕后返回的Response中break_loop=False,因此 Agent 会继续执行当前的思考-行动循环,而通知本身则通过独立通道送达用户界面。
1.2 适用场景
从 prompts/agent.system.tool.notify_user.md 的指令看,它的推荐用法包括:
- 后台任务进行中的进度提示(
progress类型); - 需要用户注意的告警(
warning/error类型); - 任务完成的成功提示(
success类型); - 通用备忘/提示(
info类型 + 普通优先级)。
同时指令明确约束了使用边界:「use for progress or alerts, not as the final answer」——通知不能替代最终答复,最终答复应使用response工具。
1.3 与项目其他模块的关系
从源码依赖看,NotifyUserTool只依赖三个区域:agent(获取AgentContext)、helpers.notification(通知枚举与管理器)、helpers.tool(Tool基类与Response)。这种扁平目录结构下,notify_user.py与其 DOX 文件notify_user.py.dox.md保持同步维护(DOX 文档明确要求「Keep this file-level DOX profile synchronized withnotify_user.py」)。
二、调用契约:参数、类型与优先级
2.1 参数总览
notify_user的调用参数在 prompts/agent.system.tool.notify_user.md 中被正式化,并在 tools/notify_user.py 中实现:
notify_user args: `message`, optional `title`, `detail`, `type`, `priority`, `timeout`对应 tools/notify_user.py 中execute()的参数解析逻辑:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
message | str | 空(必填) | 通知正文;为空则返回错误「Message is required」 |
title | str | 空 | 通知标题 |
detail | str | 空 | 详细内容,在NotificationItem中作为可展开的 HTML 内容 |
type | str | "info" | 通知类型,见 2.2 |
priority | str/int | 20(HIGH) | 优先级,见 2.3 |
timeout | str/int | 30 | 通知展示时长(秒),Agent 发出的通知使用更长的展示时间 |
注意工具默认的priority是NotificationPriority.HIGH(值为 20)、timeout是 30 秒,源码注释解释了原因:「by default, agents should notify with high priority」「agent's notifications should have longer timeouts」——Agent 主动推送的通知往往需要用户立即注意到,因此默认采用高优先级与较长驻留时间。
2.2 NotificationType:五种通知类型
类型枚举定义在 helpers/notification.py:
class NotificationType(Enum): INFO = "info" SUCCESS = "success" WARNING = "warning" ERROR = "error" PROGRESS = "progress"工具指令中的语义约定(prompts/agent.system.tool.notify_user.md):
info:普通备忘/提示;普通提示应使用type: "info"+priority: 10;success:仅用于已完成任务的成功消息,不可当作通用备注使用;warning/error:告警与错误;progress:进行中的任务进度提示。
在execute()中,字符串类型的type会被强制转换为NotificationType枚举;若传入非法值(如type: "critical"),会抛出ValueError,工具捕获后返回Response(message=f"Invalid notification type: {notification_type}", break_loop=False)——错误信息直接回传模型,便于 Agent 自我纠错后重试。
2.3 NotificationPriority:两级优先级
class NotificationPriority(Enum): NORMAL = 10 HIGH = 20工具指令中明确给模型写出数值语义:「priority values:20high urgency,10normal urgency; omit for high」(见 prompts/agent.system.tool.notify_user.md)。也就是说,省略priority即等于高优先级,只有普通提示才需要显式传priority: 10。非法优先级同样会被校验并返回Invalid notification priority错误。
2.4 参数校验顺序
从 tools/notify_user.py 源码可以看到严格的校验顺序:
- 校验
type是否合法(NotificationType(notification_type)); - 校验
priority是否合法(NotificationPriority(priority)); - 校验
message是否为空。
任一校验失败都会以break_loop=False的Response返回,不会中断 Agent 主循环,也不会创建任何通知——这保证了失败的调用是"可恢复的"而非"破坏性的"。
三、运行流程:从工具调用到通知落库
3.1 完整调用链
一次notify_user调用的完整链路如下:
- Agent 模型按工具指令构造
tool_name: "notify_user"的调用,携带message、title、detail、type、priority、timeout参数; - 框架实例化
NotifyUserTool(继承 helpers/tool.py 中的Tool抽象基类),调用await tool.execute(**kwargs); execute()解析并校验参数后,调用AgentContext.get_notification_manager().add_notification(...)写入通知;- 返回
Response(message=self.agent.read_prompt("fw.notify_user.notification_sent.md"), break_loop=False),其中message读取自 prompts/fw.notify_user.notification_sent.md(内容为 "The notification has been sent to the user."); - 框架层的
Tool.after_execution()将工具结果写入对话历史(hist_add_tool_result),Agent 继续执行后续任务。
3.2 NotificationManager 的全局单例
AgentContext.get_notification_manager()是一个类级惰性单例(见 agent.py):
@classmethod def get_notification_manager(cls): if cls._notification_manager is None: from helpers.notification import NotificationManager cls._notification_manager = NotificationManager() return cls._notification_managerNotificationManager(helpers/notification.py)内部维护:
notifications: list[NotificationItem]——通知列表;updates: list[int]——增量更新序号队列(供 WebUI 轮询/推送差异);guid——每次clear_all()都会更换的版本标识;max_notifications——容量上限,默认 100 条,超出时通过_enforce_limit()淘汰最旧通知并重排序号。
3.3 add_notification:创建与更新
add_notification(helpers/notification.py)的行为有两个分支:
- 新通知:构造
NotificationItem并追加到列表,记录updates,随后_enforce_limit()控制容量; - 更新已有通知:当传入
id且列表中存在相同id的通知时,会原地更新其type、priority、title、message、detail、timestamp、display_time、group,并将read重置为False——这是 WebUI 端"同一条通知持续刷新进度"能力的底层支撑(比如progress类型通知反复推送同id即可原地更新,而不是堆积多条)。
无论新建还是更新,最后都会调用mark_dirty_all(reason="notification.NotificationManager.add_notification")(来自 helpers/state_monitor_integration.py),把变更同步给状态监视器,保证多端 UI 感知到通知状态变化。
NotificationItem(helpers/notification.py)是一个 dataclass,__post_init__中自动生成uuid4形式的id,并保证type字段始终是NotificationType枚举;其output()方法把通知序列化为 WebUI 可消费的字典(含no、id、type、priority、title、message、detail、timestamp、display_time、read、group)。
四、面向开发者的扩展与集成
4.1 非工具场景:send_notification 静态方法
除 Agent 工具外,系统其他模块也可通过NotificationManager.send_notification(...)静态方法直接发通知(helpers/notification.py)。仓库内实际调用点包括:
- api/projects.py(项目相关事件通知);
- helpers/settings.py(设置变更通知);
- helpers/plugins.py(插件生命周期通知);
- extensions/python/user_message_ui/_10_update_check.py(更新检查通知)。
这一设计让「通知」成为系统级能力:无论是 Agent 工具、API 端点还是后台扩展,都能复用同一条通知管道。
4.2 HTTP API 侧:创建、历史与已读
WebUI 通过三个 API 端点与通知系统交互:
- 创建:api/notification_create.py 的
NotificationCreate接收type、priority、message、title、detail、display_time、group、id,其中display_time默认 3 秒、负数或非数字回退到 3 秒;与工具不同,该 API 端点的priority默认是NotificationPriority.NORMAL(普通),因为人工创建的通知不需要默认高优先级; - 历史:api/notifications_history.py 通过
output_all()返回全部通知、当前guid与数量,供历史弹窗使用; - 已读:api/notifications_mark_read.py 支持按
notification_ids批量标记已读(mark_read_by_ids)或mark_all: true一键全读(mark_all_read)。
4.3 前端消费与通知分组
NotificationItem中的group字段用于关联通知分组,detail字段可承载 HTML 可展开内容。WebUI 侧通过guid识别通知列表版本、通过updates增量序列做差异化渲染,避免整表刷新。这些字段与工具参数一一对应,开发者可以直接通过notify_user传入detail(HTML)来展示富文本细节。
五、验证与测试:如何确保契约不被破坏
DOX 文档(tools/notify_user.py.dox.md)明确要求:工具参数、输出形态、break_loop行为、干预处理、提示指令或副作用一旦变更,必须同步更新 DOX 并运行相关测试。
与notify_user直接相关的验证集中在 tests/test_tool_action_contracts.py:
test_notify_user_prompt_documents_numeric_priority_values(第 797 行起)直接读取 prompts/agent.system.tool.notify_user.md,断言提示词中写明了「priority values:20high urgency,10normal urgency」——这是工具提示词与底层枚举数值契约一致性的回归测试,防止模型提示与实际实现脱节;- 同一测试文件还验证了工具提示词禁止「顶层 multi 批量工具」等框架约定(
test_tool_prompts_prevent_top_level_multi_tool),确保notify_user这类工具按单一工具契约暴露。
该测试文件采用「stub 化依赖 +asyncio.run直驱」的方式验证工具行为,是了解本项目工具层测试写法的良好范例。
六、常见问题与注意事项
- message 必填:调用时若省略
message,工具返回Message is required且不产生任何通知。title、detail均可省略。 - type/priority 大小写与合法性:
type必须是五种枚举值之一(info/success/warning/error/progress);priority必须可转换为10或20。非法值返回明确错误信息,Agent 可据此修正重试。 - 不要用通知代替最终答复:工具指令明确要求通知仅用于进度或告警;任务收尾应使用
response工具给出最终答案。 - success 类型要克制:
success只用于"已完成任务的成功消息",通用备注请用info+priority: 10。 - 容量上限:通知管理器默认最多保留 100 条,超出会淘汰最旧记录;如需长期保留通知内容,应依赖历史 API 或其他持久化方案,而非让通知堆积。
七、总结
notify_user是 Agent Zero 中"Agent → 用户"带外通信的标准化通道,其设计体现了三个关键工程决策:通知与主循环解耦(break_loop=False)、参数契约显式化(枚举校验 + 数值优先级提示词)、系统级复用(同一个NotificationManager同时服务 Agent 工具、HTTP API 与后台扩展)。通过 tools/notify_user.py、helpers/notification.py、prompts/agent.system.tool.notify_user.md 与 tests/test_tool_action_contracts.py 的相互印证,可以完整还原这条通知管道的实现全貌——对于希望在 Agent Zero 中实现进度上报、告警推送或任务完成提示的开发者而言,notify_user是最直接、最受框架约束保护的入口。
【免费下载链接】agent-zeroAgent Zero AI framework项目地址: https://gitcode.com/GitHub_Trending/ag/agent-zero
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考