Agent Zero 用户无响应处理协议:解析 fw.msg_timeout 框架消息与自动续跑机制
【免费下载链接】agent-zeroAgent Zero AI framework项目地址: https://gitcode.com/GitHub_Trending/ag/agent-zero
导读
在 Agent Zero AI 框架的自主运行循环中,用户不可能始终在线回复每一条中间消息,因此框架内置了一套「用户无响应(timeout)」处理协议。本文以框架消息 prompts/fw.msg_timeout.md 为切入点,逐条解读这套协议的行为约定与标准 JSON 响应格式,并结合 agent.py、helpers/files.py 等核心源码,剖析框架消息(framework message)的加载、占位符渲染与 JSON 模板处理机制,以及 nudge、wait 等相邻功能如何构成完整的"等待-唤醒-续跑"闭环。读完本文,你将掌握 Agent Zero 中框架消息的设计哲学、task_done 工具的正确用法,以及如何在自定义 Agent Profile 中覆写这类行为提示。
一、fw.msg_timeout 是什么:框架消息在 Agent Zero 中的角色
Agent Zero 的prompts/目录下存放着大量fw.*.md文件(如fw.msg_repeat.md、fw.msg_misformat.md、fw.msg_unusable_response_limit.md、fw.msg_truncated.md、fw.msg_summary.md、fw.user_message.md等)。这些文件统称为框架消息(framework messages),它们是框架自身在特定运行时事件发生时,注入到 Agent 对话历史或系统提示中的标准指令模板,用于引导 Agent 以统一、可预期的行为响应各类边界情况。
fw.msg_timeout.md正是其中之一,它描述的场景是:Agent 向用户发送了一条消息(或发起了需要用户确认的交互),但用户在预期时间内没有响应。此时框架将这条消息内容注入对话,告知 Agent 应当如何处理"等待落空"的局面,避免 Agent 陷入死等或空转。
全文仅有 17 行,属于高度凝练的行为协议:
# User is not responding to your message. If you have a task in progress, continue on your own. If you don't have a task, use the task_done tool with text argument. # Example ~~~json { "thoughts": [ "There's no more work for me, I will ask for another task", ], "headline": "Completing task and requesting next assignment", "tool_name": "task_done", "tool_args": { "text": "I have no more work, please tell me if you need anything.", } } ~~~从源码结构看,这类提示文件由 Agent 的 read_prompt 方法 读取,作为框架与 LLM 之间的"带外约定",其设计意图是:把"用户缺席"视为正常运行时状态,而不是异常——Agent 应当自主决策、继续推进,而不是挂起等待。
二、协议逐条解读:两条规则与一个前提
2.1 前提:用户不再响应
消息开头User is not responding to your message.是触发前提的声明,向 Agent 明确当前状态:上一条发往用户的消息没有得到回应。在 Agent Zero 中,用户与 Agent 的交互可以来自多种渠道——终端输入、WebUI、nudge API、连接器插件 等——而框架消息所约定的行为对所有渠道一致。
2.2 规则一:有任务在身,继续自主执行
If you have a task in progress, continue on your own.是这条协议的第一优先规则。Agent Zero 的定位是自主运行的 Agent 框架,其主循环(见 agent.py 中monologue循环)设计为"尽可能无人值守地推进任务"。因此当用户未响应时:
- 如果 Agent 手头仍有未完成的子任务、未执行完的工具调用序列或明确的待办目标,它应当继续执行,而不是停下来等待;
- 这与框架中 nudge 的语义互补——nudge 用于"用户主动唤醒",而 timeout 消息用于"用户缺席时自主续跑"。
2.3 规则二:无任务在身,用 task_done 收尾
If you don't have a task, use the task_done tool with text argument.是第二优先规则,也是本协议的关键动作指令:
- task_done是一个收尾型工具,用于声明"当前没有更多工作可做"并请求新的任务分配;
- 它必须携带text 参数,用以说明当前状态(例如"我没有更多工作,如需帮助请告诉我");
- 与 response 工具(
break_loop=True结束主循环并把消息交付给用户)不同,task_done 的语义是面向任务队列的完结——Agent 主动让出执行权,等待下一个任务输入。
这两条规则构成一个完备的分支:有活干活,没活交差,保证 Agent 在用户缺席的任何时刻都能落在确定的状态机节点上。
三、标准响应格式:JSON 消息模板的实战示例
协议附带一个完整的示例,展示了 Agent 在收到该框架消息后应当输出的标准 JSON 响应。该格式与 Agent Zero 全框架统一的"thoughts / headline / tool_name / tool_args"四段式工具调用契约一致(可对照 prompts/agent.system.tools_vision.md 中vision_load工具的示例验证同一结构):
{ "thoughts": [ "There's no more work for me, I will ask for another task", ], "headline": "Completing task and requesting next assignment", "tool_name": "task_done", "tool_args": { "text": "I have no more work, please tell me if you need anything.", } }字段含义与实战要点:
| 字段 | 含义 | 本场景写法建议 |
|---|---|---|
thoughts | 内部推理过程(数组,可多条) | 说明"无剩余工作、主动请求新任务"的推理 |
headline | 面向日志/UI 的一句话摘要 | 如 "Completing task and requesting next assignment" |
tool_name | 要调用的工具名 | 本场景固定为task_done |
tool_args | 工具参数 | 必须包含text字符串参数 |
需要说明的是:task_done是框架消息层约定暴露的收尾动作名,其语义与框架中break_loop机制(工具返回Response(break_loop=True)后结束当前消息循环,见 tools/response.py)同属"终止当前执行"的范畴,但前者强调请求下一任务,后者强调把最终答复交付用户。
四、源码级解析:框架消息是如何被加载与渲染的
要理解fw.msg_timeout.md如何真正生效,需要追查它的加载链路。核心入口是 agent.py 的read_prompt方法:
@extension.extensible def read_prompt(self, file: str, **kwargs) -> str: dirs = subagents.get_paths(self, "prompts") prompt = files.read_prompt_file(file, _directories=dirs, _agent=self, **kwargs) if files.is_full_json_template(prompt): prompt = files.remove_code_fences(prompt) return prompt要点有三:
- 可扩展(extensible):
read_prompt带有@extension.extensible装饰器,意味着插件体系可以在读取前后注入处理逻辑,框架消息的行为可以被插件定制; - 目录解析:通过 subagents.get_paths 得到当前 Agent 的 prompts 搜索目录列表(包含内置
prompts/与 Agent Profile 的prompts/),再由 helpers/files.py 的 read_prompt_file 完成文件查找与读取——这允许 Profile 用同名文件覆写核心框架消息; - JSON 模板识别:若文件整体是一个 JSON 模板(
is_full_json_template),读取后会剥离代码围栏(remove_code_fences),使模板可以被直接解析。
在 read_prompt_file 内部,还依次完成了占位符替换(replace_placeholders_text,将{{variable}}替换为 kwargs 传入值)、条件求值(evaluate_text_conditions)以及include 指令处理(process_includes,支持§§include(<file>)复用其他模板片段)。这意味着fw.msg_timeout.md这类消息模板天然支持参数化——例如类似 fw.wait_complete.md 中Wait complete. Reached {{target_time}}.的动态注入方式。
由此可以推断:fw.msg_timeout.md若在未来需要携带更多上下文(如等待时长、剩余子任务列表),框架无需改动代码,只需在模板中新增{{placeholder}}并在调用处传参即可,这正是框架消息机制的扩展性设计。
五、超时场景的完整生态:nudge、wait 与 intervention
fw.msg_timeout.md并非孤立存在,它与 Agent Zero 中一系列"等待与唤醒"机制共同构成闭环:
5.1 nudge:用户主动唤醒 Agent
当 Agent 因等待用户而暂停时,用户可通过多种途径唤醒它:
- 后端 API api/nudge.py 调用
context.nudge(); - 集成命令
/nudge(见 helpers/integration_commands.py 中的_handle_nudge); - 连接器插件端点 plugins/_a0_connector/api/v1/nudge.py。
其核心实现位于 agent.py 的 nudge 方法:
@extension.extensible def nudge(self): self.kill_process() self.paused = False self.task = self.communicate(UserMessage(self.agent0.read_prompt("fw.msg_nudge.md"))) return self.task它先终止旧进程、解除暂停,再向 Agent 注入 fw.msg_nudge.md(内容为{"system_message": "Nudged - continue"}),从而让 Agent 继续。nudge 与 fw.msg_timeout 的方向正好相反:nudge 是"用户回来了,继续干",timeout 消息是"用户没回来,自己看着办"。
5.2 wait 工具与 managed_wait:受管理的等待
wait 工具 允许 Agent 主动暂停直到指定时长或时间戳(支持seconds/minutes/hours/days/until参数,对应工具说明见 prompts/agent.system.tool.wait.md)。其底层 managed_wait 在等待循环中周期性调用agent.handle_intervention(),以响应暂停/干预,并会在干预导致等待中断时自动延长目标时间,保证实际等待时长不缩水。等待结束后,Agent 收到 fw.wait_complete.md(Wait complete. Reached {{target_time}}.)通知继续执行。
这条链路说明:Agent Zero 中的"等用户"是有管理、可打断、可恢复的,而fw.msg_timeout.md处理的正是"等不到用户"的最终落点。
5.3 intervention 与 paused:执行循环的中断机制
Agent 的执行循环中大量调用 handle_intervention,它检查self.intervention字段;当用户消息到达且进程存活时(communicate 方法),消息会以广播形式写入当前 Agent 及其上级 Agent 的intervention,随后通过InterventionException打断正在进行的 LLM 调用与工具执行。等待用户与用户缺席,正是围绕这套中断机制的两侧行为。
六、相邻框架消息速览:timeout 在框架消息家族中的定位
将fw.msg_timeout.md与其同族消息对比,可以更清晰地定位它在框架运行策略中的角色:
| 框架消息 | 触发场景 | 核心指令 |
|---|---|---|
| fw.msg_timeout.md | 用户未响应消息 | 有任务继续,无任务用task_done请求新任务 |
| fw.msg_nudge.md | 用户主动唤醒暂停的 Agent | Nudged - continue,恢复执行 |
| fw.msg_repeat.md | Agent 输出了与历史完全相同的响应 | "You have sent the same message again. You have to do something else!" |
| fw.msg_misformat.md | Agent 消息不符合 JSON 格式规范 | 严格按系统提示的 JSON 消息格式重发 |
| fw.msg_unusable_response_limit.md | 连续 N 次不可用响应触达上限 | 停止以防止继续产生 API 费用,等待新消息重试 |
| fw.msg_truncated.md | 长文本超出阈值 | 用{{length}} CHARACTERS REMOVED TO SAVE SPACE占位符截断(配合 helpers/messages.py 的 truncate_text) |
| fw.msg_summary.md | 上下文压缩 | 以 JSON 形式输出messages_summary(配合 helpers/history.py 的compress_attention) |
| fw.notify_user.notification_sent.md | notify_user 工具成功发送通知 | 告知 Agent 通知已送达用户(工具实现见 tools/notify_user.py) |
可以看出,fw.msg_timeout属于"运行时状态提示类"框架消息,与fw.msg_nudge配对出现:一个管"唤醒续跑",一个管"缺席自治",共同保证 Agent 在异步人机协作中永不僵死。
七、实践指南:如何观察与定制这套行为
7.1 观察触发路径
fw.msg_timeout.md所在的 prompts/ 目录是框架消息的权威来源;当前仓库的搜索结果显示,该文件目前由框架运行时按需注入(fw.*前缀消息统一通过 read_prompt / parse_prompt 加载)。开发者可在自己的集成中,于等待用户回复的超时分支里注入该消息内容,从而让 Agent 遵循"有任务继续、无任务 task_done"的协议。
7.2 在自定义 Agent Profile 中覆写
根据 agents/AGENTS.md 的说明,每个 Agent Profile(如 agents/default、agents/developer 等)拥有自己的prompts/目录,且 Profile 内的同名提示文件会按目录搜索顺序优先于核心 prompts 被加载(这与read_prompt_file的目录列表机制一致)。因此,若希望某个 Profile 对"用户无响应"采取不同的措辞或补充额外约束(例如"继续执行前先汇报当前进度"),只需在对应 Profile 的prompts/下放置一个同名fw.msg_timeout.md即可,无需改动核心代码。参考 agents/_example 了解 Profile 的标准目录布局。
7.3 注意点
task_done的text参数是必填的,示例中给出的文案"I have no more work, please tell me if you need anything."可直接复用或按需改写;- 响应必须保持标准的四段式 JSON 结构,否则会触发 fw.msg_misformat.md 所描述的格式纠错流程;
- 本文所涉行为均为框架消息层面的协议约定,具体触发时机取决于上层调用方(CLI、WebUI、连接器)如何检测"用户超时",仓库中可参考 helpers/timed_input.py 的
timeout_input(基于inputimeout实现带超时的输入)理解 CLI 场景下的超时来源。
结语
fw.msg_timeout.md虽不足 20 行,却是 Agent Zero 自主运行哲学的一个缩影:框架不要求用户全程在线,而是通过约定的框架消息,把"用户缺席"转化为 Agent 的确定性决策分支——有任务则自主续跑,无任务则通过 task_done 主动让位。理解它,也就理解了 Agent Zero 框架消息机制(模板化、可覆写、可参数化、可扩展)的基本运转方式,以及它在整个"等待-唤醒-续跑"生态中的位置。
【免费下载链接】agent-zeroAgent Zero AI framework项目地址: https://gitcode.com/GitHub_Trending/ag/agent-zero
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考