最近有个 OpenClaw 核心 maintainer 说了一句很扎心的话:

“your OpenClaw agents work perfectly for 20 minutes, then it silently forgets your instructions and goes rogue.”

我第一次看到这句话的时候,笑了一下,然后有点难受。

因为这不是在说某个人写的 Agent 有 bug,这是在说:这个问题是系统性的,而且它是”静默”发生的——Agent 不会报错,不会提示你它忘了什么,它只是悄悄开始按自己的理解行动。


先说清楚,这不是”记忆模块”的问题

这里有个很容易混淆的地方,值得单独说一下。

很多人看到”上下文管理”,第一反应是:

“哦,就是那个 MEMORY.md?跨 session 的记忆那层?”

不是的。

OpenClaw 的记忆其实分两层,这两层干的是完全不同的事:

第一层:长期记忆(之前就有,这次没动)

1
2
3
MEMORY.md、memory/YYYY-MM-DD.md
跨 session 持久化,重启还在
解决的问题:我上周说了什么

第二层:上下文管理(这次更新的核心)

1
2
3
4
当前这个 session 里,token 窗口怎么组织
旧消息超出窗口后怎么压缩
压缩后的内容怎么还原
解决的问题:这个 session 里 20 分钟前我说了什么

那个”20 分钟后叛变”的问题,出在第二层。


滑动窗口:一个”有效但有毒”的方案

在 2026.3.7 之前,OpenClaw 处理长对话的方式是滑动窗口压缩

对话太长了 → 把老消息总结成摘要 → 摘要顶替原文 → 腾出空间给新消息

这个方案在大部分情况下是够用的。但它有一个致命的问题:压缩是有损的,而且是不可逆的

“请用 TypeScript 写”被摘要成”用户要写代码”。
“这个函数不允许有副作用”被摘要成”用户对代码质量有要求”。

Agent 从那一刻起,就在靠一个失真的摘要工作。

更麻烦的是,这个失真是渐进的——不是某一刻突然全忘了,而是每次压缩都丢一点,丢到某个临界点,Agent 的行为开始偏,然后你发现你在跟一个已经不太记得你要什么的东西对话。

这就是那个 maintainer 说的”goes rogue”。


2026.3.7 做了什么:把上下文管理从硬编码变成接口

很多人看这次更新,把它理解成”做了一个更好的压缩算法”。

这个理解是错的,而且错得有点离谱。

这次更新做的事是:把整个上下文管理逻辑从核心里挖出来,抽成一个可插拔的接口

1
2
3
4
5
6
7
8
之前:
OpenClaw Core 里写死了"如何组织上下文"
→ 想换策略?改源码,或者 fork

现在:
contextEngine = 一个插件槽(slot)
→ 接口定义好,实现可以换
→ 没配置插件?用原来的行为,零变化

接口提供了 7 个生命周期钩子,从引擎启动、消息到来、组装上下文、触发压缩,一直到子 Agent 派生和回收——整条链路全部开放。

其中最核心的一个钩子是 assemble(budget)

每次模型调用之前,OpenClaw 把 token 预算交给你,问你:这次调用,给模型看什么?

你返回什么,模型就看到什么。这一行为之前是系统决定的,现在是你的插件决定的。


lossless-claw:第一个旗舰实现

接口开放之后,第一个值得认真看的实现就是 lossless-claw,来自 Martian Engineering 的 Josh Lehman。

思路来自学术论文《LCM: Lossless Context Management》,但落地非常工程化。

核心逻辑是:

  1. 每条消息永久存入 SQLite,原文不删
  2. 旧消息分块,用 LLM 生成摘要
  3. 摘要聚合成 DAG(有向无环图),形成层级摘要树
  4. 每轮对话:高层摘要 + 最近原文 → 组成上下文
  5. Agent 有工具可以主动钻回原文lcm_greplcm_expand

DAG 的层级结构长这样:

1
2
3
4
5
6
7
Level 2 摘要(高层)
├── Level 1 摘要(中层)
│ ├── 消息块 1-20 的摘要
│ └── 消息块 21-40 的摘要(←→ 原始消息保留在 SQLite)
└── Level 1 摘要
├── 消息块 41-60 的摘要
└── 消息块 61-80 的摘要

原始消息永远不删,摘要从下往上聚合,越高层越抽象。模型每次看到的是顶层摘要加上最近的原始消息。而 Agent 随时可以用工具从任意摘要节点钻回原文——没有悬空的摘要,没有找不回去的细节

关键在第 5 点:Agent 可以主动回溯

当它遇到需要确认早期指令的场景,不是依赖一个可能失真的摘要,而是真的能查回去。这把上下文管理从”被动截断”升级成”主动检索”。

实测数据:OOLONG benchmark(专门测长上下文理解能力)里,lossless-claw 得分 74.8,Claude Code 70.3,而且上下文越长,差距越大。

Josh Lehman 本人跑了一周之后说的评价是:

“说它表现很好,都算是低估了。”


降温一下:这不是魔法

工程界出现过太多”这次彻底解决了”的说法。

接口/插件/钩子这套思想不新鲜。Eclipse 插件体系、OSGi、SOA,20 年前就这么玩了。在 AI 时代,它依然有效,但也不会因为加了 AI 就变成魔法。

有几个问题还值得观察:

  • SQLite + DAG 的方案在大规模并发子 Agent 场景下,一致性怎么保证?
  • 摘要本身是 LLM 生成的,摘要的质量依赖你用的模型,这个成本有没有算进去?
  • lcm_expand 这类工具是暴露给 Agent 主动调用的,但 Agent 知道什么时候该用吗?

这些不是否定,而是说:方向是对的,但这只是起点


真正值得关注的是这个

从工程视角来看,这次更新的本质不是”做了一个更好的记忆系统”,而是:

OpenClaw 承认了”上下文管理”是 Agent 架构中一个需要被认真设计的独立关注点。

之前这层逻辑被埋在核心里,用户只能接受,无法定制,也没有标准接口去衡量它做得好不好。

现在接口在这里了,意味着:

  • 不同场景可以有不同引擎(RAG 引擎、任务图引擎、省 token 引擎……)
  • 上下文质量可以被独立测试和优化
  • 生态可以在这一层上真正生长

这件事本身,比 lossless-claw 更重要。


最后想说的

如果你现在还在用原来的 OpenClaw,不装任何 context engine 插件,行为不会有任何变化——这次更新对你完全透明。

但如果你在跑长时间、多轮次的 Agent 任务,比如持续几小时的 coding session,或者需要跨越几十轮对话保持一致行为的场景,那这层终于可以认真设计了。

那个”20 分钟后叛变”的问题,有解了。

至少,现在你有机会自己决定它怎么解。


下一个问题可能是:当上下文管理可以被完全自定义之后,Agent 的”人格一致性”该怎么保证?这是 memory 和 context 都解决不了的另一层问题。