Skip to content

Context Engine(上下文引擎)

Context Engine 控制 OpenClaw 在每次运行时如何构建模型上下文。它决定包含哪些消息、如何总结旧历史,以及如何跨子 Agent 边界管理上下文。

OpenClaw 内置了 legacy 引擎。插件可以注册替代引擎来替换活跃的 Context Engine 生命周期。

快速上手

查看当前使用的引擎:

bash
openclaw doctor
# 或直接查看配置:
cat ~/.openclaw/openclaw.json | jq '.plugins.slots.contextEngine'

安装 Context Engine 插件

Context Engine 插件的安装方式与其他 OpenClaw 插件相同。先安装,再在 slot 中选择:

bash
# 从 npm 安装
openclaw plugins install @martian-engineering/lossless-claw

# 或从本地路径安装(开发用)
openclaw plugins install -l ./my-context-engine

然后在配置中启用插件并选择为活跃引擎:

json5
// openclaw.json
{
  plugins: {
    slots: {
      contextEngine: "lossless-claw", // 必须与插件注册的引擎 ID 匹配
    },
    entries: {
      "lossless-claw": {
        enabled: true,
        // 插件专属配置(参见插件文档)
      },
    },
  },
}

安装和配置完成后重启 Gateway。

若要切换回内置引擎,将 contextEngine 设为 "legacy"(或直接删除该键,默认就是 "legacy")。

工作原理

每次 OpenClaw 运行模型提示时,Context Engine 会在四个生命周期节点参与:

  1. Ingest(摄入)——当新消息加入会话时调用。引擎可将消息存储或索引到自己的数据库。
  2. Assemble(组装)——每次模型运行前调用。引擎返回一组有序消息(以及可选的 systemPromptAddition),确保在 token 预算内。
  3. Compact(压缩)——当上下文窗口已满,或用户执行 /compact 时调用。引擎对旧历史进行摘要以释放空间。
  4. After turn(轮次后)——运行完成后调用。引擎可持久化状态、触发后台 Compaction 或更新索引。

子 Agent 生命周期(可选)

OpenClaw 目前调用一个子 Agent 生命周期 hook:

  • onSubagentEnded——子 Agent 会话完成或被清理时执行清理操作。

prepareSubagentSpawn hook 已定义在接口中供未来使用,但运行时目前尚未调用。

系统提示追加

assemble 方法可以返回一个 systemPromptAddition 字符串。OpenClaw 会在本次运行的系统提示前添加这段内容。这让引擎可以注入动态的召回引导、检索说明或上下文感知提示,而无需依赖静态的 Workspace 文件。

Legacy 引擎

内置的 legacy 引擎保留了 OpenClaw 的原始行为:

  • Ingest:空操作(消息持久化由 Session Manager 直接处理)。
  • Assemble:透传(运行时现有的 sanitize → validate → limit 流水线负责上下文组装)。
  • Compact:委托给内置的摘要式 Compaction,对旧消息生成一条摘要,保留近期消息完整。
  • After turn:空操作。

Legacy 引擎不注册工具,也不提供 systemPromptAddition

未设置 plugins.slots.contextEngine(或设为 "legacy")时,自动使用此引擎。

插件引擎

插件可以通过 Plugin API 注册 Context Engine:

ts
export default function register(api) {
  api.registerContextEngine("my-engine", () => ({
    info: {
      id: "my-engine",
      name: "My Context Engine",
      ownsCompaction: true,
    },

    async ingest({ sessionId, message, isHeartbeat }) {
      // 将消息存入你的数据库
      return { ingested: true };
    },

    async assemble({ sessionId, messages, tokenBudget }) {
      // 返回在预算内的消息
      return {
        messages: buildContext(messages, tokenBudget),
        estimatedTokens: countTokens(messages),
        systemPromptAddition: "Use lcm_grep to search history...",
      };
    },

    async compact({ sessionId, force }) {
      // 对旧上下文进行摘要
      return { ok: true, compacted: true };
    },
  }));
}

然后在配置中启用:

json5
{
  plugins: {
    slots: {
      contextEngine: "my-engine",
    },
    entries: {
      "my-engine": {
        enabled: true,
      },
    },
  },
}

ContextEngine 接口

必填成员:

成员类型用途
info属性引擎 ID、名称、版本,以及是否拥有 Compaction
ingest(params)方法存储单条消息
assemble(params)方法为模型运行构建上下文(返回 AssembleResult
compact(params)方法摘要/压缩上下文

assemble 返回的 AssembleResult 包含:

  • messages——发送给模型的有序消息列表。
  • estimatedTokens(必填,number)——引擎对组装上下文 token 数的估算。OpenClaw 用此值进行 Compaction 阈值判断和诊断报告。
  • systemPromptAddition(可选,string)——追加到系统提示前。

可选成员:

成员类型用途
bootstrap(params)方法初始化引擎的会话状态。首次遇到某个会话时调用一次(例如导入历史)。
ingestBatch(params)方法以批量方式摄入一整个轮次。运行完成后调用,传入该轮次所有消息。
afterTurn(params)方法运行后的生命周期工作(持久化状态、触发后台 Compaction)。
prepareSubagentSpawn(params)方法为子会话准备共享状态。
onSubagentEnded(params)方法子 Agent 结束后清理资源。
dispose()方法释放资源。Gateway 关闭或插件重载时调用,不是按会话调用。

ownsCompaction

ownsCompaction 控制 Pi 内置的运行中自动 Compaction 是否对该次运行保持启用:

  • true——引擎拥有 Compaction 行为。OpenClaw 禁用 Pi 内置的自动 Compaction,引擎的 compact() 实现负责处理 /compact、溢出恢复 Compaction,以及在 afterTurn() 中主动触发的 Compaction。
  • false 或未设置——Pi 内置的自动 Compaction 在提示执行过程中可能仍会运行,但活跃引擎的 compact() 方法依然负责处理 /compact 和溢出恢复。

ownsCompaction: false 不意味着 OpenClaw 会自动回退到 legacy 引擎的 Compaction 路径。

因此存在两种有效的插件模式:

  • Owning 模式——实现自己的 Compaction 算法,设置 ownsCompaction: true
  • Delegating 模式——设置 ownsCompaction: false,在 compact() 中调用 openclaw/plugin-sdk/coredelegateCompactionToRuntime(...) 使用 OpenClaw 内置 Compaction。

对于活跃的非 Owning 引擎,空操作的 compact() 是不安全的,因为它会禁用该引擎 slot 的正常 /compact 和溢出恢复 Compaction 路径。

配置参考

json5
{
  plugins: {
    slots: {
      // 选择活跃的 Context Engine,默认 "legacy"。
      // 设为插件 ID 可使用插件引擎。
      contextEngine: "legacy",
    },
  },
}

该 slot 在运行时是独占的——每次运行或 Compaction 操作只会解析一个注册的 Context Engine。其他启用的 kind: "context-engine" 插件仍然可以加载并运行其注册代码;plugins.slots.contextEngine 仅决定 OpenClaw 需要 Context Engine 时解析哪个注册 ID。

与 Compaction 和 Memory 的关系

  • Compaction 是 Context Engine 的职责之一。Legacy 引擎委托给 OpenClaw 内置摘要;插件引擎可以实现任意 Compaction 策略(DAG 摘要、向量检索等)。
  • Memory 插件plugins.slots.memory)与 Context Engine 是独立的。Memory 插件提供搜索/检索;Context Engine 控制模型能看到什么。两者可以协同工作——Context Engine 在组装时可以利用 Memory 插件数据。
  • Session Pruning(内存中裁剪旧工具结果)无论哪个 Context Engine 活跃都会运行。

使用技巧

  • openclaw doctor 验证你的引擎是否正确加载。
  • 切换引擎时,已有的会话将继续使用现有历史;新引擎从下次运行开始接管。
  • 引擎错误会记录到日志并在诊断信息中显示。如果插件引擎注册失败,或者找不到选定的引擎 ID,OpenClaw 不会自动回退;运行会失败,直到你修复插件或将 plugins.slots.contextEngine 切回 "legacy"
  • 开发时,用 openclaw plugins install -l ./my-engine 以链接方式挂载本地插件目录,无需复制文件。

参见:CompactionContextPluginsPlugin manifest