上下文引擎
一个 上下文引擎 控制着 OpenClaw 如何为每次运行构建模型上下文:包括包含哪些消息、如何压缩旧的历史记录以及如何管理跨子代理边界的上下文。
OpenClaw 内置了 legacy 引擎并默认使用它 - 大多数用户无需更改此设置。仅当您需要不同的组装、压缩或跨会话回忆行为时,才安装并选择插件引擎。
检查哪个引擎处于活动状态
Terminal window openclaw doctor# or inspect config directly:cat ~/.openclaw/openclaw.json | jq '.plugins.slots.contextEngine'安装插件引擎
上下文引擎插件的安装方式与任何其他 OpenClaw 插件相同。
Terminal window openclaw plugins install @martian-engineering/lossless-clawTerminal window openclaw plugins install -l ./my-context-engine启用并选择引擎
openclaw.json {plugins: {slots: {contextEngine: "lossless-claw", // must match the plugin's registered engine id},entries: {"lossless-claw": {enabled: true,// Plugin-specific config goes here (see the plugin's docs)},},},}安装并配置后,请重启网关。
切换回旧版引擎(可选)
将
contextEngine设置为"legacy"(或完全删除该键 -"legacy"为默认值)。
每次 OpenClaw 运行模型提示时,上下文引擎都会在四个生命周期点参与其中:
1. 摄取
当新消息添加到会话时调用。引擎可以将其存储或索引到自己的数据存储中。
2. 组装
在每次模型运行之前调用。引擎返回一组适合令牌预算的有序消息(以及可选的 systemPromptAddition)。
3. 压缩
当上下文窗口已满,或者用户运行 /compact 时调用。引擎会对较早的历史记录进行摘要以释放空间。
4. 回合后
在一次运行完成后调用。引擎可以持久化状态、触发后台压缩或更新索引。
对于捆绑的非 ACP Codex harness,OpenClaw 通过将组装的上下文投影到 Codex 开发者指令和当前回合提示中来应用相同的生命周期。Codex 仍然拥有其原生线程历史记录和原生压缩器。
子代理生命周期(可选)
Section titled “子代理生命周期(可选)”OpenClaw 调用两个可选的子代理生命周期钩子:
系统提示词添加
Section titled “系统提示词添加”assemble 方法可以返回一个 systemPromptAdditionOpenClaw 字符串。OpenClaw 会将其前置到运行的系统提示中。这允许引擎注入动态的召回指导、检索指令或上下文感知提示,而无需静态工作区文件。
内置的 legacyOpenClaw 引擎保留了 OpenClaw 的原始行为:
- 摄取 (Ingest):无操作(会话管理器直接处理消息持久化)。
- 组装 (Assemble):直通(运行时中现有的清理 → 验证 → 限制管道处理上下文组装)。
- Compact:委托给内置的摘要压缩,它会对旧消息创建单个摘要并保持最近的消息不变。
- After turn:无操作。
旧版引擎不注册工具也不提供 systemPromptAddition。
当未设置 plugins.slots.contextEngine(或将其设置为 "legacy")时,将自动使用此引擎。
插件可以使用插件 API 注册上下文引擎:
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 }) { // Store the message in your data store return { ingested: true }; },
async assemble({ sessionId, messages, tokenBudget, availableTools, citationsMode }) { // Return messages that fit the budget return { messages: buildContext(messages, tokenBudget), estimatedTokens: countTokens(messages), systemPromptAddition: buildMemorySystemPromptAddition({ availableTools: availableTools ?? new Set(), citationsMode, }), }; },
async compact({ sessionId, force }) { // Summarize older context return { ok: true, compacted: true }; }, }));}工厂 ctx 包含可选的 config、agentDir 和 workspaceDir
值,以便插件可以在第一个生命周期钩子运行之前初始化每个代理或每个工作区的状态。
然后在配置中启用它:
{ plugins: { slots: { contextEngine: "my-engine", }, entries: { "my-engine": { enabled: true, }, }, },}ContextEngine 接口
Section titled “ContextEngine 接口”必需成员:
| 成员 | 类型 | 用途 |
|---|---|---|
info | 属性 | 引擎 ID、名称、版本以及它是否拥有压缩权 |
ingest(params) | 方法 | 存储单条消息 |
assemble(params) | 方法 | 为模型运行构建上下文(返回 AssembleResult) |
compact(params) | 方法 | 摘要/缩减上下文 |
assemble 返回一个 AssembleResult,其中包含:
compact 返回一个 CompactResult。当压缩轮换活动转录时,result.sessionId 和 result.sessionFile 标识下一次重试或回合必须使用的后续会话。
可选成员:
| 成员 | 类型 | 用途 |
|---|---|---|
bootstrap(params) | 方法 | 初始化会话的引擎状态。在引擎首次看到会话时(例如,导入历史记录)调用一次。 |
ingestBatch(params) | 方法 | 作为批次摄取已完成的回合。在运行完成后调用,一次性包含该回合的所有消息。 |
afterTurn(params) | 方法 | 运行后的生命周期工作(持久化状态,触发后台压缩)。 |
prepareSubagentSpawn(params) | 方法 | 在子会话开始之前为其设置共享状态。 |
onSubagentEnded(params) | 方法 | 在子代理结束后进行清理。 |
dispose() | 方法 | 释放资源。在网关关闭或插件重新加载期间调用 - 而非针对每个会话。 |
上下文引擎可以在 info.hostRequirements 上声明主机能力要求。
OpenClaw 会在开始操作前检查这些要求,如果所选运行时无法满足要求,则将以描述性错误关闭并失败。
对于代理运行,当引擎必须通过 assemble() 控制实际模型提示时,请声明 assemble-before-prompt:
info: { id: "my-context-engine", name: "My Context Engine", hostRequirements: { "agent-run": { requiredCapabilities: ["assemble-before-prompt"], unsupportedMessage: "Use the native Codex or OpenClaw embedded runtime, or select the legacy context engine.", }, },}Native Codex 和 OpenClaw 嵌入式代理运行满足 assemble-before-prompt。
通用 CLI 后端不满足,因此需要它的引擎会在 CLI 进程启动之前被拒绝。
OpenClaw 将选定的插件引擎与核心回复路径隔离。如果非旧版引擎缺失、未通过合约验证、在工厂创建期间抛出异常,或在生命周期方法中抛出异常,OpenClaw 会将该引擎在当前 Gateway(网关) 进程中进行隔离,并将上下文引擎工作降级为内置的 legacy 引擎。错误会与失败的操作一起记录,以便操作员可以修复、更新或禁用插件,而不会导致代理静默无响应。
主机要求失败的情况有所不同:当引擎声明运行时缺少所需功能时,OpenClaw 会在启动运行之前直接失败。这可以保护那些在不支持的主机上运行时会破坏状态的引擎。
ownsCompaction
Section titled “ownsCompaction”ownsCompaction 控制是否为本次运行启用 OpenClaw 运行时内置的尝试内自动压缩:
ownsCompaction: true
引擎拥有压缩行为。OpenClaw 禁用该次运行的 OpenClaw 运行时内置自动压缩,并且引擎的 compact() 实现负责 /compact、溢出恢复压缩以及它想要在 afterTurn() 中执行的任何主动压缩。OpenClaw 可能仍会运行预提示溢出保护措施;当它预测完整转录将溢出时,恢复路径会在提交另一个提示之前调用活动引擎的 compact()。
ownsCompaction: false or unset
OpenClaw 运行时的内置自动压缩仍可能在提示执行期间运行,但仍会调用活动引擎的 compact() 方法进行 /compact 和溢出恢复。
这意味着有两种有效的插件模式:
实现您自己的压缩算法并设置 ownsCompaction: true。
设置 ownsCompaction: false 并让 compact() 调用 openclaw/plugin-sdk/core 中的 delegateCompactionToRuntime(...),以使用 OpenClaw 的内置压缩行为。
对于非拥有模式的活跃引擎,no-op compact() 是不安全的,因为它禁用了该引擎槽位的常规 /compact 和溢出恢复压缩路径。
{ plugins: { slots: { // Select the active context engine. Default: "legacy". // Set to a plugin id to use a plugin engine. contextEngine: "legacy", }, },}与压缩和记忆的关系
Section titled “与压缩和记忆的关系”Compaction
压缩是上下文引擎的职责之一。传统引擎委托给 OpenClaw 内置的摘要。插件引擎可以实现任何压缩策略(DAG 摘要、向量检索等)。
Memory plugins
Memory 插件 (plugins.slots.memory) 与上下文引擎是分开的。Memory 插件提供搜索/检索功能;上下文引擎控制模型看到的内容。它们可以协同工作 - 上下文引擎可能会在组装过程中使用 Memory 插件的数据。如果插件引擎需要使用活跃的 Memory 提示路径,应该首选使用 openclaw/plugin-sdk/core 中的 buildMemorySystemPromptAddition(...),它将活跃的 Memory 提示部分转换为随时可预置的
systemPromptAddition。如果引擎需要更低级别的控制,它仍然可以通过 buildActiveMemoryPromptSection(...) 从 openclaw/plugin-sdk/memory-host-core 中提取原始行。
Session pruning
无论哪个上下文引擎处于活动状态,内存中修剪旧工具结果的操作仍会继续运行。
- 使用
openclaw doctor来验证您的引擎是否正在正确加载。 - 如果切换引擎,现有会话将继续使用其当前历史记录。新引擎将接管未来的运行。
- 引擎错误会被记录,所选的插件引擎将在当前 Gateway(网关) 进程中被隔离。OpenClaw 会回退到
legacy以便用户轮次可以继续回复,但你仍然应该修复、更新、禁用或卸载损坏的插件。 - 对于开发,使用
openclaw plugins install -l ./my-engine来链接本地插件目录而无需复制。