AI agent 好不好用,很大程度取決於一件你看不見的事:上下文管理。對話歷史、工具呼叫的結果、外部知識——這些東西怎麼塞進模型那個有限的窗口,決定了 agent 是真能幫上忙,還是一本正經地胡說八道。在 OpenClaw 2026.3.7 之前,這套邏輯是寫死在核心裡的。現在,它是一個外掛。
原來有什麼問題
OpenClaw 之前用的是滑動視窗壓縮:對話太長了,就把舊訊息摘要一下,給新訊息讓路。能跑,但很多人不滿意:
- •壓縮必然丟資訊。寫程式的 agent 要引用 50 輪前寫的函式?摘要裡早就沒了。
- •關了就忘。對話一結束,上下文清零。agent 沒有跨對話的記憶。
- •想換策略沒門。你想用 RAG、想做對話分支、想自己管 token 預算——沒有正經的擴充口,只能 hack。
社群的解決辦法五花八門:monkey-patch 內部模組、fork 核心程式碼、在外面套一層編排。折騰是折騰了,都不是長久之計。
ContextEngine:把上下文管理變成可替換的外掛
2026.3.7 做了一件乾脆的事:把上下文的整個生命週期抽成介面,開放為外掛槽位(slot)。你寫一個外掛,實作這套介面,就能完全接管 agent 的上下文邏輯。
怎麼接入
外掛透過 API 註冊自己的 ContextEngine:
// In your plugin's bootstrap
export default function myContextPlugin(api: PluginAPI) {
api.registerContextEngine('my-engine', (config) => {
return new MyCustomContextEngine(config);
});
}
使用者在設定裡選一下就行:
plugins:
slots:
contextEngine: my-engine
什麼都不設定?照常用。OpenClaw 會套上 LegacyContextEngine,滑動視窗該怎麼跑還怎麼跑,老使用者完全無感。
七個鉤子,管住上下文的一生
ContextEngine 介面給了你七個鉤子,從引擎啟動到子 agent 收工,每個關鍵節點都能插手:
1. `bootstrap()`
引擎初始化時跑一次。連資料庫、建圖結構、載入上次存下來的狀態,都在這兒幹。
async bootstrap(): Promise<void> {
this.vectorStore = await connectToVectorDB(this.config.dbUrl);
this.sessionGraph = new DAG();
}
2. `ingest(message: Message)`
每來一條新訊息就觸發——不管是使用者說的、agent 回的、還是工具吐出來的。你在這裡決定怎麼存、怎麼建索引。
async ingest(message: Message): Promise<void> {
// Add to the DAG
const node = this.sessionGraph.addNode(message);
// Index for retrieval
const embedding = await embed(message.content);
await this.vectorStore.upsert(node.id, embedding, message);
}
3. `assemble(budget: TokenBudget): AssembledContext`
最核心的一個。每次要調模型之前,OpenClaw 會帶著 token 預算來問你:給我組裝上下文。你回傳什麼,模型就看到什麼。
不同的引擎在這裡可以玩出完全不同的花樣:
async assemble(budget: TokenBudget): AssembledContext {
const recentMessages = this.sessionGraph.getRecent(budget.soft * 0.6);
const relevantHistory = await this.vectorStore.query(
this.currentQuery,
budget.soft * 0.3
);
const systemContext = this.buildSystemPrompt(budget.soft * 0.1);
return {
system: systemContext,
messages: [...relevantHistory, ...recentMessages],
tokenEstimate: this.estimateTokens([systemContext, ...relevantHistory, ...recentMessages]),
};
}
4. `compact()`
上下文撐破硬上限了,OpenClaw 喊你來瘦身。預設引擎會摘要舊訊息;你的外掛可以砍掉圖裡不相關的節點,可以往向量庫裡挪,也可以什麼都不做——如果你在 assemble() 裡就已經控制住了。
5. `afterTurn(turn: Turn)`
一輪對話結束(使用者說完、agent 答完)。存個狀態、寫個持久化、跑個背景索引,都適合放這兒。
6. `prepareSubagentSpawn(parentContext: Context): SubagentContext`
agent 要派子 agent 出去幹活了。給多少上下文?全給會撐爆 token,不給又兩眼一抹黑。這個鉤子讓你精確控制子 agent 帶走哪些資訊。
prepareSubagentSpawn(parentContext: Context): SubagentContext {
// Give the subagent a focused slice of context
const relevantNodes = this.sessionGraph.getSubtree(parentContext.taskId);
return {
messages: relevantNodes.map(n => n.message),
metadata: { parentSessionId: this.sessionId },
};
}
7. `onSubagentEnded(result: SubagentResult)`
子 agent 幹完活回來了。它帶回來的結果怎麼合進父級上下文?全收、摘要、還是挑著要?你說了算。
架構細節:slot 不是 hook
ContextEngine 在外掛體系裡是個槽位,不是鉤子。區別在哪?鉤子是疊加的,十個外掛可以同時監聽 onMessage;槽位是排他的,同一時間只能有一個 ContextEngine 在跑。
┌─────────────────────────────────────┐
│ Plugin Registry │
│ │
│ Hooks(可疊加): │
│ onMessage → [plugin1, plugin2] │
│ onTool → [plugin3] │
│ │
│ Slots(只能選一個): │
│ contextEngine → my-engine │
│ (預設: LegacyContextEngine) │
└─────────────────────────────────────┘
啟動時 OpenClaw 讀 plugins.slots.contextEngine 的設定值,找到對應的工廠方法,實例化。找不到?直接報錯退出,不會偷偷回退到預設引擎——這是刻意的設計,避免你以為在用自訂引擎其實跑的是預設的。
子 agent 之間的隔離靠 AsyncLocalStorage:每個子 agent 有自己的執行時作用域,外掛狀態不會串台。
已經有人在用了
Lossless-Claw
GitHub · Martian Engineering 出品
第一個有份量的 ContextEngine 外掛。用基於 DAG 的摘要系統替掉了滑動視窗,做到了在 token 上限內保留每一條原始訊息。
- •每條訊息變成有向無環圖裡的一個節點
- •按話題相關性自動分組成「片段」
- •預算超了,舊片段會被摘要——但原始訊息還留在圖裡
- •後面如果又聊到了舊內容,引擎直接取回原文,不用將就摘要
寫程式的人應該能體會:100 輪前定義的函式,突然又要用了,滑動視窗早就把它壓沒了,Lossless-Claw 還能翻出來。
MemOS Cloud Plugin
GitHub · MemTensor 出品
一個很輕的外掛,就幹一件事:讓 agent 記住你。
- •啟動時從 MemOS Cloud 召回跟當前話題相關的記憶
- •每輪對話結束後把新內容存回去
- •組裝上下文時把記憶注入進來
效果就是:上週聊過的事、你的偏好、你正在做的專案——agent 都記得,不用你每次重複交代。
接下來會冒出什麼
翻翻 GitHub issue 和 Discord,社群已經在搞這些:
- •RAG 原生組裝:不再拼訊息歷史,直接用檢索到的文件片段組裝上下文。OpenClaw 秒變對話式搜尋引擎。
- •多 agent 共享記憶:幾個 agent 共用一張知識圖譜,協作幹活時不用重複同步資訊。
- •Token 預算自動調配:根據你用的模型貴不貴、快不快,動態調整上下文怎麼分配。
- •對話分支:樹狀結構,一條對話岔出去探索不同方向,隨時切回來,歷史不丟。
這件事為什麼重要
OpenClaw 之前能加頻道、加模型、加工具,但上下文這一層——說白了就是 agent 的「腦子怎麼運轉」——一直是個碰不得的黑盒。
ContextEngine 把這個盒子撬開了。往後的事情會一環扣一環:
- 1.外掛開發者終於能在 agent 體驗裡最難也最值錢的地方發力了——上下文品質。
- 2.企業使用者可以做合規:資料到模型之前先脫敏、留存策略強制執行、每個 prompt 輸入了什麼全程可稽核。
- 3.研究者驗證新的上下文策略,再也不用 fork 整個專案。
- 4.模型廠商可以出官方外掛,針對自家架構最佳化上下文組裝——長視窗模型和短視窗模型,策略本來就該不一樣。
這就是從框架變成平台的樣子。不靠改名,不靠發公告,靠的是一個實實在在的架構改動,讓生態開始自己轉起來。外掛越多 → 使用者越多 → 開發者越多 → 外掛更多。飛輪一旦轉起來,就很難停下了。
龍蝦又長出了一隻新鉗子。