Skip to content

使用插件引擎可自定义 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

在子运行启动前准备共享上下文状态。接收父/子会话键、contextModeisolatedfork)、可用的 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 包含可选的 configagentDirworkspaceDir 值,以便插件在第一个生命周期钩子运行之前初始化每个 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.sessionIdresult.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.jsonplugins.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 和溢出恢复会失效。