OpenClaw Gateway 修复:如何清理过期的 Subagent 会话历史记录
——
OpenClaw Gateway 修复:如何清理过期的 Subagent 会话历史记录
一句话总结
OpenClaw 最新版本修复了 Gateway 模块中 subagent_announce 历史记录的水合污染问题,确保新建会话时不再混入过期的子代理上下文,提升 AI Agent 多轮对话的准确性。
—
问题背景:为什么需要这个修复?
在多 AI Agent 协作架构中,OpenClaw 的 Gateway 负责协调主代理与子代理(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_announce 是 OpenClaw 中子代理向主代理汇报任务完成状态的机制。当子代理执行完特定 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 配置最佳实践
---
相关阅读
---