乐于分享
好东西不私藏

OpenClaw 修复子代理任务通知丢失:3 种重试机制详解

OpenClaw 修复子代理任务通知丢失:3 种重试机制详解


OpenClaw 修复子代理任务通知丢失:3 种重试机制详解

OpenClaw 最新版本修复了一个关键的生产环境问题——子代理(Subagent)完成状态通知丢失。当你的 AI Agent 长时间运行后,子任务完成的消息可能无法正确触达父代理,导致整个工作流卡住。本文将详细拆解这个修复方案的技术原理,以及如何在实际项目中避免类似问题。


问题背景:为什么子代理通知会”消失”

OpenClaw 的分布式 Agent 架构中,父代理经常需要委派子代理执行耗时任务。正常情况下,子代理完成后会通过 transcript-wait 机制通知父代理恢复执行。但在特定条件下,这个通知会失效:

  • 请求运行状态过期(stale):父代理的运行上下文因超时或资源回收进入过期状态
  • 直接完成不可见:子代理的直接完成信号无法被父代理接收
  • Transcript 等待机制不支持:某些场景下 transcript-wait 唤醒会失败

这些问题共同导致了一个症状:子代理实际已完成,但父代理永远在等待,形成”僵尸任务”。


核心修复方案:三重保障机制

本次提交 04eac15 引入了三层递进式修复策略,确保通知必达。

第一层:无 Transcript 等待的重试机制

当检测到 transcript-wait 唤醒不被支持时,系统会降级到无等待模式重试:

// 伪代码示意:重试逻辑的核心判断
async function retryCompletionAnnounce(subagentRun, requesterRun) {
  try {
    // 第一次尝试:标准 transcript-wait 唤醒
    await wakeWithTranscriptWait(subagentRun);
  } catch (error) {
    if (error.code === 'UNSUPPORTED_TRANSCRIPT_WAIT') {
      // 降级策略:移除 transcript 依赖,直接重试
      console.log('[OpenClaw] Transcript-wait 不支持,切换到直接唤醒模式');
      await wakeWithoutTranscriptWait(subagentRun);
    }
    throw error;
  }
}

关键点:这种降级不会丢失完成状态,只是改变了通知的传输方式。

第二层:强制消息工具交接

当检测到请求者运行已过期(requester run is stale)时,系统会强制触发 message-tool handoff

// 强制交接的触发条件
if (isRequesterRunStale(requesterRun) && isDirectCompletionInvisible(subagentRun)) {
  // 强制使用消息工具通道完成交接
  forceMessageToolHandoff({
    from: subagentRun,
    to: requesterRun.parentContext,
    payload: subagentRun.completionResult,
    forcetrue  // 绕过常规可见性检查
  });
}

message-tool handoff 是 OpenClaw 的可靠消息通道,即使直接完成路径断裂,也能保证状态传递。

第三层:回归测试覆盖

修复方案包含完整的回归测试,模拟”过期唤醒序列”:

# OpenClaw 修复子代理任务通知丢失:3 种重试机制详解
npm test -- --grep "stale subagent completion announce"

# 预期输出:
# ✓ should recover when transcript-wait is unsupported
# ✓ should force handoff when requester run is stale
# ✓ should handle invisible direct completion gracefully

实际应用场景

场景一:长时间数据分析任务

// 父代理委派耗时数据分析
const analysisRun = await openclaw.subagents.create({
  task"分析 10GB 日志数据",
  timeout"2h",  // 长时间运行
  onCompletion"notifyParent"
});

// 修复前:如果分析在 2 小时后完成,父代理可能已过期,通知丢失
// 修复后:自动重试 + 强制交接,确保通知必达

场景二:嵌套子代理链

父代理 → 子代理 A → 子代理 B → 子代理 C
   ↑___________________________________|
              (完成通知)

在深层嵌套中,任何中间层的过期都可能导致通知链断裂。新机制在每个节点都有重试保障。


升级建议

检查当前版本

# 查看 OpenClaw 版本
openclaw --version

# 确保 >= 包含 04eac15 提交的版本

配置监控告警

建议为子代理完成通知延迟添加监控:

// 监控配置示例
openclaw.monitoring.configure({
  alerts: [{
    name"subagent-completion-delay",
    condition"completion_announce_time > 30s",
    severity"warning"
  }]
});

常见问题 FAQ

Q1: 这个修复会影响现有子代理的性能吗?

不会。 重试机制仅在检测到失败条件时触发,正常路径的性能开销为零。强制交接也是异步执行,不会阻塞子代理的完成流程。

Q2: 如何知道我的项目是否遇到了这个问题?

检查日志中是否有以下模式:

[WARN] Subagent completed but wake failed: transcript-wait unsupported
[ERROR] Requester run stale, completion announce dropped

如果出现这些日志,说明已触发修复机制,建议升级到最新版本获得完整保护。

Q3: “stale run” 的判定标准是什么?

默认情况下,运行状态在 30 分钟无活动 后标记为 stale。可通过环境变量调整:

export OPENCLAW_RUN_STALE_THRESHOLD_MS=1800000  # 30分钟

Q4: 这个修复与 Issue #83699 有什么关系?

这是该 Issue 的完整修复方案。#83699 报告了生产环境中子代理通知随机丢失的现象,经过诊断确定为上述三重故障条件的组合触发。

Q5: 如果 message-tool handoff 也失败了怎么办?

OpenClaw 会进入 持久化重试队列,将完成状态写入可靠存储,并在系统恢复后重新投递。这是最后的保障层,确保至少一次交付语义。


总结

本次修复通过 降级重试、强制交接、回归测试 三层机制,彻底解决了子代理完成通知的可靠性问题。对于运行长时间任务或复杂 Agent 链的用户,建议立即升级到包含此修复的版本。

下一步行动

  1. 升级 OpenClaw 到最新版本
  2. 审查现有子代理的超时配置
  3. 配置完成通知延迟监控

相关阅读

  • OpenClaw 子代理最佳实践[1]
  • AI Agent 消息模式设计指南[2]
  • OpenClaw 监控与告警配置[3]

参考来源

  • GitHub Commit: 04eac15[4]
  • GitHub Issue #83699[5]
  • OpenClaw 官方文档[6]
  • 阅读原文:OpenClaw 教学小站[7]

引用链接

[1]OpenClaw 子代理最佳实践: URL

[2]AI Agent 消息模式设计指南: URL

[3]OpenClaw 监控与告警配置: URL

[4]GitHub Commit: 04eac15: https://github.com/openclaw/openclaw/commit/04eac15f43d5d5d272f56ef4c343c9260a0d3d64

[5]GitHub Issue #83699: https://github.com/openclaw/openclaw/issues/83699

[6]OpenClaw 官方文档: URL

[7]阅读原文:OpenClaw 教学小站: https://61wp.com