Appearance
使用插件引擎可自定义 OpenClaw 的上下文组装、压缩和子 Agent 生命周期行为。检查当前引擎运行 openclaw doctor,安装插件后需在 plugins.slots.contextEngine 中设置插件 ID 并重启 Gateway。切换引擎时现有会话历史不变,新引擎接管后续运行。若插件引擎注册失败,OpenClaw 不会自动回退,须修复插件或将 slot 改回 "legacy"。
OpenClaw Context Engine 配置与切换指南
Context Engine 控制 OpenClaw 每次运行模型时如何构建上下文:包含哪些消息、如何总结旧历史、以及如何跨子 Agent 边界管理上下文。OpenClaw 内置 legacy 引擎并默认使用它——大多数用户无需改动。仅当需要不同的组装、压缩或跨会话召回行为时,才安装并选择一个插件引擎。
快速开始
1. 检查当前使用的引擎
bash
openclaw doctor
# 或直接查看配置:
cat ~/.openclaw/openclaw.json | jq '.plugins.slots.contextEngine'2. 安装插件引擎
Context Engine 插件的安装方式与其他 OpenClaw 插件相同。
从 npm 安装
```bash
openclaw plugins install @martian-engineering/lossless-claw
```
从本地路径安装(开发用)
```bash
openclaw plugins install -l ./my-context-engine
```
3. 启用并选择该引擎
json5
// openclaw.json
{
plugins: {
slots: {
contextEngine: "lossless-claw", // 必须与插件注册的引擎 ID 匹配
},
entries: {
"lossless-claw": {
enabled: true,
// 插件专用配置(参见插件文档)
},
},
},
}安装并配置后重启 Gateway。
4. 切回 legacy 引擎(可选)
将 contextEngine 设为 "legacy"(或直接删除该键,默认就是 "legacy")。
工作原理
每次 OpenClaw 运行模型提示时,Context Engine 会参与四个生命周期节点:
1. Ingest(摄入)
新消息加入会话时调用。引擎可将该消息存储或索引到自己的数据存储中。
2. Assemble(组装)
每次模型运行前调用。引擎返回一组有序消息(以及可选的 `systemPromptAddition`),确保在 token 预算内。
3. Compact(压缩)
上下文窗口已满,或用户执行 `/compact` 时调用。引擎对旧历史进行摘要以释放空间。
4. After turn(轮次后)
运行完成后调用。引擎可持久化状态、触发后台压缩或更新索引。
对于非 ACP 的 Codex harness,OpenClaw 通过将组装的上下文投射到 Codex 开发者指令和当前轮次提示中来应用相同的生命周期。Codex 仍拥有其原生的线程历史和原生压缩器。
子 Agent 生命周期(可选)
OpenClaw 调用两个可选的子 Agent 生命周期钩子:
prepareSubagentSpawn method
在子运行启动前准备共享上下文状态。接收父/子会话键、contextMode(isolated 或 fork)、可用的 transcript ID/文件以及可选 TTL。如果它返回一个回滚句柄,OpenClaw 会在准备成功后子生成失败时调用它。
onSubagentEnded method
子 Agent 会话完成或被清理时执行清理操作。
系统提示追加
assemble 方法可以返回一个 systemPromptAddition 字符串。OpenClaw 会将该字符串预置到本次运行的系统提示之前。这让引擎可以注入动态的召回引导、检索说明或上下文感知提示,而无需依赖静态工作区文件。
Legacy 引擎
内置的 legacy 引擎保留了 OpenClaw 的原始行为:
- Ingest:空操作(会话管理器直接处理消息持久化)。
- Assemble:透传(运行时现有的 sanitize → validate → limit 流水线处理上下文组装)。
- Compact:委托给内置的摘要式压缩,对旧消息生成一条摘要,保留近期消息完整。
- After turn:空操作。
Legacy 引擎不注册工具,也不提供 systemPromptAddition。
当未设置 plugins.slots.contextEngine(或设为 "legacy")时,自动使用此引擎。
插件引擎
插件可通过插件 API 注册 Context Engine:
ts
import { buildMemorySystemPromptAddition } from "openclaw/plugin-sdk/core";
export default function register(api) {
api.registerContextEngine("my-engine", (ctx) => ({
info: {
id: "my-engine",
name: "My Context Engine",
ownsCompaction: true,
},
async ingest({ sessionId, message, isHeartbeat }) {
// 将消息存入你的数据存储
return { ingested: true };
},
async assemble({ sessionId, messages, tokenBudget, availableTools, citationsMode }) {
// 返回符合预算的消息
return {
messages: buildContext(messages, tokenBudget),
estimatedTokens: countTokens(messages),
systemPromptAddition: buildMemorySystemPromptAddition({
availableTools: availableTools ?? new Set(),
citationsMode,
}),
};
},
async compact({ sessionId, force }) {
// 摘要旧上下文
return { ok: true, compacted: true };
},
}));
}工厂函数 ctx 包含可选的 config、agentDir 和 workspaceDir 值,以便插件在第一个生命周期钩子运行之前初始化每个 Agent 或每个工作区的状态。
然后在配置中启用:
json5
{
plugins: {
slots: {
contextEngine: "my-engine",
},
entries: {
"my-engine": {
enabled: true,
},
},
},
}ContextEngine 接口
必填成员:
| 成员 | 类型 | 用途 |
|---|---|---|
info | 属性 | 引擎 ID、名称、版本,以及是否拥有压缩 |
ingest(params) | 方法 | 存储单条消息 |
assemble(params) | 方法 | 为模型运行构建上下文(返回 AssembleResult) |
compact(params) | 方法 | 摘要/压缩上下文 |
assemble 返回的 AssembleResult 包含:
messages Message[] (必填)
发送给模型的有序消息列表。
estimatedTokens number (必填)
引擎对组装上下文 token 总数的估算。OpenClaw 用此值进行压缩阈值判断和诊断报告。
systemPromptAddition string
追加到系统提示之前的内容。
promptAuthority
控制运行程序使用哪个 token 估算进行预占溢出预检查。默认为 "assembled",表示仅检查组装提示的估算——适用于返回窗口化自包含上下文的引擎。仅当您的组装视图可能隐藏底层转录中的溢出风险时,才设置为 "preassembly_may_overflow";此时运行程序会取组装估算和预组装(非窗口化)会话历史估算的最大值,以决定是否进行预占压缩。无论哪种方式,您返回的消息仍然是模型看到的——promptAuthority 只影响预检查。
compact 返回一个 CompactResult。当压缩轮换了活跃转录时,result.sessionId 和 result.sessionFile 标识下一次重试或轮次必须使用的继承会话。
可选成员:
| 成员 | 类型 | 用途 |
|---|---|---|
bootstrap(params) | 方法 | 初始化引擎的会话状态。首次遇到某个会话时调用一次(例如导入历史)。 |
ingestBatch(params) | 方法 | 以批量方式摄入一个完整轮次。运行完成后调用,传入该轮次所有消息。 |
afterTurn(params) | 方法 | 运行后的生命周期工作(持久化状态、触发后台压缩)。 |
prepareSubagentSpawn(params) | 方法 | 为子会话准备共享状态。 |
onSubagentEnded(params) | 方法 | 子 Agent 结束后清理资源。 |
dispose() | 方法 | 释放资源。Gateway 关闭或插件重载时调用,不是按会话调用。 |
ownsCompaction
ownsCompaction 控制 Pi 内置的运行中自动压缩是否对该次运行保持启用:
ownsCompaction: true
引擎拥有压缩行为。OpenClaw 禁用 Pi 内置的自动压缩,引擎的 `compact()` 实现负责处理 `/compact`、溢出恢复压缩,以及它在 `afterTurn()` 中希望执行的主动压缩。OpenClaw 仍可能运行预提示溢出保护;当它预测完整转录会溢出时,恢复路径会在提交下一个提示前调用活跃引擎的 `compact()`。
ownsCompaction: false 或未设置
Pi 内置的自动压缩在提示执行过程中可能仍会运行,但活跃引擎的 `compact()` 方法仍然负责处理 `/compact` 和溢出恢复。
WARNING
ownsCompaction: false 不意味着 OpenClaw 会自动回退到 legacy 引擎的压缩路径。
因此有两种有效的插件模式:
Owning 模式
实现自己的压缩算法,设置 `ownsCompaction: true`。
Delegating 模式
设置 `ownsCompaction: false`,在 `compact()` 中调用 `openclaw/plugin-sdk/core` 的 `delegateCompactionToRuntime(...)` 使用 OpenClaw 内置压缩行为。
对于活跃的非 Owning 引擎,空操作的 compact() 是不安全的,因为它会禁用该引擎 slot 的正常 /compact 和溢出恢复压缩路径。
配置参考
json5
{
plugins: {
slots: {
// 选择活跃的 Context Engine。默认: "legacy"。
// 设为插件 ID 可使用插件引擎。
contextEngine: "legacy",
},
},
}INFO
该 slot 在运行时是独占的——每次运行或压缩操作只会解析一个已注册的 Context Engine。其他启用的 kind: "context-engine" 插件仍然可以加载并运行其注册代码;plugins.slots.contextEngine 仅决定 OpenClaw 需要 Context Engine 时解析哪个注册 ID。
INFO
插件卸载: 当卸载当前选为 plugins.slots.contextEngine 的插件时,OpenClaw 会将 slot 重置为默认值(legacy)。相同重置行为也适用于 plugins.slots.memory。无需手动编辑配置。
与 Compaction 和 Memory 的关系
Compaction
压缩是 Context Engine 的职责之一。Legacy 引擎委托给 OpenClaw 内置摘要;插件引擎可以实现任意压缩策略(DAG 摘要、向量检索等)。
Memory 插件
Memory 插件(`plugins.slots.memory`)与 Context Engine 相互独立。Memory 插件提供搜索/检索;Context Engine 控制模型能看到什么。它们可以协同工作——Context Engine 在组装时可以利用 Memory 插件数据。希望使用活跃 Memory 提示路径的插件引擎应优先使用 `openclaw/plugin-sdk/core` 中的 `buildMemorySystemPromptAddition(...)`,它会将活跃 Memory 提示段转换为可直接预置的 `systemPromptAddition`。如果引擎需要更低级别的控制,仍可通过 `openclaw/plugin-sdk/memory-host-core` 的 `buildActiveMemoryPromptSection(...)` 获取原始行。
Session Pruning(会话修剪)
无论在哪个 Context Engine 活跃,内存中修剪旧工具结果的逻辑都会运行。
使用技巧
- 使用
openclaw doctor验证引擎是否正确加载。 - 切换引擎时,现有会话继续使用当前历史。新引擎从后续运行开始接管。
- 引擎错误会记录到日志并显示在诊断信息中。如果插件引擎注册失败,或找不到选定的引擎 ID,OpenClaw 不会自动回退;运行会失败,直到你修复插件或将
plugins.slots.contextEngine切回"legacy"。 - 开发时,使用
openclaw plugins install -l ./my-engine以链接方式挂载本地插件目录,无需复制文件。
参考
常见问题
如何切换到自定义上下文引擎?
安装插件后,在 openclaw.json 的 plugins.slots.contextEngine 中设置插件注册的引擎 ID(例如 "lossless-claw"),并确保插件在 plugins.entries 中已启用。然后重启 Gateway。可用 openclaw doctor 验证是否激活。
切换引擎后运行报错,怎么解决?
检查插件是否已正确安装并启用,且引擎 ID 拼写无误。如果插件引擎注册失败或 ID 无法解析,OpenClaw 不会自动回退,运行会失败。先将 plugins.slots.contextEngine 切回 "legacy" 恢复服务,然后修复插件问题。错误信息会记录在诊断中。
ownsCompaction 设 true 还是 false?
如果你实现自己的压缩逻辑(例如 DAG 摘要、向量检索),设 true 并实现 compact()。如果你希望复用 OpenClaw 内置压缩行为,设 false 并在 compact() 中调用 delegateCompactionToRuntime(...)。不要对活跃的非 Owning 引擎提供空操作 compact(),否则 /compact 和溢出恢复会失效。