首页
/ 跨客户端便携式记忆插件包:OpenViking Agent Plugins 1.0 结构、安装与实现剖析

跨客户端便携式记忆插件包:OpenViking Agent Plugins 1.0 结构、安装与实现剖析

2026-09-08 16:23:48作者:房伟宁

OpenViking 在仓库根目录提供了 agent-plugins/ 这一套基于 Agent Plugins 1.0 规范打包的插件包,用于把 OpenViking 的长期语义记忆与上下文能力交付给各类 AI 编码客户端。本文以 agent-plugins/README.md 为主线,完整讲解插件包的目录组成、plugin.json / mcp.json 清单结构、stdio 代理设计动机、凭据解析优先级,并结合仓库源码(servers/config.mjsplugin.test.mjsskills/openviking-memory/SKILL.md 等)揭示其底层实现与可验证细节。读完你将掌握:如何把 OpenViking 记忆能力装载进 Cursor、VS Code 等任何遵循 Agent Plugins 1.0 的客户端,以及为什么这套包内部要用一个 stdio 代理去对接服务端的 /mcp

一、Agent Plugins 1.0 是什么,这个包是什么

Agent Plugins 1.0 是一种与厂商无关的 AI 编码 Agent 扩展打包格式,由 Amazon、Cursor、Microsoft、OpenAI、Vercel 等生态共同推动。一个插件本质上就是一个普通目录,具备三要素:

  • plugin.json 清单(manifest),声明插件的元数据;
  • skills/ 下的 Agent Skills,可被客户端自动发现;
  • mcp.json 中可选声明的 MCP 服务器。

因此,同一个包可以被任何遵循该规范的客户端(Cursor、VS Code,以及 Amazon/OpenAI 一端的客户端等)以完全相同的方式加载。OpenViking 的 agent-plugins/ 目录正是这样一份"即插即用"包,目标是把 OpenViking 的长期语义记忆与上下文能力带给编码 Agent。

目录结构速览

plugin.json                          # Agent Plugins 1.0 清单
mcp.json                             # stdio MCP 服务器声明:"openviking"
servers/mcp-proxy.mjs                # stdio -> streamable-HTTP 代理,转发到 OV 服务端 /mcp
servers/config.mjs, debug-log.mjs    # 凭据/配置解析(改编自 claude-code-memory-plugin)
servers/shared/                      # 由 examples/memory-plugin-shared/lib 生成(不要在此修改)
skills/openviking-memory/SKILL.md    # 教模型"召回 + 持久化"闭环的技能文件
plugin.test.mjs                      # node --test 合规检查

该包零 npm 依赖,代理与测试全部基于 Node.js 标准库运行(需要 Node 18+,因为要用到全局 fetch,见 shared/mcp-proxy-core.mjs 中"global fetch is required"的显式校验)。

二、清单文件结构:plugin.json 与 mcp.json

plugin.json 是插件包的"身份证"。仓库中的 plugin.json 内容如下:

{
  "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
  "name": "openviking",
  "version": "0.1.0",
  "description": "Semantic long-term memory and context engine for coding agents. Recall prior knowledge with the find/search/read MCP tools and persist durable facts with remember/write, backed by an OpenViking server.",
  "author": {
    "name": "Volcano Engine"
  },
  "homepage": "https://github.com/volcengine/OpenViking",
  "license": "AGPL-3.0",
  "keywords": ["memory", "long-term-memory", "context-engine", "semantic-search", "mcp", "openviking"]
}

说明几点:

  • name 是客户端标识插件的关键字段,必须为 1–64 个字符的小写字母数字串,允许连字符与句点,但不能出现连续分隔符、不能以分隔符开头或结尾(详见 plugin.test.mjsNAME_RE 正则校验);
  • version 必须是严格 semver;
  • 规范约束了 plugin.json 根级字段集合:$schemanameversiondescriptionauthorhomepagerepositorylicensekeywordsextensions。测试文件用 PLUGIN_ALLOWED_KEYS 集合逐项断言,任何多余字段都会被拒绝(plugin.test.mjs)。

mcp.json 声明随插件一起注册的 MCP 服务器:

{
  "$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
  "mcpServers": {
    "openviking": {
      "type": "stdio",
      "command": "node",
      "args": ["${PLUGIN_ROOT}/servers/mcp-proxy.mjs"]
    }
  }
}

关键点:MCP 服务器名为 openviking,类型是 stdio,命令为 node(必须是单一可执行令牌,不能含空格或 shell 拼接),参数中的 ${PLUGIN_ROOT} 占位符由规范客户端展开为插件目录绝对路径。合规测试会校验这些占位符展开后必须仍然位于插件根目录内,防止路径逃逸(plugin.test.mjs)。

三、为什么用 stdio 代理,而不是直接声明 streamable-http

OpenViking 服务端本身已经在 /mcp 提供 streamable HTTP 协议的 MCP 端点,但规范要求"可移植",直接在 mcp.json 里声明 streamable-http 类型会撞上两个现实问题:

  1. 服务器 URL 是随部署变化的——本地用户是 http://127.0.0.1:1933,远程用户是另一个端点,写死在清单里就无法跨用户分发;
  2. Agent Plugins 规范禁止在 mcp.json 静态 headers 映射中携带凭据,而访问 OpenViking 往往需要 API Key。

stdio 代理同时解决这两点:它由客户端以本地子进程方式启动(node ${PLUGIN_ROOT}/servers/mcp-proxy.mjs),运行时才从与 ov CLI 相同的本地配置源解析 URL 与 API Key,逐请求注入后,将客户端发来的 JSON-RPC 原样转发到服务端 streamable HTTP 端点。对客户端而言它只是一个普通 stdio MCP 服务器;对服务端而言它只是又一位 streamable-HTTP 调用者。代理同时保持 stdout 通道干净,只走 MCP 协议帧,调试日志另走文件。

从源码看,代理的主干调用链是:mcp-proxy.mjsloadConfig()config.mjs)→ buildMcpProxyConfig(...)shared/mcp-proxy-config.mjs)→ createOpenVikingMcpProxy(...).start()shared/mcp-proxy-core.mjs)。

四、安装步骤与客户端接入

安装前提是一个可访问的 OpenViking 服务端(服务端启动方式见快速开始文档,本地默认端点是 http://127.0.0.1:1933),随后:

  1. 让遵循 Agent Plugins 规范的客户端指向本目录(各客户端有自己的安装命令或插件目录,详见其文档)。客户端会完成两件事:
    • 依据 mcp.json 注册 openviking MCP 服务器——也就是以 stdio 方式运行 node <plugin>/servers/mcp-proxy.mjs
    • skills/ 发现 openviking-memory 技能。
  2. 按下一节配置凭据,然后开启一个新会话。

会话建立后,模型即可获得 find / search / read / remember / write 等 OpenViking MCP 工具。语义搜索时用 search 并传 mode="context",可获得由服务端按 token 预算组装好的上下文块,而不是一长串原始命中。

技能所教的"召回 + 持久化"闭环

没有 hook 的客户端不会自动抓取会话,因此 skills/openviking-memory/SKILL.md 承担了"教模型主动使用记忆"的责任。它的核心工具按职责划分如下:

类别 工具 用途
召回 findsearchreadlistgrepglob 核心集,所有部署都有
持久化 rememberadd_resource 核心集
维护 forgethealth 核心集
可选 treewriteeditlist_watchescancel_watch 依赖服务端版本与托管模式

任务开始时的召回流程:先判断任务是否值得检索(可执行/多步骤工作、可能接触过该系统的工作、故障恢复需要;闲聊和一次性问答则跳过);用任务目标、领域对象、预期操作与约束拼一条简洁 query;用 find(快、按相关度排序,返回 URI + 摘要 + 分数)且 limit 取 5–10 左右,需要更深入意图分析或想要服务端组装上下文时改用 search;在 list 模式下可用 target_uri 收窄范围,例如用 viking://~/memories/experiences 检索历史任务经验;最后针对 1–3 个可能改变执行方式的确切文件 URI 调 read,忽略 .abstract.md.overview.md.relations.json 这类 sidecar 文件。

工作期间与结束时的持久化:由于没有自动捕获,遇到值得保留的信息必须在同一会话内存下。remember(messages) 是默认方式,把关键对话或短事实摘要以带角色的消息传入,服务端自行抽取并归档为记忆(偏好、实体、事件、经验);add_resource 用于导入外部文档或 URL 成为可检索资源;需要精确文档且 write/edit 可用时(已知位置如 viking://~/ 个人根或 viking://resources/ 共享资料),用它们覆盖精确写入需求,否则退回 remember

应持久化的内容:稳定的偏好与约定、环境事实、带理由的决策、可复用的流程或修复方案。不应持久化的:密钥与凭据、瞬态状态、臆测、整段对话转储——只存结论,不存滚动日志。

五、凭据解析:环境变量 → ovcli.conf → ov.conf → 默认值

代理与 OpenViking 的 ov CLI 及其他插件遵循同一条凭据解析链,优先级从高到低:

  1. 环境变量OPENVIKING_URL(或 OPENVIKING_BASE_URL)、OPENVIKING_API_KEY(或 OPENVIKING_BEARER_TOKEN)、OPENVIKING_ACCOUNTOPENVIKING_USEROPENVIKING_PEER_ID
  2. ~/.openviking/ovcli.conf(CLI 客户端配置,字段 urlapi_keyaccountuser),可用 OPENVIKING_CLI_CONFIG_FILE 覆盖路径;
  3. ~/.openviking/ov.confserver(本地服务端配置,字段 urlhost/portroot_api_key),可用 OPENVIKING_CONFIG_FILE 覆盖路径;
  4. 默认值http://127.0.0.1:1933,无鉴权(本地模式)。

两份配置文件都按 JSON 解析。一个带 server 段和 CLI 配置的示意如下:

// ~/.openviking/ovcli.conf —— 优先级更高,通常由 ov CLI 侧维护
{
  "url": "http://127.0.0.1:1933",
  "api_key": "<your-api-key>",
  "account": "<account>",
  "user": "<user>"
}
// ~/.openviking/ov.conf —— 服务端配置文件中的 server 段
{
  "server": {
    "url": "http://127.0.0.1:1933",
    "root_api_key": "<root-key>"
  }
}

解析逻辑在 config.mjs 中有更细的实现,可印证几个边界行为:

  • baseUrl 构造:优先环境变量 → ovcli.urlov.server.url;若都没有,再取 ov.server.host/port 拼成 http://{host}:{port}(端口默认 1933,host 中的 0.0.0.0 会被替换为 127.0.0.1),末尾多余的 / 会被剥掉(config.mjs);
  • apiKey 解析OPENVIKING_BEARER_TOKENOPENVIKING_API_KEY 二选一(发送时都作为 Bearer),然后依次是 ovcli.api_keyov.server.root_api_keyconfig.mjs);
  • 超时OPENVIKING_TIMEOUT_MS 可调,默认 15000 ms,且下限被钳制为 1000 ms(config.mjs);
  • 布尔环境变量OPENVIKING_DEBUG 接受 0/1/false/true/no/yesconfig.mjs);
  • 配置热更新:代理每次请求前重新调用 loadConfig(),配置文件变动无需重启即可被新请求感知(readProxyConfig 为每次请求动态取配置)。

调试手段

设置 OPENVIKING_DEBUG=1 可开启调试,代理会以 JSON Lines 格式写日志到 ~/.openviking/logs/agent-plugins.log(日志记录格式为 { ts, hook, stage, data }{ ts, hook, stage, error },可通过 OPENVIKING_DEBUG_LOG 覆盖路径;未开启时 log()/logError() 是零开销的空操作)。这两点分别见 config.mjsshared/debug-log.mjs 的注释说明。

六、插件包的边界:做什么与不做什么

本包是"便携的召回 + 写入面":技能 + MCP 工具,由模型驱动。Agent Plugins 1.0 规范刻意排除了 hooks、commands、agents,因此自动会话捕获与自动的 prompt 前召回都不在本包范围内——openviking-memory 技能改为教模型自己在任务开始时召回、在任务中用 remember/write 持久化关键事实。

如果你的宿主环境有 hook 机制,建议优先选择各专用插件,因为基于 hook 的召回与捕获不消耗工具调用、也不依赖模型"自觉去记忆"。仓库中同名安装脚本一次覆盖 Claude Code、Codex、Cursor、TRAE / TRAE CN、ZCode、OpenCode 与 pi 等宿主,支持交互式选择语言、宿主、下载源与凭据,且可重复执行(脚本本体位于 examples/memory-plugin-shared/install.sh)。对应各宿主目录包括:

而本 Agent Plugins 包适用于两类场景:宿主没有任何 hook;或者你希望一份包能在尽量多的客户端间通用加载。依照规范,客户端特定的集成后续也可放进本包内反向域名命名的子目录(如 com.example.client/)或清单的 extensions 对象里,且不影响其他客户端。

可选工具与托管模式的差异

可选工具的可用性取决于服务端版本与托管形态,references/optional-tools.md 给出汇总表:

工具 服务端要求 托管云服务
tree ≥ 0.4.14 云滚动到 0.4.14 后
writeedit ≥ 0.4.14 云滚动到 0.4.14 后
list_watchescancel_watch ≥ 0.3.18,自托管/私有 不暴露

托管云是无状态多实例服务,因此账户级的有状态工具(list_watchescancel_watch)即使底层版本已具备也会被裁剪。技能文件中明确约束:只有当某个可选工具真实出现在当前会话注册的工具列表里时,才能使用它;绝不调用未注册工具,也不要退回裸 HTTP。tree 用于在陌生作用域中快速建立目录感;write 负责在已知 URI 替换/追加/新建文件(新建要求父目录已存在);edit 做目标字符串替换,建议先 read 避免内容过期;list_watches/cancel_watch 管理由带 watch 间隔的 add_resource 创建的自动刷新订阅。

七、开发与质量保障:合规测试与共享库同步

本包自带无依赖的合规测试,运行方式:

node --test agent-plugins/plugin.test.mjs

plugin.test.mjs 逐项断言了以下内容,既是 CI 守护,也是理解 Agent Plugins 1.0 规范的活教材:

  • plugin.json 根字段封闭性、name 命名规则、semver versionauthor/keywords/description/license 完整性;
  • mcp.jsonplugin.json$schema 规范版本一致;mcpServers 类型只能是 stdiostreamable-httpstreamable-http 的 headers 不得出现 authorization/api_key/token/secret/cookie 等凭据字样;stdiocommand 必须是单令牌、且 ${PLUGIN_ROOT} 占位符展开后不得逃逸插件根目录;
  • 每个 skills/* 子目录都必须有带 name + description frontmatter 的 SKILL.md,且 name 与目录名一致;
  • SKILL.md 内的相对 Markdown 链接必须真实解析到文件;
  • 插件内所有 .mjs 文件通过 node --check 语法检查,且 mcp-proxy.mjs 的 import 均存在。

需要特别提醒的仓库维护约定:servers/shared/*.mjs 是从 examples/memory-plugin-shared/lib 逐字拷贝生成的,不要在本目录内直接编辑它们。本目录是共享库同步脚本的目标之一,需要刷新时运行:

node examples/memory-plugin-shared/sync.mjs

examples/memory-plugin-shared/sync.test.mjs 会在内容漂移时失败。servers/config.mjsservers/debug-log.mjsservers/mcp-proxy.mjs 则改编自 claude-code-memory-plugin(只保留连接相关字段,丢弃 hook 调优旋钮——因为本规范没有 hooks);改动代理行为时需同步到那边。本包与 sync 测试文件都由 .github/workflows/pr.yml 在 CI 中执行。

结语:什么时候选它,什么时候不选

一句话总结选型:宿主无 hook、或想要一份跨客户端通用的包时,用本 Agent Plugins 包;宿主具备 hook 能力且希望零工具调用成本地自动召回与会话捕获时,优先选用 examples/memory-plugin-shared/install.sh 覆盖的 claude-code-memory-plugincodex-memory-pluginopencode-plugincursor-memory-plugin 等专用插件。

本包的核心设计可归纳为三句话:用 Agent Plugins 1.0 清单换取生态级可移植性;用 stdio 代理换取"URL 与凭据按部署解析"的运行时灵活性;用内嵌技能把无 hook 场景下的召回 + 持久化闭环明确教给模型。理解 mcp.jsonservers/mcp-proxy.mjsservers/config.mjsskills/openviking-memory/SKILL.md 这条链路,你就能在任何 Agent Plugins 客户端中快速复现、调试或二次接入这套 OpenViking 记忆方案。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391