前言
笔者自己养小龙虾已有月余,烧了不少token,也亲眼见证了OpenClaw的快速迭代。
近期上线的OpenClaw 2026.3.7版本提出了一项非常重要的更新——上下文引擎(Context Engine),提供了可自由扩展的上下文管理能力,同时也使得OpenClaw拥有可召回的“长期记忆”(这里打引号是因为用户体感上如此,而技术本质上不完全如此)成为可能。本文先简单介绍Context Engine,然后简述Voltropy提出的无损上下文管理(LCM)机制,最后聊聊LCM的开源实现——lossless-claw插件的使用。
本文部分图表由MiniMax-M2.7-highspeed模型协助生成。
OpenClaw Context Engine
我们知道,在LLM驱动的Agent系统中,上下文窗口(Context Window)是非常核心的限制。尤其是对于OpenClaw这样long-running的Agent,如何高效管理上下文的同时保留关键信息,也是十分具有挑战性的。
Context Engine作为应对这个挑战的产物,它最主要的职责是对会话的生命周期做了严格的定义,共有以下9个方法:
-
bootstrap:见到新会话时,完成初始化操作,并可选择性地导入历史上下文; -
ingest:单条摄入消息,可选持久化; -
ingestBatch:批量摄入消息(即一个完整的会话轮次),可选持久化; -
afterTurn:会话轮次后处理,可以用于触发维护动作(如压缩,下文详述); -
assemble:核心方法,根据存储的现有会话数据,组装上下文信息并提供给LLM; -
compact:根据上下文窗口压缩上下文,创建摘要,节省后续token消耗; -
prepareSubagentSpawn/onSubagentEnded:子Agent启动 / 结束前置处理; -
dispose:会话结束,释放资源。
以框图表示上述生命周期,如下。
Session 开始
│
▼
┌─────────────┐
│ bootstrap │ ← 首次见到 session 时调用一次
└──────┬──────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ ingest / ingestBatch → 摄入消息并写入存储 │
└─────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ assemble → 返回消息给模型 → 模型响应 │
│ │ │
│ └── afterTurn → 可选维护操作 │
└─────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────┐
│ compact → 当上下文满或手动执行compact时 │
└─────────────────────────────────────────────────────┘
│
▼
子代理生命周期
│
├── prepareSubagentSpawn
└── onSubagentEnded
Session 结束
│
▼
┌─────────────┐
│ dispose │ ← 资源清理
└─────────────┘
OpenClaw也内置了一个原生的简单Context Engine实现,称为Legacy Engine。它对上述生命周期节点的实现方法是:
-
ingest:空操作,消息只是由原生的SessionManager组件管理; -
assemble:透传消息,只做一些历史消息整理、tool call整理、格式校验等,并根据当前token budget做截断; -
compact:滑动窗口风格的压缩消息,即当上下文超限时,对窗口外较旧的消息创建单一摘要(single summary),并将旧消息用单一摘要替代; -
afterTurn:空操作。
显然,Legacy Engine的设计和我们日常中常用的简单对话型Agent类似,上下文管理还是比较粗放的,无法完全避免遗忘旧信息。不过Context Engine的初衷就是可扩展、插件化的,那么我们当然可以通过更主动、更精细的上下文管理来获得更好的体验。接下来简要介绍一种方案:LCM(Lossless Context Management)。
LCM(Lossless Context Management)
LCM是Voltropy在今年2月通过<<LCM: Lossless Context Management>>论文提出的无损上下文管理方案。它能够非常自信地被命名为“无损”,主要是基于以下3点:
- 持久化每一条消息:对应
ingest阶段,所有消息都存储在数据库中,包括消息的原始结构(text、tool calls、tool results 等); - 用摘要替代原始消息:对应
compact和afterTurn阶段,当需要压缩时,借助LLM能力生成原始消息的摘要,保留语义信息,减少token数量; - 以有向无环图(DAG)结构组织摘要:对应
assemble阶段,多层次的摘要形成DAG,允许高效回溯和选择性展开。
LCM的核心数据结构就是分级管理摘要的DAG,简单的示意图如下。熟悉数据库原理的读者可以发现,这与LSM Tree的Compaction思路非常相似。
┌─────────────────┐
│ Leaf A │───────────────────────┐
│ (msg 1-10) │ │
└─────────────────┘ │
│ │
┌─────────────────┐ │
│ Leaf B │ |
│ (msg 11-20) │ │
└─────────────────┘ │
│ ▼
│ ┌─────────────────┐ ┌─────────────────┐
└──────────────────────►│ Condensed C │ │ Condensed E │
│ (A + B) │ │ (F + G) │
│ depth=1 │ │ depth=1 │
└─────────────────┘ └─────────────────┘
│ │
└────────┬──────────┘
▼
┌─────────────────┐
│ Condensed D │
│ (C + E) │
│ depth=2 │
└─────────────────┘
直接包含原始消息的节点称为叶子摘要(Leaf Summary)节点,由叶子摘要生成的更高层摘要称为浓缩摘要(Condensed Summary)节点,且节点都会记录所属会话ID、深度、内容、token数量等元信息。同时,对于会话过程中出现超过token阈值的大文件(如大段代码、大数据集等),LCM会仅存储指向该文件的指针,避免token耗尽。这样,在组装上下文信息提供给LLM时,通过在DAG上进行遍历,就可以兼顾最近消息与历史记录了。
那么LCM是如何执行压缩的呢?当最新的消息(称为fresh tail)的token数超过一定阈值时,早于fresh tail的消息就会被异步压缩成Leaf Summary,这个压缩阶段称为Leaf Pass,如下图所示。

随着对话轮次的增多,Leaf Summary的数量达到一定阈值时,使用概括性的prompt执行Condensation Pass,生成第一层Condensed Summary,以此类推,再生成更高层级的Condensed Summary。

如果需要召回历史上下文,启动一个子Agent,从最高层级开始遍历DAG,找到元信息最符合用户query的节点,将其展开(i.e. 查询持久化存储获得摘要或原文)即可。子Agent会有一个token上限设置(图中是4000),避免浪费。

上面的截图都来自LCM官方网站,读者也可自行访问。
生成摘要这里还有一个不可避免的问题,即:如何保证摘要真的能够节省token,也就是避免摘要token数比原文token数更多这种情况?LCM的解决方法是三级跳(Three-Level Escalation):
- 使用标准摘要prompt进行摘要,目标token数控制在2000内,如果输出token比输入token多,则升级;
- 使用更严格的摘要prompt和更低的temperature值进行摘要,要求只保留关键事实,目标token数比输入token数降低50%,如果仍然无法达成,则升级;
- 强制截断到一定数量的token(如512或1024),作为摘要内容。
最后简单看看LCM的开源实现,即OpenClaw上的lossless-claw插件如何使用。
lossless-claw
lossless-claw的官方库地址在这里,昨天刚刚发布最新的0.4.0版本。安装它只需要一条命令:
openclaw plugins install @martian-engineering/lossless-claw
然后修改openclaw.json文件,将contextEngine修改为lossless-claw。
{
"plugins": {
"slots": {
"contextEngine": "lossless-claw"
}
}
}
在plugins.entries条目下,新增一个lossless-claw配置。
{
"plugins": {
"entries": {
"lossless-claw": {
"enabled": true,
"config": {
"freshTailCount": 32,
"contextThreshold": 0.75,
"incrementalMaxDepth": -1,
"summaryProvider": "openai",
"summaryModel": "deepseek/deepseek-chat"
}
}
}
}
}
刚开始使用时,部分需要关注的配置是:
-
freshTailCount:不做压缩的fresh tail消息数量,默认为32; -
contextThreshold:上下文窗口阈值,当token量超过此比例时,开始触发压缩,默认为0.75; -
incrementalMaxDepth:最大的压缩层级,0表示只做Leaf Pass,-1表示不限制层级; -
summaryProvider/summaryModel:用于做摘要的模型提供商和名称,可以设置为和OpenClaw不同的模型,以节省成本; -
leafTargetTokens:Leaf Summary的目标token数,默认1200; -
condensedTargetTokens:Condensed Summary的目标token数,默认2000; -
maxExpandTokens:子Agent执行摘要展开的token数上限,默认4000。
配置完成后,重启OpenClaw Gateway,lossless-claw插件即生效。

lossless-claw使用SQLite数据库维护DAG和其他数据结构,在OpenClaw的工作目录下,可以看到对应的db和wal文件。

关于lossless-claw的部分设计细节,可以参考官方文档,此处不再赘述。