AI多Agent协作系统实战(四十九):它说唤醒了agent,agent却还在睡觉

派发日志:✅ 已即时唤醒小天处理任务 小天:zzz... 任务在inbox里躺了一整夜。

背景

任务派发成功后,系统会【立即唤醒】agent处理------这是三层唤醒架构的第一层:"即时唤醒"。设计很完美:

scss 复制代码
派发 → 写inbox → wake_agent() → openclaw agent --message "有新任务" → agent醒来读文件

日志也显示唤醒成功。但任务就是不动。

问题:唤醒"成功"了,任务没人处理

凌晨的统筹报告:

yaml 复制代码
📊 DEV-20260822-001: pending(已过248分钟------严重超时)
📊 小天(main): ❌ 无活跃session
📊 任务已投递到inbox------等待小天启动后处理

派发日志明明写着"已即时唤醒",agent却毫无反应。session一个都没有------agent压根没被叫起来过。

排查1:唤醒命令真的执行了吗?

wake_agent.py 的核心:

python 复制代码
subprocess.Popen(
    ['openclaw', 'agent', '--agent', openclaw_id, '--message', message],
    stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
    start_new_session=True
)
print(f"✅ 已即时唤醒{agent_name}处理任务", file=sys.stderr)

注意看------stdout和stderr全部 DEVNULL

Popen 只要成功【启动进程】就返回,进程内部的失败------比如openclaw读到错误配置、认证失败、模型报错------全部静默吞掉。然后打印"✅ 已即时唤醒"。

唤醒的"成功",是打印出来的。agent的醒来,才是真的。

排查2:openclaw读了什么配置?

容器里跑 openclaw agent 命令------它读 OPENCLAW_HOME 指定的配置。但 wake_agent 的子进程继承了运行它的进程的环境------那个进程(send_task.py)的环境里【没有 OPENCLAW_HOME】!

于是 openclaw 去读默认的 ~/.openclaw/------容器里根本没有这个目录(配置在 /vol1/1000/ai-team-collab/openclaw/)。读不到配置 → agent起不来 → 静默失败 → 打印"唤醒成功"。

排查3:还有个更隐蔽的------旧名判断

send_task.py 的唤醒段:

python 复制代码
if msg_type == "new_task" and to_agent in ["小虾", "小牛", "小白"]:
    ...
    wake_agent(to_agent, ...)

看到没------硬编码旧名! 员工改名后,to_agent 是"小天"------不在 ["小虾", "小牛", "小白"] 里------整个唤醒段根本不执行!

而且唤醒段里还引用了一个不存在的变量 _fname

python 复制代码
_wake_f = os.path.join(WS_DIR, 'claw-sync', 'inbox', _role, _fname)  # _role/_fname未定义!

NameError 被 try/except 捕获------打印一句"⚠️ 即时唤醒失败"------继续跑。唤醒悄悄死掉。

类比:闹钟响了,但响的是别人的闹钟

设了6点的闹钟叫醒自己去赶飞机。结果:闹钟响了(打印"已唤醒"),但响的是隔壁房间的闹钟(读错了配置),而且自己根本没设6点的闹钟(旧名判断没触发)------人没醒,飞机飞了。

三个独立的小故障,任何一个都足以让agent睡过站,三个叠加------必挂。

修复:让"唤醒"变成可验证的事实

python 复制代码
# ① 环境:OPENCLAW_HOME显式传入(容器/Windows探测)
_envw = os.environ.copy()
if os.path.isdir('/vol1/1000/ai-team-collab'):
    _envw['OPENCLAW_HOME'] = '/vol1/1000/ai-team-collab/openclaw'

# ② 角色判断动态化(改名不失效)
if msg_type == "new_task" and ROLE_MAP.get(to_agent) in ('main', 'xnew', 'xbai'):

# ③ 唤醒消息带inbox文件绝对路径(规范:wake消息必须指定具体文件)
wake_agent(to_agent, f'请读取文件 {inbox_path},按content中的步骤执行')

关键一条经验:唤醒的验证标准不是"命令发出去了",而是"agent的session开始活动了"。后来我们在task_monitor里加了session活跃度检测------唤醒后15分钟session没动静,就判定唤醒失败,走恢复流程。

经验总结

  1. DEVNULL 会吞掉所有真相------后台命令的stdout/stderr全丢弃,等于闭着眼开枪
  2. 子进程环境不是继承的"完整环境"------OPENCLAW_HOME这种关键变量,必须在调用处显式传入
  3. try/except 包裹唤醒段,等于给失败发了免死金牌------异常要打日志,不能静默
  4. 旧名硬编码是定时炸弹------改名需求一出现就炸
  5. "唤醒成功"要定义成可观测的:session mtime更新了,才算真的醒了
相关推荐
用户7813667114451 小时前
对象存储(RGW)架构详解
后端
Python私教1 小时前
软件开发报价为什么能差 3 倍:需求范围、验收标准和变更成本怎么算
后端·python·架构
苏三说技术1 小时前
为什么越来越多人用gRPC?
后端
MacroZheng1 小时前
程序员看文档神器,装上它,看Spring官方文档就一目了然了!
java·人工智能·后端
想风1 小时前
Claude Code 实用技巧工作坊 —— Boris Cherny
前端·后端·github
长栎1 小时前
Java 17 的模式匹配,正在杀死访问者模式
后端
风曳丷1 小时前
# 03|恶意文本如何一路摸到工具按钮
后端
2501_915918411 小时前
Rust 程序抓包解密,rustls 不认系统证书的几种办法
开发语言·后端·网络协议·ios·adb·https·rust
深漂的华哥1 小时前
Ruoyi-Vue-Plus(V5.6.2) 开发环境搭建
java·前端·spring boot·后端·spring·ruoyi