Fundamentals

情境引擎

上下文引擎控制 OpenClaw 如何為每次執行建構模型上下文:要納入哪些訊息、如何摘要較舊的歷史記錄,以及如何跨子代理邊界管理上下文。

OpenClaw 內建 legacy 引擎,並預設使用此引擎。只有在需要不同的組裝、壓縮或跨工作階段回溯行為時,才安裝並選取外掛引擎。

快速開始

  • 檢查目前使用的引擎

    bash
    openclaw doctor# 或直接檢查設定:cat ~/.openclaw/openclaw.json | jq '.plugins.slots.contextEngine'
  • 安裝外掛引擎

    上下文引擎外掛的安裝方式與其他 OpenClaw 外掛相同。

    從 npm 安裝

    bash
    openclaw plugins install @martian-engineering/lossless-claw

    從本機路徑安裝

    bash
    openclaw plugins install -l ./my-context-engine
  • 啟用並選取引擎

    json5
    // openclaw.json{  plugins: {    slots: {      contextEngine: "lossless-claw", // 必須符合外掛註冊的引擎 id    },    entries: {      "lossless-claw": {        enabled: true,        // 外掛特定設定放在這裡(請參閱外掛文件)      },    },  },}

    安裝並設定後,請重新啟動閘道。

  • 切換回舊版(選用)

    contextEngine 設為 "legacy"(或完全移除該鍵,"legacy" 是預設值)。

  • 運作方式

    每當 OpenClaw 執行模型提示時,上下文引擎會參與四個生命週期階段:

    1. 擷取

    新訊息加入工作階段時呼叫。引擎可以將訊息儲存至自己的資料存放區,或為其建立索引。

    2. 組裝

    每次執行模型前呼叫。引擎會傳回符合權杖預算的有序訊息集合(以及選用的 systemPromptAddition)。

    3. 壓縮

    上下文視窗已滿,或使用者執行 /compact 時呼叫。引擎會摘要較舊的歷史記錄以釋出空間。

    4. 回合結束後

    執行完成後呼叫。引擎可以保存狀態、觸發背景壓縮或更新索引。

    引擎也可以實作選用的 maintain() 方法,以便在啟動程序、成功完成回合或壓縮後維護逐字記錄(透過 runtimeContext.rewriteTranscriptEntries() 安全重寫)。設定 info.turnMaintenanceMode: "background",即可將其作為延後工作執行,而不是阻塞回覆。

    對於隨附的非 ACP Codex 控制框架,OpenClaw 會將組裝後的上下文投射至 Codex 開發人員指示和目前回合提示,以套用相同的生命週期。Codex 仍會自行管理其原生執行緒歷史記錄與原生壓縮器。

    子代理生命週期(選用)

    OpenClaw 會呼叫兩個選用的子代理生命週期鉤子:

    prepareSubagentSpawnmethod

    在子執行開始前準備共用上下文狀態。此鉤子會接收父項/子項工作階段鍵、contextModeisolatedfork)、可用的逐字記錄 id/檔案,以及選用的 TTL。如果它傳回復原控制代碼,則 OpenClaw 會在準備成功後產生失敗時呼叫該控制代碼。要求 lightContext 且解析為 contextMode="isolated" 的原生子代理產生作業會刻意略過此鉤子,讓子項從輕量啟動上下文開始,而不使用由上下文引擎管理的產生前狀態。

    onSubagentEndedmethod

    在子代理工作階段完成或遭清除時進行清理。

    系統提示附加內容

    assemble 方法可以傳回 systemPromptAddition 字串。OpenClaw 會將其置於該次執行的系統提示之前。這讓引擎可以注入動態回溯指引、擷取指示或具上下文感知能力的提示,而不需要靜態工作區檔案。

    舊版引擎

    內建的 legacy 引擎會保留 OpenClaw 的原始行為:

    • 擷取:不執行任何操作(工作階段管理員會直接處理訊息持久化)。
    • 組裝:直接傳遞(執行階段中現有的清理 → 驗證 → 限制流水線會處理上下文組裝)。
    • 壓縮:委派給內建的摘要壓縮功能;該功能會為較舊的訊息建立單一摘要,並保持近期訊息不變。
    • 回合結束後:不執行任何操作。

    舊版引擎不會註冊工具,也不提供 systemPromptAddition

    未設定 plugins.slots.contextEngine(或將其設為 "legacy")時,會自動使用此引擎。

    外掛引擎

    外掛可以使用外掛 API 註冊上下文引擎:

    ts
     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,      sessionKey,      messages,      tokenBudget,      availableTools,      citationsMode,    }) {      // 傳回符合預算的訊息      return {        messages: buildContext(messages, tokenBudget),        estimatedTokens: countTokens(messages),        systemPromptAddition: buildMemorySystemPromptAddition({          availableTools: availableTools ?? new Set(),          citationsMode,          agentSessionKey: sessionKey,        }),      };    },     async compact({ sessionId, force }) {      // 摘要較舊的上下文      return { ok: true, compacted: true };    },  }));}

    工廠函式 ctx 包含選用的 configagentDirworkspaceDir 值,讓外掛能在第一次生命週期呼叫前初始化每個代理或每個工作區的狀態。在非舊版 assemble() 呼叫前,主機會完成 已註冊的非同步記憶提示準備。同步 buildMemorySystemPromptAddition(...) 輔助函式會讀取該不可變的執行快照; 請原封不動地傳遞所提供的工具、引用、代理和工作階段上下文。

    接著在設定中啟用:

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

    ContextEngine 介面

    必要成員:

    成員 種類 用途
    info 屬性 引擎 id、名稱、版本,以及是否由其負責壓縮
    ingest(params) 方法 儲存單一訊息
    assemble(params) 方法 為模型執行建構上下文(傳回 AssembleResult
    compact(params) 方法 摘要/縮減上下文

    assemble 會傳回包含以下項目的 AssembleResult

    messagesMessage[]required

    要傳送給模型的有序訊息。

    estimatedTokensnumberrequired

    引擎對組裝後上下文權杖總數的估算值。OpenClaw 會將此值用於壓縮閾值判斷和診斷報告。

    systemPromptAdditionstring

    置於系統提示之前。

    promptAuthority"assembled" | "preassembly_may_overflow"

    控制執行器在預先溢位檢查中使用哪一個權杖估算值。預設為 "assembled",這表示對於不負責壓縮的引擎,只會檢查組裝後提示的估算值。 設定 ownsCompaction: true 的引擎會自行管理提示准入,因此 OpenClaw 預設會略過一般的提示前預先檢查。只有在組裝後的檢視可能隱藏基礎逐字記錄中的溢位 風險時,才設定 "preassembly_may_overflow";接著執行器會維持一般 預先檢查啟用,並在決定是否要 預先壓縮時,採用組裝後估算值與組裝前(未套用視窗)工作階段歷史記錄估算值中的較大值。 無論如何,你傳回的訊息仍是模型 實際看到的內容;promptAuthority 只會影響預先檢查。

    contextProjectionContextEngineProjection

    適用於具有持久後端執行緒之主機(例如 Codex app-server)的選用投射生命週期。mode: "thread_bootstrap" 搭配穩定的 epoch,會要求主機在每個時期僅注入一次組裝後的上下文,並重複使用後端執行緒直到時期變更,而不是在每個回合重新投射。一般的逐回合投射請省略此欄位。

    compact 會傳回 CompactResult。壓縮變更作用中工作階段 身分時,result.sessionTarget(攜帶 工作階段身分與存放區範圍的具型別 ContextEngineSessionTarget)會識別下一次重試或回合必須使用的後繼工作階段;result.sessionId 會反映後繼項 id。

    選用成員:

    成員 種類 用途
    bootstrap(params) 方法 初始化工作階段的引擎狀態。引擎第一次看到工作階段時呼叫一次(例如匯入歷史記錄)。
    maintain(params) 方法 在啟動程序、成功完成回合或壓縮後維護逐字記錄。使用 runtimeContext.rewriteTranscriptEntries() 進行安全重寫。
    ingestBatch(params) 方法 以批次方式擷取已完成的回合。在執行完成後呼叫,並一次傳入該回合的所有訊息。
    afterTurn(params) 方法 執行後生命週期工作(保存狀態、觸發背景壓縮)。
    prepareSubagentSpawn(params) 方法 在子工作階段開始前設定其共用狀態。
    onSubagentEnded(params) 方法 在子代理結束後進行清理。
    dispose() 方法 釋放資源。在閘道關閉或重新載入外掛時呼叫,而非針對每個工作階段。

    執行階段設定

    在 OpenClaw 內執行的生命週期鉤子會接收選用的 runtimeSettings 物件。這是具版本控制的唯讀內部 生產者/消費者 API 表面:OpenClaw 會為所選的上下文 引擎產生此物件,而上下文引擎會在生命週期鉤子內使用它。它不會 直接呈現給使用者,也不會建立專用的報告介面。

    • schemaVersion:目前為 1
    • runtime:OpenClaw 主機、執行階段模式(normalfallbackdegraded),以及選用的控制框架/執行階段 ID
    • contextEngineSelection:所選的情境引擎 ID 與選取來源
    • executionHost:叫用掛鉤之介面的主機 ID 與標籤
    • model:要求的模型、解析後的模型、提供者,以及選用的模型系列
    • limits:提示詞權杖預算,以及已知時的最大輸出權杖數
    • diagnostics:已知時的封閉式後援與降級原因代碼

    可能未知的欄位會表示為 null;執行階段模式與選取來源等 辨別欄位仍不可為 null。舊版引擎仍維持相容:若嚴格的舊版引擎因 runtimeSettings 是未知屬性而拒絕它,OpenClaw 會在不附帶該屬性的情況下 重試生命週期呼叫,而不是隔離該引擎。

    主機需求

    情境引擎可以在 info.hostRequirements 上宣告主機能力需求。 OpenClaw 會在開始操作前檢查這些需求;若所選執行階段無法滿足需求, 便會以描述性錯誤採取封閉式失敗。

    對於代理程式執行,若引擎必須透過 assemble() 控制 實際的模型提示詞,請宣告 assemble-before-prompt

    ts
    info: {  id: "my-context-engine",  name: "我的情境引擎",  hostRequirements: {    "agent-run": {      requiredCapabilities: ["assemble-before-prompt"],      unsupportedMessage:        "請使用原生 Codex 或 OpenClaw 內嵌執行階段,或選取舊版情境引擎。",    },  },}

    原生 Codex 與 OpenClaw 內嵌代理程式執行符合 assemble-before-prompt。 通用命令列介面後端則不符合,因此需要此能力的引擎會在命令列介面程序 啟動前遭到拒絕。

    失敗隔離

    OpenClaw 會將所選的外掛引擎與核心回覆路徑隔離。若非舊版引擎 不存在、未通過合約驗證、在建立工廠時擲回例外,或從生命週期方法 擲回例外,OpenClaw 會在目前的閘道程序中隔離該引擎,並將情境引擎 工作降級至內建的 legacy 引擎。系統會記錄錯誤及失敗的操作, 讓操作人員能修復、更新或停用外掛,而不會導致代理程式停止回應。

    主機需求失敗的處理方式不同:當引擎宣告某個執行階段缺少必要能力時, OpenClaw 會在開始執行前採取封閉式失敗。這可保護那些若在不受支援的 主機上執行便會損毀狀態的引擎。

    ownsCompaction

    ownsCompaction 控制 OpenClaw 執行階段內建的單次嘗試內自動壓縮是否在該次執行中保持啟用:

    ownsCompaction: true

    引擎負責壓縮行為。OpenClaw 會在該次執行中停用 OpenClaw 執行階段內建的自動壓縮與通用提示詞前溢位預先檢查,而引擎的 compact() 實作則負責 /compact、提供者溢位復原壓縮,以及它想在 afterTurn() 中執行的任何主動壓縮。當引擎從 assemble() 傳回 promptAuthority: "preassembly_may_overflow" 時,OpenClaw 仍會執行提示詞前溢位防護措施。

    ownsCompaction: false 或未設定

    OpenClaw 執行階段內建的自動壓縮仍可能在提示詞執行期間運作,但作用中引擎的 compact() 方法仍會針對 /compact 與溢位復原而被呼叫。

    這表示有兩種有效的外掛模式:

    自主模式

    實作你自己的壓縮演算法,並設定 ownsCompaction: true

    委派模式

    設定 ownsCompaction: false,並讓 compact()openclaw/plugin-sdk/core 呼叫 delegateCompactionToRuntime(...),以使用 OpenClaw 的內建壓縮行為。

    對於作用中的非自主引擎,無操作的 compact() 並不安全,因為它會停用該引擎位置正常的 /compact 與溢位復原壓縮路徑。

    設定參考

    json5
    {  plugins: {    slots: {      // 選取作用中的情境引擎。預設值:"legacy"。      // 設為外掛 ID 以使用外掛引擎。      contextEngine: "legacy",    },  },}

    與壓縮和記憶的關係

    壓縮

    壓縮是情境引擎的職責之一。舊版引擎會委派給 OpenClaw 的內建摘要功能。外掛引擎可以實作任何壓縮策略(DAG 摘要、向量檢索等)。

    記憶外掛

    記憶外掛(plugins.slots.memory)與情境引擎彼此獨立。記憶外掛提供搜尋/檢索;情境引擎控制模型所看到的內容。兩者可以搭配運作——情境引擎可能會在組裝期間使用記憶外掛資料。若外掛引擎想使用作用中的記憶提示詞路徑,應使用 openclaw/plugin-sdk/core 中的 buildMemorySystemPromptAddition(...),它會將主機準備的記憶提示詞區段轉換為可直接前置的 systemPromptAddition,而不會公開記憶外掛的配置。

    工作階段修剪

    無論哪個情境引擎處於作用中,仍會在記憶體內修剪舊的工具結果。

    提示

    • 使用 openclaw doctor 驗證你的引擎是否正確載入。
    • 切換引擎時,現有工作階段會繼續使用其目前的歷程記錄。新引擎會接管後續執行。
    • 系統會記錄引擎錯誤,並在目前的閘道程序中隔離所選的外掛引擎。OpenClaw 會在使用者回合中後援至 legacy,讓回覆得以繼續,但你仍應修復、更新、停用或解除安裝損壞的外掛。
    • 開發時,使用 openclaw plugins install -l ./my-engine 連結本機外掛目錄,無須複製。

    相關內容

    Was this useful?
    On this page

    On this page