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更新了,才算真的醒了
相关推荐
特立独行的猫A2 小时前
用仓颉语言 cj-tauri 框架,五分钟给娃做了个鸿蒙形近字游戏
java·后端·python
码事漫谈5 小时前
我花了一周时间,看AI公司怎么"管"AI,结果越看越后背发凉
后端
爱学习的程序媛7 小时前
Python常用框架梳理
开发语言·后端·python·ai·web·后端框架·python框架
GISer_Jing7 小时前
Agent核心内容
后端·ai·langchain
budingxiaomoli8 小时前
Spring统一功能处理
java·后端·spring
某鹏9 小时前
网关选型:Go、Java、Graal 谁都不能完胜
后端
用户02478365309710 小时前
从屎山到防线:14 行状态迁移表,给任务系统装上防瞎跳闸门
后端
CQU_JIAKE10 小时前
11.13[体系结构】指标,五级流水线,八级流水线,虚实地址思考
后端
panbook12 小时前
从0到1实现一个分布式时序数据库(三):主从复制、故障检测与切换
后端
上线再说12 小时前
图片从 8.2MB 压到 296KB:我把小程序图片链路的账单拆了一遍
后端