【插件】OpenClaw 上下文引擎指南

AI 时代程序员必备技能

Codex、Claude Code、Cursor、Hermes Agent、OpenClaw等工程化实战专栏 ,讲透 AI 如何接管脏活累活

上下文引擎(Context Engine)是 OpenClaw 的核心组件,负责构建、压缩和管理每一次模型调用的上下文——它决定哪些历史消息被保留、如何总结早期对话,以及如何在子智能体(subagent)之间传递记忆。


🎯 上下文引擎

LLM 的上下文窗口是有限的(例如 128k tokens),但会话可能持续数千轮。传统做法是简单地“先进先出”或“滑动窗口”,但这会丢失关键信息。OpenClaw 的上下文引擎提供了一套可插拔的生命周期钩子,让你可以:

  • 精准控制:哪些消息进入模型?顺序如何?如何压缩?
  • 跨会话回忆:通过外部存储(如向量数据库)实现长期记忆。
  • 子智能体隔离:为子任务创建独立或继承的上下文环境。
  • 故障隔离:即使引擎出错,也不会导致主回复流程中断。

🚀 快速开始:

1️⃣ 检查当前引擎

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

默认输出为 "legacy",即内置的经典引擎。
在这里插入图片描述

2️⃣ 安装一个插件引擎

安装方式与普通插件一致:

  • 从 npm 安装openclaw plugins install @martian-engineering/lossless-claw
  • 从本地路径安装(开发调试):openclaw plugins install -l ./my-context-engine

在这里插入图片描述

3️⃣ 启用并配置引擎

编辑 ~/.openclaw/openclaw.json(JSON5 格式):

{
  plugins: {
    slots: {
      contextEngine: "lossless-claw", // 必须与插件注册的引擎 id 一致
    },
    entries: {
      "lossless-claw": {
        enabled: true,
        // 插件专属配置(参考其文档)
      },
    },
  },
}

配置完成后重启 Gateway 网关即可生效。

4️⃣ 切回旧版引擎(可选)

只需将 contextEngine 设置为 "legacy" 或直接删除该键(默认即为 "legacy")。


⚙️ 工作原理:生命周期

每当 OpenClaw 需要调用模型时,上下文引擎会依次经历以下阶段:

⚠️ 已超预算

✅ 未超预算

⚙ stubLargeToolPayloads=true

📨 新消息到达

📥 ingest 摄入持久化

🔍 assemble 组装前检查

🚑 紧急同步 compactUntilUnder

🧩 assemble 组装:摘要 + freshTail

🧠 模型推理

🔄 afterTurn 轮次结束

📊 记录阈值压缩债务

⏳ 后台异步排水 / maintain()

🌿 叶子摘要 / 凝聚摘要 生成

🗂️ 更新摘要 DAG

👤 用户触发 /compact

🔎 显式全量扫描压缩

💥 上下文窗口溢出

🚑 compactUntilUnder 急救压缩

📦 large_files 外部存储

阶段关键配置行为
📥 摄入replayFloodThresholdExternal / Internal防重放洪水守卫
🧩 组装freshTailCountfreshTailMaxTokenspromptAwareEvictionstubLargeToolPayloads保护新鲜尾部、按相关性/时间裁剪、大载荷存根
🗜️ 压缩contextThreshold(默认 0.75)、leafChunkTokenssweepMaxDepthleafMinFanout阈值触发、叶子大小、凝聚深度、扇出
⏳ 延迟模式proactiveThresholdCompactionMode: deferred非阻塞、后台排水
🚑 急救compactUntilUnderDeadlineMs(默认 300s)溢出恢复硬限预算
🛠️ 维护autoRotateSessionFilestranscriptGcEnabled轮转、GC

🔍 验证方式

快速检查 — 运行状态命令:

/lossless          # 或
/lcm status

在这里插入图片描述
在这里插入图片描述

输出一览:

信息项说明
当前 frontier token当前前沿 token 位置
压缩比摘要压缩比
待处理维护状态pending / running / last-failure
摘要计数摘要总数,含 broken / truncated 标记

深入排查 — 查看独立日志:

tail -f /tmp/openclaw/lossless-claw-$(date +%F).log

在这里插入图片描述

💡 搜索关键词 [lcm] (compact|assembly|maintain|auto-rotate) 即可定位真实执行轨迹。

摄取(ingest)

当新消息(用户或助手)加入会话时,引擎可以将其存储到自己的数据存储中,或建立索引(例如用于后续检索)。
参数sessionId, message, isHeartbeat 等。

组装(assemble)

每次模型运行调用,引擎返回一个有序消息列表,必须符合当前的令牌预算(tokenBudget)。同时可返回:

  • systemPromptAddition:追加到系统提示词前的字符串(如动态回忆指令)。
  • estimatedTokens:引擎估算的组装后总令牌数,用于压缩阈值判断。
  • promptAuthority:控制预检查使用哪个估算值(默认 "assembled",即基于组装后的结果检查溢出)。
  • contextProjection(可选):为支持持久化线程的后端(如 Codex app-server)提供“线程引导”模式,避免每轮重复投影。

压缩(compact)

当上下文窗口已满,或用户执行 /compact 命令时触发。引擎需要将较早的历史总结为更紧凑的形式(如摘要、向量摘要等)。
返回 CompactResult,可指明压缩后的新会话标识(sessionTarget),用于后续路由。

轮次结束后(afterTurn)

模型运行完成后调用,引擎可持久化状态、触发后台压缩或更新索引。

除此之外,引擎还可以实现:

  • maintain():在引导启动、每轮成功完成或压缩后执行“维护任务”,可通过 runtimeContext.rewriteTranscriptEntries() 安全重写对话记录。将 info.turnMaintenanceMode 设为 "background" 可使其异步执行,不阻塞回复。
  • 子智能体钩子
    • prepareSubagentSpawn:在子会话开始前准备共享上下文状态(接收父/子会话键、contextModeisolatedfork)等),可返回回滚句柄,在生成失败时调用。若请求 lightContext 且解析为 isolated,则跳过此钩子。
    • onSubagentEnded:子会话结束后的清理工作。

🏛️ 内置 Legacy 引擎 vs 插件引擎

旧版引擎(legacy)

  • 摄取:无操作(由会话管理器直接持久化)。
  • 组装:直接传递,由运行时的清理→验证→限制流水线处理。
  • 压缩:委托给内置的摘要机制,生成早期消息的摘要,保留近期完整消息。
  • 轮次结束后:无操作。
  • 不注册工具,不提供 systemPromptAddition
特性Legacy 引擎插件引擎(任意)
自定义存储/索引✅ 通过 ingest 自由实现
消息组装策略固定(运行时流水线)完全自由,可基于外部记忆
压缩算法内置摘要任意(DAG、向量检索等)
系统提示动态注入systemPromptAddition
子智能体上下文控制✅ 通过 prepareSubagentSpawn
故障隔离稳定(无需隔离)被隔离后自动回退到 Legacy

🧩 开发一个插件引擎:接口详解

注册入口

export default function register(api) {
  api.registerContextEngine("my-engine", (ctx) => ({
    info: {
      id: "my-engine",
      name: "My Context Engine",
      ownsCompaction: true, // 是否自主管理压缩
    },
    // ... 生命周期方法
  }));
}

核心必需成员

成员类型说明
info属性对象包含 id, name, version?, ownsCompaction
ingest(params)异步方法存储单条消息,返回 { ingested: boolean }
assemble(params)异步方法构建消息列表,返回 AssembleResult(见下文)
compact(params)异步方法压缩上下文,返回 CompactResult
AssembleResult 字段
字段类型必需说明
messagesMessage[]有序消息列表(发送给模型)
estimatedTokensnumber引擎估算的总令牌数
systemPromptAdditionstring可选添加到系统提示之前
promptAuthority"assembled" | "preassembly_may_overflow"可选控制溢出预检查使用哪个估算值。若引擎 ownsCompaction: true,默认跳过预检查;设置此值为 "preassembly_may_overflow" 可强制保留预检查(取组装前后估算值较大者)。
contextProjectionContextEngineProjection可选为支持持久化线程的后端提供“线程引导”模式(mode: "thread_bootstrap" + epoch),避免每轮重新投影。
CompactResult 字段
  • ok: boolean
  • compacted: boolean
  • sessionTarget?:类型 ContextEngineSessionTarget,用于指示压缩后应切换到哪个后继会话。
  • sessionId?:后继会话的 ID(一般与 sessionTarget 结合使用)。

可选成员(增强功能)

成员用途
bootstrap(params)引擎首次看到会话时调用(例如导入历史记录)
maintain(params)在引导、轮次成功或压缩后维护记录(可重写转录)
ingestBatch(params)批量摄取一个完整轮次的所有消息(运行后调用)
afterTurn(params)轮次结束后的持久化/后台压缩触发
prepareSubagentSpawn(params)子会话开始前准备共享状态
onSubagentEnded(params)子会话结束后的清理
dispose()释放资源(网关关闭或插件重载时调用,非会话级)

🛠️ 高级特性与生产建议

🔐 运行时设置(runtimeSettings)

生命周期钩子会收到一个只读的 runtimeSettings 对象,包含当前执行环境的上下文信息:

  • schemaVersion:当前为 1
  • runtime:主机类型("openclaw" 等)、模式(normal/fallback/degraded
  • contextEngineSelection:所选引擎 ID 及来源
  • executionHost:调用界面的主机 ID 和标签
  • model:请求的模型、解析后的模型、提供商及系列
  • limits:提示词令牌预算、最大输出令牌数(若已知)
  • diagnostics:回退/降级原因代码(若已知)

若旧版引擎将 runtimeSettings 视为未知属性而拒绝,OpenClaw 会重试不带该属性,保证兼容性。

🖥️ 主机要求(hostRequirements)

引擎可以在 info.hostRequirements 中声明对宿主的能力要求。例如,若引擎必须通过 assemble() 完全控制提示词,则应声明 assemble-before-prompt

info: {
  id: "my-engine",
  hostRequirements: {
    "agent-run": {
      requiredCapabilities: ["assemble-before-prompt"],
      unsupportedMessage: "请使用原生 Codex 或 OpenClaw 嵌入式运行时,或切换回 Legacy 引擎。",
    },
  },
}
  • 原生 Codex 和 OpenClaw 嵌入式运行时满足此能力。
  • 通用 CLI 后端不满足,因此该引擎在 CLI 进程启动前会被拒绝。

🧯 故障隔离

OpenClaw 会将选中的插件引擎与核心回复路径隔离。如果引擎缺失、契约验证失败、工厂抛出异常或生命周期方法抛出异常,系统会:

  1. 在当前 Gateway 进程中隔离该引擎。
  2. 自动降级到内置 legacy 引擎,保证智能体继续响应。
  3. 记录错误日志,供运维人员修复。

主机要求失败属于硬性约束,会直接导致启动失败,以防引擎在不受支持的环境中损坏状态。

💾 ownsCompaction 的两种模式

该属性控制运行时是否自动启用内置的“单次尝试内压缩”:

ownsCompaction含义推荐实现
true引擎自己管理压缩,运行时跳过自动溢出压缩compact() 中实现自己的压缩逻辑
false 或未设置运行时保留自动压缩路径,但插件仍需在 compact() 中调用 delegateCompactionToRuntime(...) 来实际触发内置压缩调用 SDK 的委派函数,否则 /compact 和溢出恢复会失效

⚠️ 重要:ownsCompaction: false 并不意味着自动使用 Legacy 压缩——你必须显式委派。

🔗 与记忆(Memory)插件的关系

  • 记忆插件plugins.slots.memory)负责检索/搜索,例如从向量库中召回相关片段。
  • 上下文引擎负责组装视图,决定模型到底看到什么。
  • 二者可协同:引擎可在 assemble 时调用记忆插件的数据,并通过 buildMemorySystemPromptAddition() 辅助函数将准备好的记忆提示词转换成 systemPromptAddition,无需暴露记忆插件的内部布局。

✂️ 会话裁剪

无论哪个引擎活动,OpenClaw 始终在内存中裁剪旧的工具结果(tool results),以保持基本的内存健康。


📝 配置参考(JSON5)

{
  plugins: {
    slots: {
      // 选中的上下文引擎 ID,默认为 "legacy"
      contextEngine: "legacy",
    },
    entries: {
      // 引擎插件的启用状态及配置
      "my-engine": {
        enabled: true,
        // ... 引擎特定配置
      },
    },
  },
}
  • 该槽位具有排他性:每次运行或压缩只解析一个引擎。
  • 若卸载当前选中的引擎,OpenClaw 会自动将槽位重置为 "legacy"(记忆槽位同理),无需手动编辑。

💡 实用小贴士

  • openclaw doctor 随时验证引擎是否加载成功。
  • 切换引擎不会影响已有会话的历史记录,后续运行由新引擎接管。
  • 开发时使用 openclaw plugins install -l ./my-engine 链接本地目录,无需每次复制。
  • 若插件引擎发生错误,会记录并隔离,但用户轮次会回退到 Legacy,请及时修复插件。

🧪 完整插件示例(TypeScript)

import { buildMemorySystemPromptAddition } from "openclaw/plugin-sdk/core";

export default function register(api) {
  api.registerContextEngine("my-engine", (ctx) => ({
    info: {
      id: "my-engine",
      name: "My Engine",
      ownsCompaction: false,
      hostRequirements: {
        "agent-run": {
          requiredCapabilities: ["assemble-before-prompt"],
        },
      },
    },

    async ingest({ sessionId, message }) {
      // 存储到自定义 DB
      await myDB.store(sessionId, message);
      return { ingested: true };
    },

    async assemble({ sessionId, messages, tokenBudget, availableTools, citationsMode, agentSessionKey }) {
      // 自定义排序/筛选/检索
      const contextualMessages = await myRetriever.retrieve(sessionId, messages, tokenBudget);
      const addition = buildMemorySystemPromptAddition({
        availableTools: availableTools ?? new Set(),
        citationsMode,
        agentSessionKey,
      });
      return {
        messages: contextualMessages,
        estimatedTokens: countTokens(contextualMessages),
        systemPromptAddition: addition,
      };
    },

    async compact({ sessionId, force }) {
      // 使用内置委派(因为 ownsCompaction: false)
      return await delegateCompactionToRuntime({ sessionId, force });
    },

    async afterTurn({ sessionId }) {
      // 异步更新索引
      await myIndexer.update(sessionId);
    },
  }));
}

📚 总结

OpenClaw 的上下文引擎通过清晰的生命周期钩子强大的插件机制,让你能够完全掌控模型输入的构建过程。无论是简单的线性摘要,还是基于检索的复杂记忆系统,都能通过实现几个核心方法快速集成。同时,故障隔离自动回退保证了生产环境的稳定性,让你放心探索高级上下文策略。

AI 时代程序员必备技能

Codex、Claude Code、Cursor、Hermes Agent、OpenClaw等工程化实战专栏 ,讲透 AI 如何接管脏活累活

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

海兰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值