OpenClaw Gateway 修复:如何清理过期的 Subagent 会话历史记录

——

OpenClaw Gateway 修复:如何清理过期的 Subagent 会话历史记录

一句话总结

OpenClaw 最新版本修复了 Gateway 模块中 subagent_announce 历史记录的水合污染问题,确保新建会话时不再混入过期的子代理上下文,提升 AI Agent 多轮对话的准确性。

问题背景:为什么需要这个修复?

在多 AI Agent 协作架构中,OpenClawGateway 负责协调主代理与子代理(subagent)之间的通信。当子代理完成特定任务后,会通过 subagent_announce 机制向主代理汇报结果。

然而,在特定场景下会出现历史记录污染

| 场景 | 问题描述 |
|:—|:—|
| 会话重建 | 用户执行 /new 新建会话时,旧的 subagent_announce 消息被错误地水合到新会话 |
| 时间戳错位 | 过期的 announce/user 回复对被投影到 chat.history,导致上下文混乱 |
| 边界泄漏 | 限制窗口(limit-window)边缘的过期助手回复未被正确过滤 |

这些问题会导致 AI Agent 产生”幻觉”——基于错误的上下文生成回复。

核心修复方案详解

1. 会话起始时间过滤机制

修复的核心是在 chat.history 投影之前,过滤掉会话开始前的 announce/user 回复对。

// 伪代码:过滤逻辑的核心思想
function filterStaleAnnounces(history, sessionStartTime) {
  return history.filter(record => {
    // 关键条件:相邻的助手回复必须携带会话前时间戳才允许删除
    const hasPreSessionTimestamp = record.assistantReply?.timestamp < sessionStartTime;
    const isAnnouncePair = record.type === 'subagent_announce' || record.type === 'user_reply';
    
    // 仅当满足严格条件时才过滤
    if (isAnnouncePair && hasPreSessionTimestamp) {
      return false; // 丢弃过期记录
    }
    return true;
  });
}

关键约束:必须要求相邻的助手回复携带预会话时间戳(pre-session timestamp)才能执行删除,避免误删有效记录。

2. 超大转录占位符的时间戳保留

对于超出处理限制的转录内容,系统会使用占位符替代。修复确保这些占位符保留原始记录的时间戳,便于后续追溯和调试。

// 保留时间戳的占位符生成
function createOversizedPlaceholder(originalRecord) {
  return {
    type: 'placeholder',
    content: '[转录内容超出限制]',
    // 关键:保留原始时间戳用于过滤判断
    originalTimestamp: originalRecord.timestamp,
    size: originalRecord.content.length
  };
}

3. Claude CLI 历史导入的兼容性

修复后的过滤逻辑在 Claude CLI 历史导入流程之后执行,并支持导入数据的时间戳/文本回退机制:

验证命令:运行 Gateway 相关测试套件

node scripts/run-vitest.mjs \ src/gateway/server-methods/server-methods.test.ts \ src/gateway/session-utils.fs.test.ts \ src/gateway/session-history-state.test.ts \ src/gateway/cli-session-history.test.ts \ src/gateway/server.chat.gateway-server-chat-b.test.ts

结果:11 个文件,463 个测试全部通过 ✅

4. 边界上下文的安全读取

为避免限制窗口边缘泄漏过期助手回复,系统采用仅多读一条本地转录消息的策略作为边界上下文:

[有效消息 N-1]  ← 多读一条作为边界
[有效消息 N]    ← 窗口起始边界
...
[消息 N+limit]  ← 窗口结束边界

这种设计确保窗口边缘的上下文完整性,同时严格控制过期内容的混入。

---

验证与质量保证

本次修复经过多层验证:

| 验证层级 | 命令/工具 | 结果 |
|:---|:---|:---|
| 代码规范 | git diff --check | 无冲突标记 |
| 单元测试 | Vitest 测试套件(463 项) | 全部通过 |
| 自动审查 | autoreview --mode branch | 无有效发现项 |

完整的自动审查命令

/Users/steipete/Projects/agent-scripts/skills/autoreview/scripts/autoreview \ --mode branch \ --base origin/main

输出:clean, no accepted/actionable findings

---

FAQ:常见问题解答

Q1: 什么是 subagent_announce,它在 OpenClaw 中起什么作用?

A: subagent_announceOpenClaw 中子代理向主代理汇报任务完成状态的机制。当子代理执行完特定 skill 后,通过该消息类型将结果、日志或中间状态传递给 Gateway,由 Gateway 决定是否整合到主会话上下文中。

Q2: 这个修复会影响现有的会话历史数据吗?

A: 不会。该修复仅作用于新建会话/new)时的历史水合过程,不会修改已持久化的历史记录。对于现有会话,时间戳过滤机制会正确识别并保留有效内容。

Q3: 如何判断我的 OpenClaw 版本是否包含此修复?

A: 检查您的 Gateway 模块版本是否包含 commit 982e888

cd /path/to/openclaw
git log --oneline --grep="drop stale subagent announce" --all

或查看特定提交

git log --oneline | grep 982e888

Q4: Claude CLI 历史导入与此修复有什么关系?

A: Claude CLI 导出的历史记录可能包含不完整的时间戳信息。修复确保过滤逻辑在导入流程之后执行,并为缺失时间戳的记录提供文本内容回退,避免导入数据导致的过滤误判。

Q5: 作为开发者,我需要调整我的 skill 实现吗?

A: 通常不需要。此修复是 Gateway 层的内部优化,对 skill 开发接口无影响。但如果您的 skill 直接操作 chat.history 或实现自定义的历史管理逻辑,建议审查是否遵循相同的时间戳过滤原则。

---

总结与下一步

本次修复解决了 OpenClaw Gateway 中关键的会话历史污染问题,核心要点:

1. 严格过滤 — 基于会话起始时间和预会话时间戳双重验证
2. 兼容导入 — 支持 Claude CLI 历史导入的特殊场景
3. 边界安全 — 限制窗口边缘的上下文泄漏风险

建议行动

  • 升级至包含此修复的 OpenClaw 版本
  • 审查您的多 Agent 协作流程,确认无自定义历史操作冲突
  • 关注 OpenClaw 文档 获取 Gateway 配置最佳实践

---

相关阅读

---

参考来源