OpenClaw + OpenViking 高可用上下文引擎技术方案
版本: v1.0 | 日期: 2026-03-10 | 作者: wairesearch
状态: 提案 (Proposal)
目录
- 价值和意义 — 为什么 AI Agent 需要高可用上下文引擎
- 方案总览
- OpenClaw Context Engine 接口详解
- OpenViking 架构深度分析
- 集成方案设计
- 高可用架构设计
- 风险评估与缓解
- 附录
1. 价值和意义 — 为什么 AI Agent 需要高可用上下文引擎
1.1 从”健忘助手”到”可靠伙伴”:AI Agent 的记忆困局
今天的 AI Agent 正在从”单次问答工具”演进为”长期协作伙伴”。用户期望 Agent 能记住三个月前的架构决策、理解项目的演化脉络、在多 Agent 团队中共享工作记忆。然而现实却远远落后于期望——大多数 Agent 仍然是”健忘”的。
每一次新会话开启,Agent 都像失忆患者一样从零开始。用户被迫反复解释相同的上下文,Agent 反复犯相同的错误,团队中的多个 Agent 彼此割裂、无法共享认知。这不是 AI 能力的问题,而是基础设施的缺失。
AI Agent 要真正成为”可靠伙伴”,需要的不仅仅是更大的上下文窗口或更好的 RAG 检索——它需要一个工业级的、高可用的上下文引擎。
1.2 当前 Agent 记忆系统的四大痛点
| 痛点 | 现状 | 后果 |
|---|---|---|
| 碎片化 | 记忆散落在会话日志、Markdown 文件、向量数据库等多个系统中,缺乏统一的组织范式 | Agent 无法形成完整认知,同一信息被重复存储却无法有效检索 |
| 不可靠 | 大部分记忆方案基于单机文件系统,没有冗余、没有备份、没有故障转移 | 一次服务器崩溃就可能丢失数月积累的 Agent 记忆,项目上下文灰飞烟灭 |
| Token 浪费 | 传统 RAG 采用扁平化存储,检索时返回大量低相关度内容塞入上下文窗口 | 每次推理调用消耗大量无效 Token,成本飙升而效果不佳 |
| 孤岛效应 | 多 Agent 系统中,每个 Agent 各自为政,无法读取同伴的工作记忆 | 协调者需要在 Agent 之间手动传递信息,协作效率低下 |
这四个痛点叠加在一起,导致了一个根本矛盾:Agent 的记忆能力远远跟不上其推理能力的进化速度。
1.3 本方案解决的根本问题
本方案通过将 OpenClaw 的 pluggable Context Engine 与 OpenViking 上下文数据库深度集成,从根本上解决上述四大痛点:
-
统一范式,消除碎片化 — OpenViking 的文件系统范式(
viking://)将 Memory、Resource、Skill 统一组织在层级化的 URI 命名空间下,Agent 的所有认知形成一棵结构清晰的知识树,而非散落的碎片。 -
三级加载,终结 Token 浪费 — L0/L1/L2 三级按需加载机制彻底改变了”全量灌入上下文窗口”的粗暴模式。先用 ~100 Token 的摘要做向量匹配,再用 ~2K Token 的概览做语义重排,只在真正需要时才加载完整内容。Token 成本直降 91%。
-
共享存储 + 多实例部署,实现 99.9% 可用性 — 通过 S3/NFS 后端 + 主备实例 + 自动故障转移,将 Agent 记忆从脆弱的单机文件提升为工业级高可用服务。故障切换时间 < 15 秒,可用性达 99.9%。
-
多 Agent 共享命名空间,打破孤岛 — 5 个 Agent(main/waicode/waidesign/wairesearch/waiqa)共享同一上下文数据库,通过 URI 命名空间实现隔离与共享的平衡。waicode 发现的 bug 模式,wairesearch 可以立即检索到。
1.4 量化价值
基于 OpenViking 官方 LoCoMo10 评测(1,540 个案例)的实测数据:
| 指标 | 基线 (memory-core) | 集成 OpenViking 后 | 提升幅度 |
|---|---|---|---|
| 任务完成率 | 35.65% | 51.23% - 52.08% | +43% ~ +46% |
| 输入 Token 消耗 | 24,611,530 | 2,099,622 - 4,264,396 | -83% ~ -91% |
| 系统可用性 | 单机无冗余 | 主备 + 自动故障转移 | 99.9% |
| 故障恢复时间 | 手动恢复(小时级) | 自动切换 < 15s | 秒级 |
这不只是技术指标的提升。Token 成本降低 91% 意味着同样的预算可以支撑 11 倍的 Agent 交互量;任务完成率提升 43% 意味着Agent 从”勉强可用”跨越到”真正可靠”;99.9% 可用性意味着Agent 记忆成为可以信赖的基础设施,而不是随时可能消失的脆弱状态。
1.5 对 AI Agent 生态的意义
这个方案的意义超越了 OpenClaw 自身:
- 为 Agent 记忆树立工业级标准 — 三级加载 + HA 部署 + 共享命名空间,定义了 Agent 上下文管理应有的工程水准
- 让多 Agent 协作成为可能 — 共享记忆层是多 Agent 团队从”松散协调”走向”深度协作”的基础设施
- 降低 Agent 部署的运维风险 — 自动故障转移和增量备份让生产环境部署 Agent 不再是冒险行为
- 推动 Agent 从工具走向伙伴 — 当 Agent 拥有了可靠的、高效的、可共享的长期记忆,它才真正具备成为”伙伴”的基础能力
2. 方案总览
核心价值回扣:本节呈现方案的整体架构视图——一个统一的、高可用的、多 Agent 共享的上下文引擎,正是解决上述四大痛点的技术载体。
本方案通过 OpenClaw 的 pluggable Context Engine 机制与 OpenViking 上下文数据库深度集成,实现:
- 统一上下文管理:Memory/Resource/Skill 通过文件系统范式统一组织
- 三级按需加载:L0/L1/L2 层级控制 token 消耗,降低 83-96% 输入 token 成本
- 高可用存储:通过 S3/NFS 后端 + 多实例部署,消除单点故障
- 多 Agent 共享:5 个 Agent(main/waicode/waidesign/wairesearch/waiqa)共享同一上下文数据库
- 自动故障转移:主从复制 + 健康检查 + 自动切换
目标架构总览
┌──────────────────────────────────────────────────────────────────┐
│ OpenClaw Gateway │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐ │
│ │ main │ │ waicode │ │waidesign │ │wairesearch│ │ waiqa │ │
│ │ Agent │ │ Agent │ │ Agent │ │ Agent │ │ Agent │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └───┬────┘ │
│ │ │ │ │ │ │
│ ┌────▼─────────────▼────────────▼─────────────▼────────────▼──┐ │
│ │ OpenViking Context Engine Plugin │ │
│ │ (implements ContextEngine interface: ingest/assemble/compact)│ │
│ └──────────────────────┬──────────────────────────────────────┘ │
│ │ │
│ ┌──────────────────────▼──────────────────────────────────────┐ │
│ │ OpenViking Memory Slot Plugin │ │
│ │ (memory_recall / memory_store / memory_forget tools) │ │
│ └──────────────────────┬──────────────────────────────────────┘ │
└──────────────────────────┼─────────────────────────────────────────┘
│ HTTP API (:1933)
┌────────────▼────────────┐
│ Load Balancer / VIP │
└─────┬──────────┬────────┘
│ │
┌─────────▼──┐ ┌───▼──────────┐
│ OpenViking │ │ OpenViking │
│ Primary │ │ Standby │
│ Instance │ │ Instance │
└─────┬──────┘ └──────┬────────┘
│ │
┌─────▼────────────────▼────────┐
│ Shared Storage Layer │
│ (S3 / NFS / Distributed FS) │
│ ┌─────────┐ ┌────────────┐ │
│ │ AGFS │ │Vector Index│ │
│ │ Content │ │ (Dense + │ │
│ │ Storage │ │ Sparse) │ │
│ └─────────┘ └────────────┘ │
└────────────────────────────────┘
3. OpenClaw Context Engine 接口详解
核心价值回扣:Context Engine 是 OpenClaw 实现”统一上下文管理”和”三级按需加载”的接口契约。正是这个 pluggable 架构,使得我们可以将 OpenViking 的高效记忆检索无缝接入 Agent 运行时,从根本上解决 Token 浪费和记忆碎片化问题。
3.1 接口概述
OpenClaw 通过 plugins.slots.contextEngine 配置项选择活跃的 Context Engine。默认使用内置的 legacy 引擎。自定义引擎通过插件注册:
api.registerContextEngine("openviking", () => new OpenVikingContextEngine(config));
3.2 ContextEngine 接口定义
源码位置:/usr/lib/node_modules/openclaw/dist/plugin-sdk/context-engine/types.d.ts
interface ContextEngine {
/** 引擎元信息 */
readonly info: ContextEngineInfo;
/** 初始化引擎状态,可导入历史上下文 */
bootstrap?(params: {
sessionId: string;
sessionFile: string;
}): Promise<BootstrapResult>;
/** 写入单条消息到引擎存储 */
ingest(params: {
sessionId: string;
message: AgentMessage;
isHeartbeat?: boolean;
}): Promise<IngestResult>;
/** 批量写入一个完整 turn */
ingestBatch?(params: {
sessionId: string;
messages: AgentMessage[];
isHeartbeat?: boolean;
}): Promise<IngestBatchResult>;
/** Turn 完成后的生命周期处理(持久化、后台压缩等) */
afterTurn?(params: {
sessionId: string;
sessionFile: string;
messages: AgentMessage[];
prePromptMessageCount: number;
autoCompactionSummary?: string;
isHeartbeat?: boolean;
tokenBudget?: number;
runtimeContext?: ContextEngineRuntimeContext;
}): Promise<void>;
/** 在 token 预算内组装模型上下文 */
assemble(params: {
sessionId: string;
messages: AgentMessage[];
tokenBudget?: number;
}): Promise<AssembleResult>;
/** 压缩上下文以减少 token 使用 */
compact(params: {
sessionId: string;
sessionFile: string;
tokenBudget?: number;
force?: boolean;
currentTokenCount?: number;
compactionTarget?: "budget" | "threshold";
customInstructions?: string;
runtimeContext?: ContextEngineRuntimeContext;
}): Promise<CompactResult>;
/** 为子代理准备上下文状态 */
prepareSubagentSpawn?(params: {
parentSessionKey: string;
childSessionKey: string;
ttlMs?: number;
}): Promise<SubagentSpawnPreparation | undefined>;
/** 子代理生命周期结束通知 */
onSubagentEnded?(params: {
childSessionKey: string;
reason: SubagentEndReason;
}): Promise<void>;
/** 释放资源 */
dispose?(): Promise<void>;
}
3.3 核心方法详解
ingest() — 消息写入
| 参数 | 类型 | 说明 |
|---|---|---|
sessionId |
string | 会话 ID |
message |
AgentMessage | 单条消息(user/assistant/tool) |
isHeartbeat |
boolean? | 是否心跳消息 |
返回 IngestResult { ingested: boolean } — 是否成功写入(去重时可返回 false)。
设计要点:
- Legacy 引擎的
ingest是 no-op(SessionManager 自行处理持久化) - 自定义引擎应将消息转发到 OpenViking 的 Session API
assemble() — 上下文组装
| 参数 | 类型 | 说明 |
|---|---|---|
sessionId |
string | 会话 ID |
messages |
AgentMessage[] | 当前所有消息 |
tokenBudget |
number? | Token 预算上限 |
返回:
type AssembleResult = {
messages: AgentMessage[]; // 排序后的模型上下文消息
estimatedTokens: number; // 估算总 token 数
systemPromptAddition?: string; // 注入到系统提示的额外内容
};
设计要点:
- 这是集成 L0/L1/L2 三级加载的关键入口
- 可通过
systemPromptAddition注入 OpenViking 检索到的记忆
compact() — 上下文压缩
| 参数 | 类型 | 说明 |
|---|---|---|
sessionId |
string | 会话 ID |
sessionFile |
string | 会话 JSONL 文件路径 |
tokenBudget |
number? | 目标 token 预算 |
force |
boolean? | 是否强制压缩 |
currentTokenCount |
number? | 当前 token 数 |
compactionTarget |
string? | 压缩目标模式 |
返回:
type CompactResult = {
ok: boolean;
compacted: boolean;
reason?: string;
result?: {
summary?: string;
firstKeptEntryId?: string;
tokensBefore: number;
tokensAfter?: number;
details?: unknown;
};
};
设计要点:
- 当
info.ownsCompaction = true时,引擎完全接管压缩生命周期 - OpenViking 的 Session Compressor 天然适配此接口
3.4 注册机制
// registry.d.ts
type ContextEngineFactory = () => ContextEngine | Promise<ContextEngine>;
function registerContextEngine(id: string, factory: ContextEngineFactory): void;
function resolveContextEngine(config?: OpenClawConfig): Promise<ContextEngine>;
配置激活:
{
"plugins": {
"slots": {
"contextEngine": "openviking-context"
}
}
}
3.5 插件清单 (openclaw.plugin.json)
{
"id": "openviking-context",
"kind": "context-engine",
"name": "OpenViking Context Engine",
"description": "Three-tier context assembly with OpenViking backend",
"configSchema": {
"type": "object",
"additionalProperties": false,
"properties": {
"mode": {
"type": "string",
"enum": ["local", "remote"],
"default": "remote"
},
"baseUrl": {
"type": "string",
"default": "http://localhost:1933"
},
"apiKey": {
"type": "string"
},
"l1TokenBudget": {
"type": "number",
"default": 2000
},
"autoCompact": {
"type": "boolean",
"default": true
}
}
}
}
4. OpenViking 架构深度分析
核心价值回扣:OpenViking 是实现”Token 成本 -91%”的核心引擎。它的 L0/L1/L2 三级加载机制和文件系统范式,正是将”粗暴的全量检索”转变为”精准的按需加载”的技术基础,同时也是多 Agent 共享记忆的统一数据层。
4.1 系统架构
┌────────────────────────────────────────────────────────┐
│ OpenViking Server (:1933) │
│ │
│ ┌────────────┐ ┌──────────────┐ ┌────────────────┐ │
│ │ Retrieve │ │ Session │ │ Parse │ │
│ │ Module │ │ Module │ │ Module │ │
│ │ │ │ │ │ │ │
│ │ • Intent │ │ • Add msg │ │ • Doc parsing │ │
│ │ Analysis │ │ • Commit │ │ • L0/L1/L2 │ │
│ │ • Hierarch.│ │ • Extract │ │ • Tree build │ │
│ │ Retrieval│ │ memories │ │ │ │
│ │ • Rerank │ │ • Compress │ │ │ │
│ └─────┬──────┘ └──────┬───────┘ └───────┬────────┘ │
│ │ │ │ │
│ ┌─────▼─────────────────▼───────────────────▼────────┐ │
│ │ Storage Layer │ │
│ │ ┌──────────────────┐ ┌─────────────────────────┐ │ │
│ │ │ AGFS │ │ Vector Index │ │ │
│ │ │ (File Content) │ │ (URI + Vector + Meta) │ │ │
│ │ │ │ │ │ │ │
│ │ │ Backends: │ │ Backends: │ │ │
│ │ │ • localfs │ │ • local │ │ │
│ │ │ • s3fs │ │ • http │ │ │
│ │ │ • memory │ │ • volcengine VikingDB │ │ │
│ │ └──────────────────┘ └─────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────┘
4.2 L0/L1/L2 三级上下文加载机制
这是 OpenViking 的核心创新,也是实现 Token 消耗降低 91% 的关键技术。对比传统 RAG 的扁平存储,三级加载实现了”用 1% 的 Token 完成 100% 的检索精度”:
| 层级 | 名称 | 文件 | Token 限制 | 用途 |
|---|---|---|---|---|
| L0 | Abstract | .abstract.md |
~100 tokens | 向量检索 + 快速过滤 |
| L1 | Overview | .overview.md |
~2k tokens | 重排序 + 内容导航 |
| L2 | Detail | 原始文件 | 无限制 | 完整内容,按需加载 |
加载策略:
Query → L0 向量匹配 → L1 语义重排 → L2 按需读取
↓ ↓ ↓
~100 tok ~2k tok 完整内容
目录结构示例:
viking://user/memories/
├── .abstract.md # L0: "用户偏好:中文沟通,TypeScript 开发"
├── .overview.md # L1: 详细偏好列表 + 子目录导航
├── preferences/
│ ├── .abstract.md
│ ├── .overview.md
│ └── coding-style.md # L2: 完整编码风格文档
└── decisions/
├── .abstract.md
├── .overview.md
└── arch-2026-01.md # L2: 2026年1月架构决策
这种层级结构让 Agent 像人类浏览目录一样逐层深入,而不是把整个图书馆搬进对话窗口。
4.3 文件系统范式
OpenViking 用 viking:// URI 统一管理三种上下文类型,消除记忆碎片化的核心就在于这个统一的寻址方案:
| URI Scheme | 上下文类型 | 说明 |
|---|---|---|
viking://user/ |
用户记忆 | 偏好、历史、决策 |
viking://agent/ |
Agent 记忆 | 技能、工作区、指令 |
viking://resources/ |
资源 | 文档、代码、知识库 |
4.4 HTTP API 接口 (端口 1933)
核心 API 端点:
| 类别 | Method | Path | 说明 |
|---|---|---|---|
| 系统 | GET | /health |
健康检查(无需认证) |
| 系统 | GET | /api/v1/system/status |
系统状态 |
| 文件系统 | GET | /api/v1/fs/ls |
目录列表 |
| 文件系统 | GET | /api/v1/fs/tree |
目录树 |
| 文件系统 | DELETE | /api/v1/fs |
删除资源 |
| 内容 | GET | /api/v1/content/read |
读取完整内容 (L2) |
| 内容 | GET | /api/v1/content/abstract |
读取摘要 (L0) |
| 内容 | GET | /api/v1/content/overview |
读取概览 (L1) |
| 检索 | POST | /api/v1/search/find |
语义搜索 |
| 会话 | POST | /api/v1/sessions |
创建会话 |
| 会话 | POST | /api/v1/sessions/:id/messages |
添加消息 |
| 会话 | POST | /api/v1/sessions/:id/extract |
提取记忆 |
| 资源 | POST | /api/v1/resources |
导入资源 |
| 导出 | POST | /api/v1/pack/export |
导出 .ovpack |
| 导入 | POST | /api/v1/pack/import |
导入 .ovpack |
认证:
- Header:
X-API-Key: your-key或Authorization: Bearer your-key /health端点不需要认证
响应格式:
{
"status": "ok",
"result": { ... },
"time": 0.123
}
4.5 现有 Memory 插件分析
现有 memory-openviking 插件实现了 Memory Slot(kind: "memory"),注册了三个工具:
| 工具 | 功能 |
|---|---|
memory_recall |
语义搜索记忆,同时检索 user/agent 两个 scope |
memory_store |
创建临时 session → 添加消息 → 提取记忆 → 清理 |
memory_forget |
按 URI 或搜索匹配删除记忆 |
关键特性:
- 支持
local和remote两种模式 - Local 模式自动启动 OpenViking Python 进程
- Auto-recall:在
before_prompt_buildhook 中自动检索相关记忆 - Auto-capture:在
after_compactionhook 中自动提取新记忆
5. 集成方案设计
核心价值回扣:本节是”怎么做”的核心——通过 Context Engine + Memory Slot 双层集成,将 OpenViking 的能力无缝融入 Agent 运行时。这一集成使得每次 Agent 调用都自动享受三级加载的 Token 优化和跨 Agent 记忆共享,无需 Agent 自身做任何适配。
5.1 双层集成架构
我们采用 Context Engine + Memory Slot 双层集成:
┌─────────────────────────────────────────────────┐
│ OpenClaw Agent Runtime │
│ │
│ 每次 Agent Run: │
│ 1. assemble() ← Context Engine 组装上下文 │
│ ├─ 注入 L1 概览作为 systemPromptAddition │
│ ├─ 基于 token budget 智能裁剪历史消息 │
│ └─ 附加相关记忆摘要 │
│ │
│ 2. ingest() ← 每条消息写入 OpenViking Session │
│ │
│ 3. afterTurn() ← Turn 完成后触发 │
│ ├─ 持久化 canonical context │
│ └─ 触发后台压缩决策 │
│ │
│ 4. compact() ← Token 超预算或 /compact 触发 │
│ ├─ 委托 OpenViking Session Compressor │
│ ├─ 压缩历史 → 生成 L0/L1 归档 │
│ └─ 提取长期记忆写入 memory store │
│ │
│ 独立工具调用: │
│ • memory_recall → 显式语义搜索 │
│ • memory_store → 显式存储记忆 │
│ • memory_forget → 删除记忆 │
└─────────────────────────────────────────────────────┘
5.2 Context Engine 插件实现
// openviking-context-engine/index.ts
import type {
OpenClawPluginApi,
OpenClawPluginDefinition,
} from "openclaw/plugin-sdk";
import type {
ContextEngine,
ContextEngineInfo,
AssembleResult,
CompactResult,
IngestResult,
IngestBatchResult,
BootstrapResult,
} from "openclaw/plugin-sdk/context-engine";
import type { AgentMessage } from "@mariozechner/pi-agent-core";
// ─── Configuration ─────────────────────────────────────
interface OpenVikingContextConfig {
mode: "local" | "remote";
baseUrl: string;
apiKey?: string;
agentId?: string;
/** L1 token budget for assemble() systemPromptAddition */
l1TokenBudget: number;
/** Whether to auto-compact via OpenViking */
autoCompact: boolean;
/** Threshold ratio to trigger compaction (e.g., 0.85 = 85% of budget) */
compactThreshold: number;
/** Max memories to inject per assemble */
maxMemoryInjection: number;
}
// ─── HTTP Client (simplified) ─────────────────────────
class OVClient {
constructor(
private baseUrl: string,
private apiKey?: string,
private agentId?: string,
) {}
private async request<T>(path: string, init?: RequestInit): Promise<T> {
const headers = new Headers(init?.headers ?? {});
if (this.apiKey) headers.set("X-API-Key", this.apiKey);
if (this.agentId) headers.set("X-OpenViking-Agent", this.agentId);
if (init?.body) headers.set("Content-Type", "application/json");
const res = await fetch(`${this.baseUrl}${path}`, { ...init, headers });
const payload = await res.json() as { status?: string; result?: T };
if (!res.ok || payload.status === "error") {
throw new Error(`OpenViking error: HTTP ${res.status}`);
}
return (payload.result ?? payload) as T;
}
async health(): Promise<void> {
await this.request("/health");
}
async createSession(): Promise<string> {
const r = await this.request<{ session_id: string }>("/api/v1/sessions", {
method: "POST", body: JSON.stringify({}),
});
return r.session_id;
}
async addMessage(sessionId: string, role: string, content: string): Promise<void> {
await this.request(`/api/v1/sessions/${sessionId}/messages`, {
method: "POST", body: JSON.stringify({ role, content }),
});
}
async extractMemories(sessionId: string): Promise<unknown[]> {
return this.request(`/api/v1/sessions/${sessionId}/extract`, {
method: "POST", body: JSON.stringify({}),
});
}
async find(query: string, targetUri: string, limit: number): Promise<{
memories?: Array<{ uri: string; abstract?: string; score?: number; level?: number }>;
}> {
return this.request("/api/v1/search/find", {
method: "POST",
body: JSON.stringify({ query, target_uri: targetUri, limit }),
});
}
async overview(uri: string): Promise<string> {
return this.request(`/api/v1/content/overview?uri=${encodeURIComponent(uri)}`);
}
async abstract(uri: string): Promise<string> {
return this.request(`/api/v1/content/abstract?uri=${encodeURIComponent(uri)}`);
}
async deleteSession(sessionId: string): Promise<void> {
await this.request(`/api/v1/sessions/${sessionId}`, { method: "DELETE" });
}
}
// ─── Context Engine Implementation ────────────────────
class OpenVikingContextEngine implements ContextEngine {
readonly info: ContextEngineInfo = {
id: "openviking-context",
name: "OpenViking Context Engine",
version: "1.0.0",
ownsCompaction: true, // 引擎接管压缩生命周期
};
private client: OVClient;
private sessionMap = new Map<string, string>(); // openclawSessionId → ovSessionId
private cfg: OpenVikingContextConfig;
constructor(config: OpenVikingContextConfig) {
this.cfg = config;
this.client = new OVClient(config.baseUrl, config.apiKey, config.agentId);
}
// ── bootstrap: 初始化 OpenViking session ──
async bootstrap(params: {
sessionId: string;
sessionFile: string;
}): Promise<BootstrapResult> {
try {
const ovSessionId = await this.client.createSession();
this.sessionMap.set(params.sessionId, ovSessionId);
return { bootstrapped: true, importedMessages: 0 };
} catch (err) {
return { bootstrapped: false, reason: String(err) };
}
}
// ── ingest: 写入消息到 OpenViking session ──
async ingest(params: {
sessionId: string;
message: AgentMessage;
isHeartbeat?: boolean;
}): Promise<IngestResult> {
if (params.isHeartbeat) return { ingested: false };
const ovSessionId = await this.ensureOVSession(params.sessionId);
const role = this.mapRole(params.message);
const content = this.extractContent(params.message);
if (!content) return { ingested: false };
await this.client.addMessage(ovSessionId, role, content);
return { ingested: true };
}
// ── ingestBatch: 批量写入 ──
async ingestBatch(params: {
sessionId: string;
messages: AgentMessage[];
isHeartbeat?: boolean;
}): Promise<IngestBatchResult> {
if (params.isHeartbeat) return { ingestedCount: 0 };
let count = 0;
for (const msg of params.messages) {
const result = await this.ingest({
sessionId: params.sessionId,
message: msg,
isHeartbeat: false,
});
if (result.ingested) count++;
}
return { ingestedCount: count };
}
// ── assemble: 核心 — 三级加载组装上下文 ──
async assemble(params: {
sessionId: string;
messages: AgentMessage[];
tokenBudget?: number;
}): Promise<AssembleResult> {
const budget = params.tokenBudget ?? 128000;
const reservedForMemory = Math.min(this.cfg.l1TokenBudget, budget * 0.15);
// 1. 提取最新用户消息作为检索 query
const query = this.extractLatestUserQuery(params.messages);
let memoryAddition = "";
if (query) {
// 2. L0 级检索:快速语义匹配
const results = await this.client.find(
query,
"viking://user/memories",
this.cfg.maxMemoryInjection * 3,
);
if (results.memories && results.memories.length > 0) {
// 3. 取 top-N,用 L1 概览丰富上下文
const topMemories = results.memories
.filter(m => m.level === 2)
.slice(0, this.cfg.maxMemoryInjection);
const memoryTexts: string[] = [];
let tokenUsed = 0;
for (const mem of topMemories) {
const text = mem.abstract ?? "";
const estimatedTokens = text.length / 4;
if (tokenUsed + estimatedTokens > reservedForMemory) break;
memoryTexts.push(`- ${text}`);
tokenUsed += estimatedTokens;
}
if (memoryTexts.length > 0) {
memoryAddition = [
"\n## Recalled Memories (OpenViking)",
...memoryTexts,
].join("\n");
}
}
}
// 4. 裁剪消息列表到 token budget
const messagesForContext = this.trimMessages(
params.messages,
budget - reservedForMemory,
);
return {
messages: messagesForContext,
estimatedTokens: this.estimateTokens(messagesForContext) +
(memoryAddition.length / 4),
systemPromptAddition: memoryAddition || undefined,
};
}
// ── afterTurn: Turn 完成后的后台处理 ──
async afterTurn(params: {
sessionId: string;
sessionFile: string;
messages: AgentMessage[];
prePromptMessageCount: number;
tokenBudget?: number;
}): Promise<void> {
// 评估是否需要后台压缩
if (!this.cfg.autoCompact) return;
const budget = params.tokenBudget ?? 128000;
const currentTokens = this.estimateTokens(params.messages);
const threshold = budget * this.cfg.compactThreshold;
if (currentTokens > threshold) {
// 异步触发压缩,不阻塞当前 turn
this.compact({
sessionId: params.sessionId,
sessionFile: params.sessionFile,
tokenBudget: budget,
}).catch(() => { /* logged internally */ });
}
}
// ── compact: 委托 OpenViking 压缩 + 提取记忆 ──
async compact(params: {
sessionId: string;
sessionFile: string;
tokenBudget?: number;
force?: boolean;
}): Promise<CompactResult> {
const ovSessionId = this.sessionMap.get(params.sessionId);
if (!ovSessionId) {
return { ok: false, compacted: false, reason: "No OpenViking session" };
}
try {
// 1. 触发记忆提取
const extracted = await this.client.extractMemories(ovSessionId);
// 2. 创建新 session(压缩后的干净 session)
const newOvSession = await this.client.createSession();
// 3. 迁移 session 映射
const oldSession = ovSessionId;
this.sessionMap.set(params.sessionId, newOvSession);
// 4. 清理旧 session
await this.client.deleteSession(oldSession).catch(() => {});
return {
ok: true,
compacted: true,
result: {
summary: `Extracted ${extracted.length} memories, session rotated`,
tokensBefore: params.tokenBudget ?? 0,
tokensAfter: 0,
details: { extractedCount: extracted.length },
},
};
} catch (err) {
return {
ok: false,
compacted: false,
reason: String(err),
};
}
}
// ── prepareSubagentSpawn: 子代理上下文准备 ──
async prepareSubagentSpawn(params: {
parentSessionKey: string;
childSessionKey: string;
ttlMs?: number;
}) {
// 为子代理创建独立 OpenViking session
// 但共享同一个 user/agent memory space
const childOvSession = await this.client.createSession();
this.sessionMap.set(params.childSessionKey, childOvSession);
return {
rollback: async () => {
this.sessionMap.delete(params.childSessionKey);
await this.client.deleteSession(childOvSession).catch(() => {});
},
};
}
// ── onSubagentEnded: 子代理结束 ──
async onSubagentEnded(params: { childSessionKey: string }) {
const ovSession = this.sessionMap.get(params.childSessionKey);
if (ovSession) {
// 提取子代理产生的记忆到共享空间
await this.client.extractMemories(ovSession).catch(() => {});
await this.client.deleteSession(ovSession).catch(() => {});
this.sessionMap.delete(params.childSessionKey);
}
}
// ── dispose ──
async dispose(): Promise<void> {
for (const [key, ovSession] of this.sessionMap) {
await this.client.deleteSession(ovSession).catch(() => {});
}
this.sessionMap.clear();
}
// ── Private helpers ──
private async ensureOVSession(sessionId: string): Promise<string> {
let ovSession = this.sessionMap.get(sessionId);
if (!ovSession) {
ovSession = await this.client.createSession();
this.sessionMap.set(sessionId, ovSession);
}
return ovSession;
}
private mapRole(msg: AgentMessage): string {
const role = (msg as { role?: string }).role;
if (role === "assistant") return "assistant";
if (role === "tool") return "tool";
return "user";
}
private extractContent(msg: AgentMessage): string {
const content = (msg as { content?: unknown }).content;
if (typeof content === "string") return content;
if (Array.isArray(content)) {
return content
.map((c: { text?: string; type?: string }) =>
c.type === "text" ? c.text ?? "" : "")
.join("\n");
}
return "";
}
private extractLatestUserQuery(messages: AgentMessage[]): string | null {
for (let i = messages.length - 1; i >= 0; i--) {
const msg = messages[i] as { role?: string };
if (msg.role === "user") {
return this.extractContent(messages[i] as AgentMessage);
}
}
return null;
}
private trimMessages(
messages: AgentMessage[],
tokenBudget: number,
): AgentMessage[] {
// 简单策略:保留最新消息直到 budget 用完
const result: AgentMessage[] = [];
let tokens = 0;
for (let i = messages.length - 1; i >= 0; i--) {
const content = this.extractContent(messages[i] as AgentMessage);
const msgTokens = content.length / 4;
if (tokens + msgTokens > tokenBudget && result.length > 0) break;
result.unshift(messages[i]!);
tokens += msgTokens;
}
return result;
}
private estimateTokens(messages: AgentMessage[]): number {
return messages.reduce((sum, msg) => {
return sum + this.extractContent(msg).length / 4;
}, 0);
}
}
// ─── Plugin Definition ─────────────────────────────────
const plugin: OpenClawPluginDefinition = {
id: "openviking-context",
name: "OpenViking Context Engine",
description: "Three-tier context assembly powered by OpenViking",
kind: "context-engine",
register(api: OpenClawPluginApi) {
const config = api.pluginConfig as OpenVikingContextConfig;
const defaults: OpenVikingContextConfig = {
mode: "remote",
baseUrl: "http://localhost:1933",
l1TokenBudget: 2000,
autoCompact: true,
compactThreshold: 0.85,
maxMemoryInjection: 10,
...config,
};
api.registerContextEngine(
"openviking-context",
() => new OpenVikingContextEngine(defaults),
);
api.logger.info(
`openviking-context: registered (mode=${defaults.mode}, baseUrl=${defaults.baseUrl})`,
);
},
};
export default plugin;
5.3 多 Agent 共享上下文方案
多 Agent 共享记忆是打破”孤岛效应”的关键。通过统一的 URI 命名空间,5 个 Agent 既能共享用户级记忆,又能保持各自工作记忆的独立性:
┌──────────────────────────────────────────────────────────────────┐
│ OpenViking URI Namespace │
│ │
│ viking://user/{userId}/ │
│ ├── memories/ ← 所有 Agent 共享的用户记忆 │
│ │ ├── preferences/ ← 用户偏好 │
│ │ ├── decisions/ ← 架构/产品决策 │
│ │ └── context/ ← 项目上下文 │
│ │ │
│ viking://agent/{agentHash}/ │
│ ├── memories/ ← Agent 专属记忆 │
│ │ ├── main/ ← Coordinator 的任务协调记忆 │
│ │ ├── waicode/ ← 编码经验、bug 模式 │
│ │ ├── waidesign/ ← 设计规范、UI 模式 │
│ │ ├── wairesearch/ ← 研究结论、技术选型 │
│ │ └── waiqa/ ← 测试策略、质量标准 │
│ ├── skills/ ← Agent 技能定义 │
│ ├── instructions/ ← Agent 工作指令 │
│ └── workspaces/ ← 工作区上下文 │
│ │
│ viking://resources/ │
│ ├── codebase/ ← 代码库知识 │
│ ├── docs/ ← 技术文档 │
│ └── designs/ ← 设计文档 │
└──────────────────────────────────────────────────────────────────┘
Agent ID 隔离方案:
每个 Agent 连接 OpenViking 时使用不同的 X-OpenViking-Agent header:
// OpenClaw 配置 - 每个 agent 独立的 pluginConfig 覆盖
// ~/.openclaw/openclaw.json
{
"agents": {
"main": {
"plugins": {
"entries": {
"openviking-context": {
"config": { "agentId": "main" }
}
}
}
},
"waicode": {
"plugins": {
"entries": {
"openviking-context": {
"config": { "agentId": "waicode" }
}
}
}
}
// ... 其他 agent 类似
}
}
跨 Agent 记忆共享机制:
Agent 写入流程:
waicode ingest("found a bug pattern in auth module")
→ OpenViking Session → Extract → viking://agent/{hash}/memories/waicode/
Agent 读取流程 (assemble):
main assemble()
→ find("auth module")
→ 搜索 viking://user/memories + viking://agent/memories
→ 返回所有 Agent 的相关记忆(包括 waicode 发现的 bug 模式)
5.4 配置示例
完整 OpenClaw 配置
// ~/.openclaw/openclaw.json
{
"plugins": {
"enabled": true,
"slots": {
"memory": "memory-openviking", // Memory 工具层
"contextEngine": "openviking-context" // Context Engine 层
},
"entries": {
// Layer 1: Memory Plugin (工具 + auto-recall/capture)
"memory-openviking": {
"config": {
"mode": "remote",
"baseUrl": "http://openviking-lb:1933",
"apiKey": "${OPENVIKING_API_KEY}",
"autoRecall": true,
"autoCapture": true,
"recallLimit": 15,
"recallScoreThreshold": 0.3,
"targetUri": "viking://user/memories"
}
},
// Layer 2: Context Engine (assemble/compact 生命周期)
"openviking-context": {
"config": {
"mode": "remote",
"baseUrl": "http://openviking-lb:1933",
"apiKey": "${OPENVIKING_API_KEY}",
"l1TokenBudget": 2000,
"autoCompact": true,
"compactThreshold": 0.85,
"maxMemoryInjection": 10
}
}
}
}
}
OpenViking Server 配置(HA 模式)
// ~/.openviking/ov.conf
{
"storage": {
// 使用 S3 后端实现共享存储
"workspace": "s3://openviking-prod/workspace",
"backend": "s3fs",
"s3": {
"bucket": "openviking-prod",
"endpoint": "https://tos-s-sgp.volces.com",
"access_key": "${S3_ACCESS_KEY}",
"secret_key": "${S3_SECRET_KEY}",
"region": "ap-southeast-1"
}
},
"log": {
"level": "INFO",
"output": "file"
},
"embedding": {
"dense": {
"api_base": "https://ark.cn-beijing.volces.com/api/v3",
"api_key": "${VLM_API_KEY}",
"provider": "volcengine",
"dimension": 1024,
"model": "doubao-embedding-vision-250615"
},
"max_concurrent": 10
},
"vlm": {
"api_base": "https://ark.cn-beijing.volces.com/api/v3",
"api_key": "${VLM_API_KEY}",
"provider": "volcengine",
"model": "doubao-seed-2-0-pro-260215",
"max_concurrent": 100
},
// 向量索引使用托管服务
"vector": {
"backend": "volcengine",
"config": {
"endpoint": "https://vikingdb.volces.com",
"api_key": "${VIKINGDB_API_KEY}"
}
},
// 认证
"auth": {
"api_key": "${OPENVIKING_API_KEY}"
},
// 服务器配置
"server": {
"host": "0.0.0.0",
"port": 1933,
"workers": 4
}
}
HAProxy 负载均衡配置
# /etc/haproxy/haproxy.cfg
global
log stdout format raw local0
maxconn 4096
defaults
log global
mode http
option httplog
timeout connect 5s
timeout client 120s
timeout server 120s
frontend openviking_front
bind *:1933
default_backend openviking_back
backend openviking_back
option httpchk GET /health
http-check expect status 200
# 主实例(优先路由)
server ov-primary 10.0.1.10:1933 check inter 5s fall 3 rise 2
# 备用实例
server ov-standby 10.0.1.11:1933 check inter 5s fall 3 rise 2 backup
# 可选:多活模式(需要共享存储 + 写锁)
# server ov-node1 10.0.1.10:1933 check inter 5s
# server ov-node2 10.0.1.11:1933 check inter 5s
6. 高可用架构设计
核心价值回扣:高可用不是锦上添花,而是 Agent 记忆从”玩具”到”基础设施”的分水岭。本节设计的 HA 架构,正是实现 99.9% 可用性和秒级故障恢复的技术保障——让用户可以信任 Agent 的记忆永远在那里。
6.1 HA 架构总览
┌─────────────────────┐
│ OpenClaw Gateway │
│ (Context Engine + │
│ Memory Plugin) │
└──────────┬───────────┘
│
┌──────────▼───────────┐
│ HAProxy / Nginx LB │
│ (Health Check :1933) │
│ ┌────────────────┐ │
│ │ Active Probing │ │
│ │ GET /health │ │
│ │ interval: 5s │ │
│ └────────────────┘ │
└──────┬──────────┬─────┘
│ │
┌────────────▼──┐ ┌────▼───────────┐
│ OpenViking │ │ OpenViking │
│ Instance A │ │ Instance B │
│ (Primary) │ │ (Standby) │
│ :1933 │ │ :1933 │
└───────┬───────┘ └────────┬────────┘
│ │
┌───────▼───────────────────▼────────┐
│ Shared Storage Layer │
│ │
│ Option A: S3-Compatible Storage │
│ ┌─────────┐ ┌────────────────┐ │
│ │ MinIO │ │ AWS S3 / R2 / │ │
│ │ (on-prem)│ │ Volcengine TOS │ │
│ └─────────┘ └────────────────┘ │
│ │
│ Option B: NFS Shared Mount │
│ ┌─────────────────────────────┐ │
│ │ NFS Server (RAID + Backup) │ │
│ └─────────────────────────────┘ │
│ │
│ Vector Index: Volcengine VikingDB │
│ (Managed service, built-in HA) │
└──────────────────────────────────────┘
6.2 存储层 HA 方案
方案 A:S3 后端(推荐生产环境)
OpenViking 的 AGFS 原生支持 s3fs 后端:
{
"storage": {
"workspace": "s3://openviking-context/workspace",
"backend": "s3fs",
"s3": {
"bucket": "openviking-context",
"endpoint": "https://tos-s-sgp.volces.com",
"access_key": "...",
"secret_key": "...",
"region": "ap-southeast-1"
}
}
}
优势:
- 99.999999999% (11个9) 持久性
- 多实例可同时读写(通过对象锁定保证一致性)
- 无需自建存储基础设施
- 跨区域复制能力
注意事项:
- S3 延迟高于本地文件系统(~50-200ms vs ~1ms)
- 需要考虑 list 操作的最终一致性
- 建议搭配本地缓存层
方案 B:NFS 共享挂载
{
"storage": {
"workspace": "/mnt/nfs/openviking_workspace",
"backend": "localfs"
}
}
优势:
- 延迟低(~2-5ms)
- POSIX 兼容,与 localfs 后端无缝对接
- 运维熟悉度高
注意事项:
- NFS 本身是单点(需要额外 HA 方案如 DRBD + Pacemaker)
- 文件锁性能问题
- 大规模并发写入需要调优
方案 C:混合方案(推荐)
AGFS Content → S3 (持久化、跨实例共享)
Vector Index → Volcengine VikingDB (托管服务、内建 HA)
Hot Cache → Local SSD (减少 S3 延迟)
6.3 多实例部署方案
┌─────────────────────────────────────────────────────┐
│ Deployment Topology │
│ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Node 1 (SGP) │ │ Node 2 (SGP) │ │
│ │ │ │ │ │
│ │ OpenClaw GW │ │ OpenViking │ │
│ │ OpenViking (A) │ │ Instance (B) │ │
│ │ [Primary] │ │ [Standby] │ │
│ │ │ │ │ │
│ │ Local Cache: │ │ Local Cache: │ │
│ │ /tmp/ov-cache │ │ /tmp/ov-cache │ │
│ └────────┬──────────┘ └────────┬──────────┘ │
│ │ │ │
│ └────────┬───────────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ S3 Storage │ │
│ │ (VolcEngine TOS)│ │
│ └─────────────────┘ │
└─────────────────────────────────────────────────────────┘
6.4 故障转移策略
健康检查
# HAProxy 配置示例
backend openviking_backend
option httpchk GET /health
http-check expect status 200
server ov-primary 10.0.1.10:1933 check inter 5s fall 3 rise 2
server ov-standby 10.0.1.11:1933 check inter 5s fall 3 rise 2 backup
故障转移流程
Primary 健康检查失败
│
┌──────▼──────┐
│ 连续 3 次失败 │
│ (15 秒窗口) │
└──────┬──────┘
│
┌──────▼──────┐
│ LB 自动切换 │
│ 到 Standby │
└──────┬──────┘
│
┌────────────▼────────────┐
│ Standby 变为 Active │
│ • 连接共享存储 (已就绪) │
│ • 加载向量索引 (已同步) │
│ • 服务恢复时间 < 5s │
└──────────────────────────┘
6.5 增量备份与全量重建
增量备份策略
#!/bin/bash
# cron: 每小时执行增量备份
# S3 后端自带版本控制,额外备份到冷存储
BACKUP_BUCKET="s3://openviking-backup"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
# 1. 导出 ovpack(OpenViking 原生导出格式)
curl -X POST http://localhost:1933/api/v1/pack/export \
-H "X-API-Key: ${OV_API_KEY}" \
-H "Content-Type: application/json" \
-d '{"scope": "all"}' \
-o "/tmp/backup_${TIMESTAMP}.ovpack"
# 2. 上传到备份存储
aws s3 cp "/tmp/backup_${TIMESTAMP}.ovpack" \
"${BACKUP_BUCKET}/incremental/${TIMESTAMP}.ovpack"
# 3. 保留最近 72 小时的增量备份
aws s3 ls "${BACKUP_BUCKET}/incremental/" | \
awk '{print $4}' | head -n -72 | \
xargs -I {} aws s3 rm "${BACKUP_BUCKET}/incremental/{}"
全量重建流程
#!/bin/bash
# 从备份恢复 OpenViking 实例
# 1. 启动空 OpenViking 实例
openviking-server &
sleep 5
# 2. 导入最新备份
LATEST_BACKUP=$(aws s3 ls s3://openviking-backup/incremental/ | tail -1 | awk '{print $4}')
aws s3 cp "s3://openviking-backup/incremental/${LATEST_BACKUP}" /tmp/restore.ovpack
curl -X POST http://localhost:1933/api/v1/pack/import \
-H "X-API-Key: ${OV_API_KEY}" \
-F "file=@/tmp/restore.ovpack"
# 3. 等待语义处理完成
curl -X POST http://localhost:1933/api/v1/system/wait \
-H "X-API-Key: ${OV_API_KEY}" \
-H "Content-Type: application/json" \
-d '{"timeout": 300}'
echo "Restore complete"
7. 风险评估与缓解
| 风险 | 概率 | 影响 | 缓解措施 |
|---|---|---|---|
| OpenViking API 延迟过高影响 assemble | 中 | 高 | 本地缓存 L0/L1 + 5s 超时 + 降级到 legacy |
| Context Engine 与 Memory Plugin 冲突 | 低 | 中 | 明确分工 + 集成测试覆盖 |
| S3 存储最终一致性导致读取脏数据 | 低 | 中 | 强一致性读取策略 + 缓存验证 |
| OpenViking 版本升级 breaking changes | 中 | 中 | 锁定版本 + 升级测试环境 |
| VLM/Embedding API 限流 | 中 | 低 | 令牌桶限流 + 队列化 |
| 多 Agent 并发写入冲突 | 低 | 低 | 写入是 append-only + 不同 scope 隔离 |
| 灾难恢复时 ovpack 恢复耗时过长 | 低 | 高 | 定期演练 + 增量备份缩小恢复时间窗口 |
降级策略
// Context Engine 内建降级逻辑
class OpenVikingContextEngine implements ContextEngine {
private fallbackToLegacy = false;
async assemble(params: AssembleParams): Promise<AssembleResult> {
if (this.fallbackToLegacy) {
// 降级:直接返回消息,不做 OpenViking 检索
return {
messages: params.messages,
estimatedTokens: this.estimateTokens(params.messages),
};
}
try {
return await this.assembleWithOpenViking(params);
} catch (err) {
this.logger.warn(`OpenViking assemble failed, falling back: ${err}`);
this.fallbackToLegacy = true;
// 60 秒后尝试恢复
setTimeout(() => {
this.fallbackToLegacy = false;
}, 60_000);
return {
messages: params.messages,
estimatedTokens: this.estimateTokens(params.messages),
};
}
}
}
8. 附录
A. OpenViking HTTP API 快速参考
# 健康检查
curl http://localhost:1933/health
# 系统状态
curl http://localhost:1933/api/v1/system/status -H "X-API-Key: xxx"
# 目录列表
curl "http://localhost:1933/api/v1/fs/ls?uri=viking://user/memories/"
# 语义搜索
curl -X POST http://localhost:1933/api/v1/search/find \
-H "Content-Type: application/json" \
-d '{"query": "TypeScript best practices", "target_uri": "viking://user/memories", "limit": 10}'
# 创建会话
curl -X POST http://localhost:1933/api/v1/sessions \
-H "Content-Type: application/json" -d '{}'
# 添加消息
curl -X POST http://localhost:1933/api/v1/sessions/{id}/messages \
-H "Content-Type: application/json" \
-d '{"role": "user", "content": "Hello world"}'
# 提取记忆
curl -X POST http://localhost:1933/api/v1/sessions/{id}/extract \
-H "Content-Type: application/json" -d '{}'
# 导出备份
curl -X POST http://localhost:1933/api/v1/pack/export \
-H "Content-Type: application/json" -d '{"scope": "all"}' -o backup.ovpack
# 导入恢复
curl -X POST http://localhost:1933/api/v1/pack/import -F "file=@backup.ovpack"
B. OpenClaw Plugin SDK 关键类型引用
// Context Engine 注册
api.registerContextEngine(id: string, factory: ContextEngineFactory): void;
// 可用 Plugin Hooks
type PluginHookName =
| "before_model_resolve"
| "before_prompt_build"
| "before_agent_start"
| "llm_input" | "llm_output"
| "agent_end"
| "before_compaction" | "after_compaction"
| "before_reset"
| "message_received" | "message_sending" | "message_sent"
| "before_tool_call" | "after_tool_call"
| "session_start" | "session_end"
| "subagent_spawning" | "subagent_spawned" | "subagent_ended"
| "gateway_start" | "gateway_stop";
// Plugin Slots
"plugins.slots.memory" // Memory 插件选择
"plugins.slots.contextEngine" // Context Engine 选择 (default: "legacy")
C. 性能基准参考
基于 OpenViking 官方 LoCoMo10 评测(1,540 个案例):
| 方案 | 任务完成率 | 输入 Token |
|---|---|---|
| OpenClaw (memory-core) | 35.65% | 24,611,530 |
| OpenClaw + LanceDB | 44.55% | 51,574,530 |
| OpenClaw + OpenViking (-memory-core) | 52.08% | 4,264,396 |
| OpenClaw + OpenViking (+memory-core) | 51.23% | 2,099,622 |
结论:OpenViking 集成后,任务完成率提升 43-49%,Token 消耗降低 83-96%。
文档结束。如有疑问请联系 wairesearch。