LLM新技术中的CS原型(一)OpenViking:上下文像文件系统一样组织

主作者:陈劲铧

参考图片:

image

官方链接:OpenViking - The Context Database for AI Agents

github链接:volcengine/OpenViking: Self-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.

参考链接:

1 项目介绍

OpenViking 是面向 AI Agent 的开源上下文数据库。它用虚拟文件系统组织资源、记忆和技能,让应用按路径浏览、检索相关上下文,并按需读取详细内容。

当 Agent 需要跨会话复用文档和经验时,可以用它集中组织和检索这些上下文。

由于官方文档十分详细,我就只展示一些核心内容和对应的参考链接。重点放在实验,体验与思考中。其中大多数官方已给出及其详细的内容,我仅复制重要内容,方便读者理解OpenViking大致面貌。

1.1 系统概述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
┌────────────────────────────────────────────────────────────────────────────┐
│ OpenViking 系统架构 │
├────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ │
│ │ Client │ │
│ │ (OpenViking)│ │
│ └──────┬──────┘ │
│ │ 委托 │
│ ┌──────▼──────┐ │
│ │ Service │ │
│ │ Layer │ │
│ └──────┬──────┘ │
│ │ │
│ ┌─────────────────────────┼─────────────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Retrieve │ │ Session │ │ Parse │ │
│ │ (上下文检索) │ │ (会话管理) │ │ (上下文提取) │ │
│ │ │ │ │ │ │ │
│ │ search/find │ │ add/used │ │ 文档解析 │ │
│ │ 意图分析 │ │ commit │ │ L0/L1/L2 │ │
│ │ Rerank │ │ commit │ │ 树构建 │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
│ │ │ │ │
│ │ │ 记忆提取 │ │
│ │ ▼ │ │
│ │ ┌─────────────┐ │ │
│ │ │ Compressor │ │ │
│ │ │ 压缩/去重 │ │ │
│ │ └──────┬──────┘ │ │
│ │ │ │ │
│ └────────────────────────┼────────────────────────┘ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Storage 层 │ │
│ │ AGFS (文件内容) + 向量库 (索引) │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└────────────────────────────────────────────────────────────────────────────┘

1.2 核心模块

模块 职责 关键能力
Client 统一入口 提供所有操作接口,委托给 Service 层
Service 业务逻辑 FSService、SearchService、SessionService、ResourceService、PackService、DebugService
Retrieve 上下文检索 意图分析(IntentAnalyzer)、层级检索(HierarchicalRetriever)、Rerank 精排
Session 会话管理 消息记录、使用追踪、会话压缩、记忆提交
Parse 上下文提取 文档解析(PDF/MD/HTML)、树构建(TreeBuilder)、异步语义生成
Compressor 记忆压缩 Schema 驱动的记忆提取、LLM 去重决策
Storage 存储层 VikingFS 虚拟文件系统、向量索引、AGFS 集成

1.3 Service 层

Service 层将业务逻辑与传输层解耦,便于 HTTP Server 和 CLI 复用:

Service 职责 主要方法
FSService 文件系统操作 ls, mkdir, rm, mv, tree, stat, read, abstract, overview, grep, glob
SearchService 语义搜索 search, find
SessionService 会话管理 session, sessions, commit, delete
ResourceService 资源导入 add_resource, add_skill, wait_processed
PackService 导入导出、备份恢复 export_ovpack, import_ovpack, backup_ovpack, restore_ovpack
DebugService 调试服务 observer (ObserverService)

1.4双层存储

OpenViking 采用双层存储架构,实现内容与索引分离:

存储层 职责 内容
AGFS 内容存储 L0/L1/L2 完整内容、多媒体文件、关联关系
向量库 索引存储 URI、向量、元数据(不存储文件内容)

1.5 数据流概览

添加上下文

1
输入 → Parser → TreeBuilder → AGFS → SemanticQueue → 向量库
  1. Parser:解析文档,创建文件和目录结构(无 LLM 调用)
  2. TreeBuilder:移动临时目录到 AGFS,入队语义处理
  3. SemanticQueue:异步自底向上生成 L0/L1
  4. 向量库:建立索引用于语义搜索

检索上下文

1
查询 → 意图分析 → 层级检索 → Rerank → 结果
  1. 意图分析:分析查询意图,生成 0-5 个类型化查询
  2. 层级检索:目录级递归搜索,使用优先队列
  3. Rerank:标量过滤 + 模型重排
  4. 结果:返回按相关性排序的上下文

会话提交

1
消息 → 压缩 → 归档 → 记忆提取 → 存储
  1. 消息:累积对话消息和使用记录
  2. 压缩:保留最近 N 轮,旧消息归档
  3. 归档:生成历史片段的 L0/L1
  4. 记忆提取:根据记忆策略和 MemoryType Schema 从消息中提取记忆
  5. 存储:写入 AGFS + 向量库

1.6 设计原则

原则 说明
存储层纯粹 存储层只做 AGFS 操作和基础向量搜索,Rerank 在检索层完成
三层信息 L0/L1/L2 实现渐进式详情加载,节省 Token 消耗
两阶段检索 向量搜索召回候选 + Rerank 精排提高准确性
单一数据源 所有内容从 AGFS 读取,向量库仅存储引用和索引

2 核心模型

2.1 上下文类型

基于对人类认知模式的简化映射与工程化思考,OpenViking 将上下文抽象为 资源、记忆、能力三种基本类型,每种类型在 Agent 中有不同的用途。

类型 用途 生命周期 主动性
Resource 知识和规则 长期,相对静态 用户添加
Memory Agent 的认知 长期,动态更新 Agent 记录
Skill 可声明的 agent 能动性配置(AgentDefinedContextType) 长期,静态 用户或系统添加

抽象为三种不同基本类型可以通过不同的API和方式进行管理,在我看来资源更像是文件系统中的 办公盘 存储数据为多,记忆更像是 C盘系统盘 存储临时缓存和用户配置,能力更像是配置好的exe程序 只有需要时才会调用。

Resource:资源相对静态和用户主动添加的特性使其非常适合做 团队项目资源。重点倾斜在单个项目多个用户更新或读取等情况。某种情况下有点像Linux多用户读取同一文件的形式,不过换成了 LLM的记忆与规则。

Memory:记忆动态更新的特性使其更加灵活,更贴切原本Agent的记忆系统。好比是操作系统里每个人的个人账号,互相隔离,保留不同agent之间的认知。在下两张对比中,我们可以看到一个常见的windows用户管理系统,其中的.xxx文件就是各类工具的配置/记忆等,在对应的AppData中也存放着相关存档记忆。OpenViking正是借鉴该思路做了虚拟文件系统以进行区分。

Skill:可自己添加的程序型技能。类比可索引到的可启动的脚本程序。

image 20260920161418321](https://www.imagehub.cc/image/image-

通过OpenViking helper可以直观看到虚拟文件系统中的记忆存储情况。其中对不同文件夹和数据有清楚的分类和排布,加速了文件检索的效率。

2.2 上下文层级(L0/L1/L2)

OpenViking 使用三层信息模型,在检索效率、导航能力和原始内容完整性之间取得平衡。

层级 名称 存储形式 默认正文上限 用途
L0 摘要 目录内的 .abstract.md 256 字符 向量检索、快速过滤
L1 概览 目录内的 .overview.md 4000 字符 Rerank、内容导航
L2 详情 原始文件和子目录 无统一上限 完整内容、按需加载

L0/L1 是目录级语义 sidecar。它们描述一个目录,不是为每个普通文件创建的同名伴生文件。文件摘要会作为输入,聚合到所在目录的 L1 中。

L0 和 L1 通常成对生成,但系统允许只存在其中一个。例如,mkdir() 会先创建 L0:未传入 description 时使用目录名作为默认正文,传入后使用该说明。因此只有 .abstract.md 的目录也是合法状态。读取和向量重建只处理实际存在的层级。

正文上限由 semantic.abstract_max_chars 和 semantic.overview_max_chars 配置;上表是默认值。限制只作用于 Markdown 正文,不会截断 sidecar 元数据。

L0:摘要

L0 是目录内容的最精简表示,用于向量召回和快速相关性判断。

1
API 认证指南,涵盖 OAuth 2.0、JWT 令牌和 API 密钥的安全访问方式。

通过语义 accessor 读取时,只返回可见正文:

1
abstract = client.abstract(uri="viking://resources/docs/auth")

L1:概览

L1 提供更完整的目录摘要和导航信息,用于 Rerank 和决定是否继续加载 L2。

1
2
3
4
5
6
7
8
9
# 认证指南

本目录介绍 API 的主要认证方式。

## 快速导航

- `oauth.md`:OAuth 2.0 流程和代码示例
- `jwt.md`:令牌生成和验证
- `api-keys.md`:API Key 认证
1
overview = client.overview(uri="viking://resources/docs/auth")

L0 从 L1 正文中提取:取 H1 标题之后、第一个 ## 标题之前的 Brief Description 段落。YAML frontmatter 不参与提取。

L2:详情

L2 是原始文件或解析后的完整内容,只在需要时加载,并保留源格式和结构。

1
2
content = client.read(uri="viking://resources/docs/auth/oauth.md")

目录结构

一个已完成语义处理的目录通常如下:

1
2
3
4
5
6
7
viking://resources/docs/auth/
├── .abstract.md # L0,隐藏的目录级 sidecar
├── .overview.md # L1,隐藏的目录级 sidecar
├── oauth.md # L2,完整内容
├── jwt.md # L2,完整内容
└── api-keys.md # L2,完整内容

普通 ls 默认隐藏 .abstract.md 和 .overview.md。它们不一定同时存在;不要依赖“每个目录始终具有两个 sidecar”的假设。

通过L0,L1,L2的方式提高在多文件大文件后期时的检索效率,但我发现其中L0时概括性描述,若换为事实性描述,其检索精度和效率更高。类似相关性树结构。个人人为这种上下文层级的设置还有很多可以优化的空间。

2.3 Viking URI

Viking URI 是 OpenViking 中所有内容的统一资源标识符。

格式

1
2
viking://{scope}/{path}

  • scheme: 始终为 viking
  • scope: 顶级命名空间(resources、user、agent;temp、queue 和 upload 为内部作用域)
  • path: 作用域内的资源路径

作用域

作用域 说明 生命周期 可见性
resources 独立资源/客观知识 长期 account 全局
user 用户级数据,包括 session 长期 / 会话生命周期 当前用户
agent agent 能力与配置(技能、端点、工具、支付等) 长期 account 全局
queue 处理队列 临时 内部
temp 临时文件 解析期间 内部
upload 临时上传文件 临时 内部

公开 API 和 CLI 的文件系统/内容操作接受公开作用域 resources、user 和 agent, 以及根 URI viking://。session 保留为 user session 路径的向后兼容别名; 新 session 数据位于 viking://user/{user_id}/sessions。 temp、queue 和 upload 是内部实现作用域,不能通过公开 API 的 URI 参数直接访问。

这个是最明显的借鉴文件系统方式,使得原本的记忆库可视化可索引可目录化。且极大的便利了文件的分门别类。在此基础上我们搭建了公司的OpenViking+对应gateway中转网关,通过一个OpenViking,不同文件目录管理公司组里的项目记忆,有效节约了同项目跨团队的Agent记忆学习消耗。

3 实际表现

3.1 官方实验截图

长期记忆准确率对比

image 20260920164210027

总输入 Token 消耗对比

image 20260920164301182

关键结论:OpenViking 在 Claude Code、Hermes、OpenClaw 三组基座上都把长期记忆准确率推到 80%+;在高消耗基线下,输入 Token 最高下降 63%。

3.2 自测实验

自测分为两条相互独立的实验线。两条实验采用不同的观测单位和评价指标,结论不能混用。

实验线 观测单位 主要指标 回答的问题
端到端长任务对照 一次完整的多段任务 交付完整度、墙钟时间、费用、缓存、产物质量 跨会话记忆是否有助于持续完成复杂任务
资源检索对照 一次 /search/find 请求 Recall、Hit、MRR、目录节点占位、延迟 检索配置能否更准确地返回目标文档

端到端实验会同时受到模型随机性、任务难度、工具调用和 Prompt Cache 的影响,不能直接换算为召回准确率;资源检索实验只评价 Resource 检索,也不能代替真实任务中的交付质量评估。

3.2.1 长任务实验设计

实验任务是从市场调研开始,完整制作一款可离线运行的单文件肉鸽卡牌游戏《灰烬牌局》。任务包含市场报告、市场分析、游戏策划、游戏制作、游戏优化和游戏评价 6 个阶段,拆成 5 段连续执行。工作目录中预置 38 篇、约 37 万字符的资料,覆盖市场、竞品、设计、数值、技术和评价六类内容。

完整跑批包含 A0、A1、A2 三个实验臂,共 15 个运行单元,连续执行约 10 小时。A1 用于观察商业版表现,核心结论主要比较 A0 与 A2。

实验臂 OpenViking 环境 命名空间状态 用途
A0 原生 不接入 OpenViking 不适用 纯 Claude Code 对照组
A1 商业版 商业版 v0.4.17.3 空命名空间 观察官方托管版本;不作为 A2 的直接归因对照
A2 公司网关 公司网关 + 上游 v0.4.12 已有用户级记忆 验证实际生产接入形态

三个实验臂使用相同的 claude-opus-5、Claude 中转站、题面、资料库和运行限制。不同版本与命名空间状态被单独标注,避免将 A1 与 A2 的差异全部归因于网关。

控制项 设置
模型 claude-opus-5
资料 38 篇、约 37 万字符,覆盖市场、竞品、设计、数值、技术和评价
会话边界 每段使用全新会话,段间清空模型上下文
单元上限 45 分钟或 50 美元,任一上限先到即停止
执行方式 三个实验臂串行运行,避免共享中转密钥的其他流量干扰逐单元计费
隔离方式 独立 USERPROFILE、CLAUDE_CONFIG_DIR、工作目录与 Peer ID

每段结束后立即关闭会话。A0 依赖工作区文件和 Claude Code 原生机制恢复状态;A2 在此基础上额外使用 OpenViking 的自动召回与捕获能力。第 2~5 段开头设置记忆探针,要求模型回答上一阶段采用的方案、被否决的方案及原因;无法确定时必须明确回答“不记得”。其中部分取舍信息不会写入交付文档,因此能够区分文件反推与跨会话记忆。

实验执行流程如下:

  1. 预检隔离。 A0 必须满足 MCP 工具、Hook 日志和上下文注入均为 0;A1、A2 必须能够连接各自的 OpenViking 服务。
  2. 分段执行。 三个实验臂在同一段中接收完全相同的任务范围,运行完成后保存回答、Transcript、事件流和产物。
  3. 提交屏障。 每段结束后等待 OpenViking 服务端完成会话提交与记忆抽取,再启动下一段,避免下一会话早于记忆入库。
  4. 产物验证。 检查 index.html 是否单文件、是否存在外链、能否离线加载,并记录文档、脚本和自检结果。
  5. 费用核对。 正常结束的运行读取 modelUsage 计算费用;超时运行使用中转站逐单元账本差值。两种口径在可同时取得数据的运行中差异不超过 4e-6 美元。

隔离记录显示,A0 在五段中始终为 0 个 OpenViking MCP 工具、0 条 Hook 增量和 0 次上下文注入;A2 始终暴露 13 个 MCP 工具,并在各段产生上下文注入。由此可以排除 A0 意外加载 OpenViking 插件这一类实验污染。

3.2.2 长任务实验结果

端到端结果如下:

指标 A0 原生 A2 OV 记忆库 对比结果
完成交付阶段 4 / 6 6 / 6 A2 补齐游戏优化与评价阶段
总耗时 209.7 分钟 185.0 分钟 减少 11.8%
总费用 52.91 美元 47.22 美元 减少 10.8%
自然结束的运行单元 1 / 5 2 / 5 A0 有 4 个运行单元触及 45 分钟上限
第 5 段单位费用产出 开局的 47% 开局的 95% A2 的成本曲线更稳定
缓存写占比 4.72% 4.64% 未观察到额外的 KV Cache 失效

image

图:三臂各段的中转站账本费用。第 2~4 段大多运行至 45 分钟上限;A2 在第 5 段提前完成,因此该段费用明显下降。

两臂最终都生成了无外链、可断网运行的单文件 index.html。以下截图来自无头浏览器对最终产物的实际渲染,而非设计稿。

A0 原生 A2 OV 记忆库
image 20260920 OpenViking ab a0 image 20260920 OpenViking ab a2

图:A0 与 A2 最终交付的《灰烬牌局》启动界面。两者均为单文件离线游戏,但功能组织和后续验证完整度存在差异。

A2 在最后一段用 30.9 分钟完成收尾,并交付评价文档和模拟脚本;A0 运行满 45 分钟后仍缺少游戏优化和游戏评价两个阶段的文档。A2 还在游戏中内置了 27 项数据完整性与可复现性断言,覆盖卡牌引用、敌人数量、事件数量、费用范围、随机数生成和状态迁移等项目,全部执行通过。

image 20260920 OpenViking ab selfcheck

图:A2 产物内置的自检页面,27 项断言全部通过。

从结果中可以得到四项观察:

  1. 主要差异出现在任务后段。 第 1 段不依赖历史决策,记忆优势尚不明显;进入优化与评价阶段后,早期方案和数值框架能否被恢复,直接影响交付完整度。
  2. 时间和费用同时下降。 A2 相比 A0 减少 24.7 分钟和 5.69 美元,交付完整度的提升并非以更高的总费用为代价。
  3. 单位成本更稳定。 到第 5 段,A0 每美元输出 Token 降至第 1 段的 47%,A2 仍保持 95%,表明重复理解既有项目逐渐成为 A0 的主要成本来源。
  4. 未观察到额外缓存破坏。 A2 的缓存写入占比为 4.64%,A0 为 4.72%。接入增加的是工具定义与启动注入形成的固定前缀,而不是持续改写系统前缀。

OpenViking 的 13 个 MCP 工具定义及启动注入会增加约 5,350 Token 的固定前缀,本轮折算约 1.07 美元,占 A2 总费用的 2.3%。因此,接入后并非从第一轮开始就必然降低成本;只有当任务跨越多个会话、并反复依赖既有决策时,固定开销才会被后续收益抵消。

**实验边界:**每个运行单元只执行 1 次,即 n=1;同时,A2 使用的是公司网关和已有用户空间,并非完全空白的 OpenViking 命名空间。因此该结果适合作为端到端案例和机制验证,不能当作稳定的性能分布,也不能把全部差异都归因于 OpenViking 本身。若要获得统计结论,还需要使用干净命名空间完成至少 3 次重复运行,并对最终产物做独立盲评。

3.2.3 资源检索终验

第二条实验直接调用生产环境的 /search/find。测试集冻结为 288 条查询,其中正例 255 条、负例 33 条,覆盖 40 篇资源文档。问题按照实际任务需求构造,例如询问起始生命、稀有度权重或存档迁移,而不是直接复述文档标题;负例用于观察系统是否对语料中不存在的主题仍然返回结果。

主要指标含义如下:

指标 含义
Recall@k 预期目标文档是否进入前 k 条结果
Hit@k 查询是否在前 k 条中命中至少一个相关结果
MRR 首个相关结果排名倒数的均值,越高表示目标文档排序越靠前
目录节点占位 返回结果被目录摘要占用的数量,过高会挤占正文文档位置

测试环境以生产上游 OpenViking v0.4.12 为基线。最终配置并非单一参数变更,而是以下组合方案:

变更 作用
事实型摘要模板 将摘要从编目式描述调整为可直接检索的事实陈述;主要收益体现在注入长度
qwen3.7-text-embedding 提升查询与目标文档之间的语义区分度;更换后对 3,607 条向量完成全量重嵌入
level=[2] 只检索文件节点,减少目录摘要占用排序位置
limit=6 在召回覆盖率与返回长度之间取平衡
国内 Embedding 端点 保持同一模型和向量空间,同时降低跨地域调用延迟

最终配置在相同测试集、相同过滤口径下复测,结果如下:

指标 基线 最终配置 变化
Recall@1 / @3 / @5 0.3559 / 0.5242 / 0.6255 0.4065 / 0.6092 / 0.6895 +14.2% / +16.2% / +10.2%
Hit@1 / @3 / @5 0.4000 / 0.5804 / 0.6745 0.4667 / 0.6706 / 0.7412 +16.7% / +15.5% / +9.9%
MRR 0.4976 0.5763 +15.8%
前五条结果中的目录节点数 435 36 减少 91.7%
P50 延迟 188 ms 151 ms 减少 20%
P95 延迟 394 ms 437 ms 增加 11%

七项精度指标均提升 9.9%~16.7%,目录节点占位由 435 个下降至 36 个。残留的 36 个节点来自被索引为 L2 文件的 .abstract.md 或 .overview.md,因此无法仅通过 level=[2] 完全排除。

参数扫描也修正了早期结论:在较小测试集上,limit=4 曾表现为可降低 Token 且不损失精度;在冻结的 288 条测试集上,limit=4 会使 Recall 下降 0.061、命中率下降 0.051,因此最终改为 limit=6。该结果表明,检索参数必须绑定具体基线与数据集,不能脱离实验条件复用。

延迟方面,P50 从 188 ms 降至 151 ms,但 P95 从 394 ms 增至 437 ms。中位延迟已经改善,长尾仍有 11% 的增幅,后续仍需关注连接复用、TLS 握手和模型端点抖动。

需要强调的是,该实验测量的是 Resource 的 /search/find 检索,不是每轮自动执行的 Memory Recall。两条链路共享 Embedding 与部分排序机制,但查询范围、配额和注入策略不同,趋势可以参考,数值不能直接互换。最终数据也是多项配置组合后的整体结果,不能全部归因于某一个模型或某一个网关参数。

3.3 使用体验

3.3.1 接入与日常使用

实际使用环境覆盖 OpenViking 商业版、自建服务、OpenViking Helper,以及 Claude Code、Codex 等 Agent。商业版接入步骤较少,并支持自动更新;自建服务的配置与数据控制能力更强,但需要自行维护模型端点、向量索引、权限、异步队列和版本升级。

image 20260920 OpenViking deployment

图:OpenViking Helper 的 Agent 接入页,可直接检查本机 CLI、MCP 与 Hook 状态。图中显示的是本机客户端版本,不等同于服务端版本。

OpenViking Helper 适合用于日常检查:可以配置本地 Agent、查看会话中的召回与捕获事件,并同步本地记忆和 Skill。它将原本隐藏在插件后台的动作可视化;当发生错误召回、身份不匹配或记忆未写入时,可以沿会话、URI 和事件记录定位问题。

CLI 安装本身较为直接,主流 Agent 均提供对应接入方式。实际部署中,安装完成并不等于接入有效,至少应核对以下项目:

检查项 核对内容
服务配置 ovcli.conf 中的 Base URL、API Key、account 与 user 是否匹配
Agent 接入 MCP 与 Hook 是否均处于已接入状态
身份作用域 当前用户、项目 Peer 与 Resource 命名空间是否符合预期
服务健康 模型、系统状态和任务队列端点是否正常
首次会话 SessionStart 是否出现注入记录,Stop/PreCompact 后是否生成提交任务

接入后的工作流由生命周期 Hook 与显式工具共同组成:

阶段 自动行为 可观测结果
SessionStart 注入用户画像、记忆索引和会话摘要 Prompt 中出现 OpenViking 上下文块
UserPromptSubmit 根据当前问题检索相关记忆 生成召回事件和命中 URI
Stop 捕获本轮新增消息 会话记录增加,等待后续提交
PreCompact / 正常结束 提交完整会话并触发记忆抽取 生成提交任务和 memory_diff.json
显式调用 通过 Skill 或 MCP 执行搜索、读取、写入和目录浏览 返回确定的 URI、正文或写入结果

“自动召回 + 显式工具”的混合方式兼顾了低操作负担与人工控制能力。常规对话依靠自动 Hook 完成;重要事实需要立即写入、自动检索不准确或需要读取指定文档时,再切换到显式工具。在一次 Claude 会话导入中,先读取 OpenViking 记忆、再读取本地项目记忆,全过程只占用了约 9% 的上下文上限。

需要注意,记忆抽取与向量写入是异步过程。若在上一会话结束后立即启动下一会话,可能出现提交已发出但记忆尚未进入可检索状态的短暂窗口。对强依赖上一阶段决策的自动化流程,应设置任务完成屏障,或在下一阶段开始前检查提交状态。

3.3.2 体验较好的部分

方面 实际感受
确定性寻址 Resource、Memory 与 Skill 统一使用 viking:// URI,可通过 ls、find、grep 和 read 定位;召回结果能够回溯到具体路径。
分层披露 L0 用于相关性判断,L1 用于目录导航,L2 承载正文;只有确认相关后才读取详细内容。实测一次会话导入仅占上下文上限的约 9%。
跨会话接续 新会话可以恢复用户偏好、项目背景和上一阶段决策;五段长任务中,A2 完成 6/6 阶段,A0 完成 4/6。
不破坏前缀缓存 上下文注入采用追加方式,缓存写入占比为 4.64%,未高于未接入时的 4.72%。
团队隔离 同一服务内可共享项目 Resource,同时按用户隔离 Memory;account、user 与 peer 构成不同层次的访问边界。
可治理与可审计 会话、记忆和检索轨迹均可观察;提交时生成变更记录,便于定位错误抽取和权限问题。

实际使用中,记忆召回与普通回复的等待时间通常处于可接受范围。收益最明显的场景不是一次性短对话,而是数据库整理、多文件研究和持续开发等大上下文工作:任务持续时间越长,可复用的决策、偏好和经验越多,跨会话收益越容易覆盖固定接入成本。

3.3.3 当前边界

  • 知识条目之间缺少横向关系。 当前优势主要来自目录与纵向分层,独立条目之间缺少可直接遍历的交叉引用。随着条目增加,仍需依赖全文扫描或向量检索发现关联。
  • 早期路由错误难以后续纠正。 层级检索先确定目录、再检索文档;若目录阶段选择错误,正确文档不会进入候选集,后续 Rerank 无法恢复。本项目路由实验的 Top-1 为 49.2%、Top-3 为 74.2%,目录设计仍会直接影响召回上限。
  • 接入存在固定成本。 工具定义、用户画像和自动召回增加约 5,350 Token 的首轮前缀;短任务可能只有开销,没有足够的后续轮次摊薄成本。
  • 记忆质量不会自动得到保证。 错误、重复、冲突和过期内容仍需通过 Schema、抽取策略、容量限制、权限和清理机制治理。
  • 不同宿主的生命周期能力不一致。 例如 Codex 被 SIGTERM、Ctrl+C 或 /exit 终止时可能不触发结束 Hook,需要在下次启动时回收孤儿会话。重要任务应正常结束或主动提交。
  • 商业版成本需要提前评估。 Session 会保存消息和工具输出;若按文件数量、文件大小、模型调用和流量计费,长期高频使用会形成持续费用。
  • 自建服务具有明确的运维负担。 模型端点、向量一致性、队列恢复、版本差异、权限隔离和可观测性都需要专门配置。实测自建上游 v0.4.12 与商业版 v0.4.17.3 已存在能力差异,因此不能将不同版本的结果直接归因于部署形态。

3.3.4 适用场景判断

更适合采用 不宜优先采用
需要跨多次会话持续推进的研发或研究任务 一次会话即可完成、历史信息很少的短任务
多人或多 Agent 共享项目资料、但需要隔离个人记忆 只有少量静态文档、普通目录检索已经足够的场景
需要查看记忆来源、检索轨迹和变更记录的审计场景 无法承担模型、向量库、权限和队列维护成本的项目
上下文持续增长,重复阅读成本已经可观测的项目 要求写入后立即强一致可见、且不能设置等待屏障的流程

综合来看,OpenViking 的核心价值是将上下文从一次性 Prompt 输入转化为可寻址、可分层、可复用和可治理的长期资产。它适合长周期协作与大上下文任务,但不替代 Agent 编排,也不会自动将低质量对话转化为高质量记忆;最终效果仍取决于数据组织、抽取策略、权限边界和持续评测。

4 迁移解剖与联想:上下文文件系统还缺什么

前三节已经说明 OpenViking 的结构、检索链路和实测效果。本节不再重复功能清单,而是按照“迁移解剖—阻抗核对—联想推广”的方法回答三个问题:它从文件系统中迁移了什么,经典文件系统的哪些前提在 LLM 场景中不再成立,以及这些差异还能推出哪些可验证的设计。在本章节,加粗字体为比较有吸引力的可靠的内容。

4.1 原型界定:迁移的不是目录外观,而是上下文管理结构

OpenViking 的直接原型是文件系统,但它并非只借用了“文件夹”这一表面隐喻。真正发生迁移的是一组互相配合的机制:用统一命名空间组织异构数据,用路径提供确定性寻址,用目录缩小检索范围,用分层内容控制读取成本,再用会话提交把运行过程沉淀为长期记忆。

经典系统中的角色 OpenViking 中的对应物 被保留的性质 面向 LLM 的改造
路径名 viking:// URI 路径已知后可确定性定位 路径发现可由语义检索完成,结果具有概率性
目录 Resource、Memory、Skill 的层级树 分组、遍历和局部搜索 目录同时包含模型生成的摘要,可参与路由
文件正文 L2 详细内容 承载可完整读取的内容 正文既可能来自原始资源,也可能来自会话抽取
目录项与元数据 L0、L1、向量索引 先检查低成本信息,再决定是否读取正文 摘要与向量由模型生成,可能过期或失真
文件操作 ls、tree、read、grep、glob、mv、rm 等操作 操作对象和结果可追踪 通过 API、MCP 和自然语言工具调用暴露给 Agent
用户与进程边界 account、user、agent、peer 等作用域 形成不同层次的可见范围 权限边界无法等价为指令与数据的硬隔离
写入与整理 Session Commit、记忆抽取与索引任务 将临时状态转为可复用状态 提交包含压缩、抽取和异步索引,并非简单字节落盘

由此可以区分三层迁移深度:

  1. 概念迁移已经明确发生。 URI、目录树、文件操作和作用域直接借用了文件系统语言。
  2. 架构迁移已经形成主体。 命名空间、分层读取、确定性操作与检索索引共同参与运行,而非只用于界面展示。OpenViking 实际上更接近“虚拟文件系统 + 数据库索引 + 会话压缩管线”的组合。
  3. 问题迁移只完成了一部分。 上下文管理被重述为寻址、索引、装载和治理问题,但稳定身份、原子提交、锁、故障恢复和强权限等文件系统契约尚未完整迁入。

其中,L0/L1/L2 不应简单理解为传统文件系统的缓存层。更准确的对应是“目录项/摘要/正文”三级披露:它们解决的是 Agent 应该看多少内容,而不是内核应该把哪些数据页保留在内存。Session Commit 也更接近日志压缩和物化视图生成,而不是 POSIX fsync 或完整事务。

4.2 阻抗失配:文件系统假设进入 LLM 场景后发生了什么

原型迁移是否有效,取决于原系统的前提能否在新环境中成立。OpenViking 已经处理了部分失配,但尚未消除它们。

文件系统中的隐含前提 LLM 场景中的失配 OpenViking 的处理 尚存代价或风险
给定路径即可确定定位 用户通常只表达意图,不知道 URI 用 find/search 发现候选,再用 read(uri) 确定读取 目录路由一旦选错,后续排序无法看到正确文档;路由实验 Top-1 仅 49.2%、Top-3 为 74.2%
一个对象通常位于一个父目录 同一知识可能同时属于多个主题、项目和任务 可依赖向量检索跨越目录发现内容 当前横向关系未形成主要检索通道,多归属仍依赖复制或概率检索横向记忆能力查,即一个类似内容在不同resource或记忆的相关。
写入完成后状态立即可见 摘要生成、向量化和记忆抽取是异步任务 通过任务队列完成派生数据写入 内容、摘要与索引可能短暂不一致,强依赖前序结果的流程需要完成屏障
系统调用具有严格参数和错误契约 Agent 通过自然语言选择并调用工具 MCP/API 将操作约束为结构化接口 工具选择仍可能出错,运行时校验不能省略
访问控制等于内容安全 文档内容还可能包含针对模型的恶意指令 account、user、peer 控制可见范围 命名空间不能提供硬件式“指令位”,Prompt Injection 仍需独立防护
保存进程状态可以近似恢复执行 模型内部状态不可序列化,长对话还必须压缩 保存消息并抽取事件、实体、偏好和摘要 恢复的是有损代理状态,不是模型思考过程的完整快照
元数据读取成本很低 L0/L1、Embedding 和 Rerank 都可能产生模型成本 以渐进披露减少不必要的 L2 读取 短任务可能无法摊薄约 5,350 Token 的固定接入开销
相同输入产生稳定测量 模型、网络端点和检索链路均存在波动 使用冻结数据集和相同过滤口径比较 长任务对照仍为 n=1,只能作为案例证据,不能视为稳定分布

这组失配解释了第三节结果中的“收益与边界并存”:分层索引使 Recall@5 从 0.6255 提升到 0.6895,并将前五条结果中的目录节点数从 435 降至 36;与此同时,P95 从 394 ms 增至 437 ms。迁移解决了平均意义上的内容筛选,却没有自动消除长尾延迟、异步一致性和概率路由问题。

4.3 纵向联想:文件系统还有哪些机制可以继续迁移

纵向联想不是把文件系统术语逐项照搬,而是从已经成立的角色映射中寻找缺口。结合当前实现与本地实验,可将候选机制分为“已有但未充分生效”和“尚需补足”两类。

经典机制 当前状态或实验依据 可继续迁移的方向
inode 式稳定身份 URI 同时承担路径与对象定位;移动或重命名会改变外部地址 为上下文节点分配与路径无关的稳定 context_id,路径只作为目录项
硬链接、符号链接与反向链接 关系基础设施存在,但当前配置中 memory.link_enabled = false,检索也未使用反向链接加权 允许一个节点出现在多个主题下,并把引用关系纳入召回和解释
工作集与冷热分层 retrieval.hotness_alpha = 0.0,热度未参与排序;当前也没有自动容量上限和 LRU 式淘汰 建立工作集、冷存储和保留策略,限制长期记忆无限增长
目录分数向下传播 retrieval.score_propagation_alpha = 1.0,父目录得分未实际影响子节点排序 将可靠的目录路由信号传递给叶子节点,同时保留跨目录补救通道
WAL、事务与 fsck 内容、摘要、向量和关系由多阶段任务生成,维护与孤儿清理仍需要显式执行 记录提交日志,并提供跨存储对账、重放与修复工具
快照、导入与备份 CLI 已有 snapshot 的 commit/restore/log/diff,也有 export/import/backup/restore 重点不应是重复增加命令,而是验证快照是否覆盖全部派生索引及恢复一致性
mount 与 overlay 项目 Resource、个人 Memory 和 Skill 已有不同作用域 将组织政策、项目资料和个人上下文以只读层、可写层叠加,明确覆盖优先级
capability 与只读挂载 已有身份和命名空间隔离 将“能看到”细化为可检索、可读取、可修改、可分享等最小能力

这些候选项的优先级并不相同。稳定身份、原子提交和一致性检查直接影响数据正确性,应先于复杂图检索;关系遍历和热度淘汰只有在条目规模增长后才会显著体现收益;overlay 与细粒度 capability 则主要面向团队和多 Agent 场景。

4.4 横向联想:同一结构还能迁移到哪些 LLM 问题

OpenViking 可被抽象为一个更一般的结构:确定性地址 + 概率性发现 + 渐进式装载。只要目标问题也同时存在“对象很多、完整加载昂贵、最终操作必须可追踪”三个条件,这一结构就可能横向迁移。以下联想均给出角色映射、测量指标和失败条件,避免停留在表面类比。

候选场景 角色映射 可测指标 失败条件
MCP 工具定义按需加载 文件对应完整工具 Schema,URI 对应工具名,L0 是一句话用途,L1 是参数概览,L2 是完整 Schema 与说明 系统前缀 Token、工具选择准确率、首次调用延迟 模型在未读取 L2 前无法可靠选中工具,或节省的 Token 小于额外路由成本
多 Agent 共享工作区 文件对应任务上下文片段,目录对应项目/任务树,Commit 对应 Agent 结果提交,版本号用于发现并发修改 重复读取量、冲突率、合并耗时、任务完成质量 共享结构增加协调开销,却没有降低重复工作或冲突
政策与指令治理 组织、项目、用户政策分别映射为只读挂载层,Agent 只获得任务所需 capability 无权访问率、越权修改率、政策命中率、提示词开销 内容中的恶意指令仍越过政策层,或层间优先级无法确定

第一项具有直接的实验动机:当前 13 个 OpenViking MCP 工具带来约 5,350 Token 的固定前缀。如果只常驻工具的 L0 索引,在确定需要后再加载完整 Schema,理论上可以降低短任务的固定成本。但这一方案只有在工具选择准确率不下降时才成立,不能仅以 Token 下降判定成功。

4.5 反向联想:LLM 的特化机制能否回流经典系统

迁移并非只能从经典系统流向 LLM。OpenViking 为概率模型增加确定性边界时形成的机制,也可以反向用于传统信息系统:

  • 语义寻址回流文档库或 IDE。 用户先用自然语言描述意图,系统返回可审计的规范路径、命中理由和遍历轨迹;语义检索负责发现,路径负责后续确定操作。
  • L0/L1 边车回流数据湖和归档系统。 为大文件生成一行摘要和结构概览,使人或自动化程序在打开全文前完成低成本筛选。
  • 会话压缩回流客服与事故知识库。 将连续日志抽取为事件、实体、决策和待办,同时保留到原始记录的引用,降低复盘时的全量读取成本。

反向迁移同样有边界:生成式摘要与语义寻址具有概率性,不应进入内核启动、账务一致性或安全授权等要求确定正确的关键路径。它们适合承担发现、导航和解释,最终修改仍应落到规范路径、版本和强校验接口上。

4.6 候选设计:稳定上下文身份与原子提交

综合纵向和横向联想,可以提出一个可证伪的候选设计:稳定上下文身份 + 多父关系 + 原子上下文提交。该设计属于推断,不代表 OpenViking 当前已经实现。

设计包含五项最小改动:

  1. 每个上下文节点获得不可随移动和重命名变化的 context_id,viking:// URI 退化为指向该节点的目录项。
  2. 关系限定为少量有类型的边,例如 contains、references、supersedes 和 derived_from,避免无约束知识图谱膨胀。
  3. 同一节点可以通过多个路径或链接出现,但正文只保存一份;反向链接可用于解释召回来源。
  4. 一次 Commit 必须共同覆盖正文、L0/L1、向量记录和关系更新;失败时能够整体回滚或根据日志重放。
  5. 提供 fsck 式对账,检查正文、目录树、向量索引和反向链接,并结合引用计数与保留策略回收孤儿节点。

借用wiki的存储方法,可参考llm-wiki

该设计应在生产基线 v0.4.12 上使用同一冻结的 288 条查询集验证,并增加跨目录引用、移动/重命名和故障注入三类测试。接受标准至少包括:Recall@5 与 MRR 不退化,跨目录子集的召回显著改善;移动或重命名不触发无必要的重新 Embedding;在正文写入与向量写入之间注入失败后,对账恢复的陈旧记录和孤儿记录均为 0;P95 检索延迟增幅不超过预先声明的 10%。精度差异应使用配对 Bootstrap 置信区间,而不是只比较单次点估计。

如果多父关系没有改善跨目录召回,或一致性与延迟成本超过上述阈值,就应否决该设计,而不是因为它“更像文件系统”而保留。由此可见,OpenViking 最有价值的迁移不是目录界面本身,而是把不可控的上下文堆积改写为可寻址、可装载、可审计的问题;其下一阶段的关键,也不是增加更多文件系统术语,而是补足稳定身份、一致性和关系治理,并用可重复实验判断这些机制是否真正改善 Agent 工作。

5 相关项目扩展分享

本节选择两个与 OpenViking 具有直接可比性的项目。它们都把 Agent 的长期状态从一次性 Prompt 中拆出来,但解决的问题并不相同:MemFS 解决“运行中的 Agent 如何组织和修改记忆”,agent-file 解决“一个已经形成的 Agent 如何被打包、迁移和复现”。前者偏运行时,后者偏交换格式。

5.1 Letta MemFS:把记忆变成可提交的工作区

原文链接:MemFS | Letta Docs

5.1.1 核心概念

MemFS(Memory File System)是 Letta Agent 使用的 Git-backed memory filesystem,也可以理解为 Agent 的上下文仓库。每个 Agent 拥有一个 Git 仓库,Letta 将仓库投影为 Agent 当前运行环境中的真实目录;Agent 通过普通的文件工具读取和修改 Markdown 文件,修改在提交前属于本地工作区,提交并推送后才成为其他运行位置可见的长期记忆。

它的关键抽象不是“把聊天记录存成文件”,而是把记忆拆成三种状态:

状态 典型位置或对象 对上下文的意义
当前身份与硬约束 system/ 下的 persona.md、human.md 等 每轮注入,保证 Agent 的基本身份和关键偏好稳定
可按需读取的长期知识 reference/、项目目录、主题目录 文件树常驻为路标,正文只有在需要时才读取
可复用的行为程序 skills/ 下的技能文件 记忆与工具使用方法一起版本化,形成可迁移工作流

每个记忆文件可以带 YAML frontmatter,用于描述其用途;文件名和目录名本身也承担索引作用。也就是说,MemFS 把“哪些内容始终在上下文中”和“哪些内容需要主动读取”编码进文件布局,而不是把所有历史对话都塞进上下文窗口。

5.1.2 实现原理

MemFS 的运行链路可以概括为“工作区投影—文件编辑—Git 提交—跨位置同步”:

  1. 仓库投影。 Letta 将 Agent 所属的 Git 仓库检出为运行时目录,Agent 看到的是普通路径,而不是专有记忆 API。
  2. 渐进式装载。 system/ 文件在每轮系统提示中加载;其他目录只把树结构作为路标,Agent 通过 ls、搜索和读取工具按需打开。
  3. 提交形成边界。 文件修改先留在工作区;提交后形成版本节点,云端 Agent 再将提交推送到托管仓库,从而在其他设备或运行环境中同步。
  4. 并发修改使用 Git 机制。 记忆子 Agent 可以使用 worktree 独立修改,主 Agent 通过提交、合并和冲突处理收敛结果,而不是直接覆盖同一份文本。
  5. 搜索与会话历史分离。 普通文件搜索可直接检索 MemFS;语义或混合搜索需要额外的 Search Mod 和 QMD 索引;聊天消息历史则是另一条检索链路,不能把两者的召回结果混为一谈。

这种设计把“写入记忆”降格为 Agent 熟悉的文件编辑行为,使记忆治理可以复用 Git 的提交、差异、回滚和分支语义。需要注意,Git 只保证版本可追踪和冲突可见,并不保证写入内容正确;错误记忆同样可以被可靠地提交。

5.1.3 主要优点、缺点与预期收益

预期收益 形成原因 需要监测的边界
降低每轮上下文开销 仅将核心身份放入 system/,其余内容按需读取 文件树和摘要过长时仍会占用固定 Token
提高记忆可解释性 每条记忆有路径、正文、提交记录和差异 Agent 可能选择错误路径,文件存在不等于被正确使用
支持回滚与审计 Git commit、diff 和分支提供历史 合并冲突、重复事实和过期偏好仍需人工或规则治理
支持跨设备接续 提交推送后,其他投影可拉取同一仓库 本地 Agent 未提交的修改不会自动同步
复用现有工具链 文件读写、搜索和版本控制无需重新发明接口 仅有关键词搜索时,语义相关但词面不同的内容可能漏召回

主要优点

  • 记忆可审阅。 记忆就是普通 Markdown 文件,路径、正文和 Git diff 都可以直接检查,适合人工纠错。
  • 版本可追踪。 Commit、分支和 worktree 为修改提供时间线,能够回滚到已知状态,并显式暴露并发冲突。
  • 上下文开销可控。 system/ 中的核心内容常驻,其余内容通过文件树和工具按需读取,不必将全部历史对话放入每轮 Prompt。
  • 迁移成本较低。 Agent 可以复用文件读写、搜索和 Git 工具,不需要为每一种记忆类型设计专用接口。

主要缺点

  • 检索能力依赖工具。 MemFS 默认不是向量数据库;只使用关键词搜索时,表达不同但语义相近的记忆可能无法命中。
  • 记忆质量不会自动提高。 Git 能保证版本和差异可见,不能判断内容是否错误、重复、过期或相互矛盾。
  • 提交存在同步窗口。 未提交或未推送的修改不会出现在其他运行环境;并发修改还需要处理合并冲突。
  • 运行时边界偏单 Agent。 MemFS 主要围绕一个 Agent 的仓库设计,多 Agent 共享、跨租户权限和统一索引需要额外系统支持。

与 OpenViking 相比,MemFS 更强调“让 Agent 像开发者一样编辑记忆”,OpenViking 更强调“服务端统一管理多种上下文并进行分层检索”。MemFS 的确定性来自 Git 路径和提交历史,OpenViking 的发现能力更多来自摘要、Embedding 和目录路由;前者更容易审阅和回滚,后者更适合多租户、跨资源检索与集中治理。

5.2 Agent File(.af):把 Agent 状态做成可交换文件

原文链接:letta-ai/agent-file

5.2.1 核心概念

Agent File 是面向有状态 Agent 的开放文件格式。它不是一个运行时文件系统,而是一份可以导出、下载、导入和归档的 Agent 状态包。当前仓库中的 .af 示例本质上是结构化 JSON,顶层包含 agents、groups、blocks、files、sources、tools、mcp_servers、metadata 和 created_at 等对象。

其目标是把重建一个 Agent 所需的关键状态集中到同一份文件中,典型内容包括:

状态类别 .af 中的内容 迁移时的作用
模型配置 模型名称、上下文窗口、Embedding 模型等 指定运行时能力边界和默认配置
行为定义 System Prompt、Tool Rules、标签 保留 Agent 的身份、行为约束和工具调用顺序
记忆与历史 Memory Blocks、消息历史及 in_context 标记 恢复个性、用户信息和当前上下文窗口
工具实现 工具源码、JSON Schema、执行环境变量 让 Agent 不只“知道工具”,还携带工具契约
外部引用 files、sources、MCP server 配置等 描述 Agent 依赖的文件或外部服务
安全字段 导出时将 secrets 置为 null 避免把凭据直接打包进可分享文件

因此,.af 更接近“可移植的 Agent 镜像或检查点”,而不是单独的 Prompt 模板。它保存的不只是知识,还包括行为、工具和一部分运行历史。

5.2.2 实现原理

Agent File 的实现重点在序列化协议和适配器,而不是检索算法:

  1. 导出。 从 Letta 服务中读取 Agent 的配置、记忆块、消息、工具和相关引用,按照统一 Schema 生成 .af JSON 文件。
  2. 验证。 导入方先校验版本、必填字段、对象 ID 和引用关系,再决定哪些字段能映射到本地框架。
  3. 映射。 将 system、blocks、tools、messages 等元素映射到目标框架的系统提示、记忆、工具注册和历史消息结构;无法一一对应的功能必须显式降级或拒绝导入。
  4. 重建。 创建新的 Agent 实例,重新绑定模型端点、执行环境和权限;.af 本身不应携带可直接使用的生产密钥。
  5. 版本化。 .af 可以作为仓库中的二进制/文本资产进行版本控制,也可以作为发布物在不同环境中导入,形成“导出—修改—再导入”的检查点循环。

这套机制的难点不是 JSON 能否解析,而是不同框架对“记忆块”“归档记忆”“工具状态”和“上下文窗口”的语义并不相同。项目 README 已将 Passages、数据源、MCP 配置迁移、多 Agent 文件和跨框架转换列为后续方向,说明当前格式仍主要围绕 Letta 的状态模型设计。

5.2.3 主要优点、缺点与预期收益

预期收益 形成原因 需要监测的边界
Agent 可携带、可分发 一个文件集中描述行为、记忆和工具 外部模型、数据库、文件和网络服务仍需另行准备
检查点与回滚 导出文件可保存某一时刻的完整状态 导出时未包含的远程状态无法通过回滚恢复
跨环境部署 ADE、REST API 和 SDK 都可以导入 跨框架语义不一致时,导入可能只是近似重建
形成 Agent 生态 代理可以像模型、插件一样发布和复用 工具源码和提示词的供应链安全需要审核、签名和沙箱
便于研究复现 配置、历史和工具契约集中保存 相同文件在不同模型版本、采样参数和外部数据下不保证相同输出

主要优点

  • 状态打包完整。 System Prompt、记忆块、消息历史、工具定义和模型配置可以放在同一个可传输对象中,比单独分享 Prompt 更接近完整 Agent。
  • 部署和分发简单。 .af 可通过 ADE、REST API 或 SDK 导入,适合制作模板、检查点和可下载的 Agent 资产。
  • 便于版本化与归档。 文件可以进入 Git、制品库或研究数据集,支持差异比较、回滚和长期保存。
  • 有利于生态互操作。 统一 Schema 为其他框架提供了适配入口,降低 Agent 在不同平台之间迁移的起始成本。

主要缺点

  • 跨框架迁移仍是近似转换。 不同系统对记忆块、归档记忆、工具生命周期和上下文窗口的定义不同,导入后可能需要人工修复。
  • 外部依赖没有被真正封装。 模型端点、数据库、文件、网络服务和运行权限通常需要在目标环境重新配置。
  • 行为不可完全复现。 模型版本、采样参数、工具返回值和外部数据变化,都可能让同一个 .af 产生不同结果。
  • 供应链风险集中。 文件可能同时携带系统提示、个人记忆和工具代码;导入前必须进行来源、Schema、权限、沙箱和敏感信息审查。
  • 状态覆盖仍不完整。 当前格式对 Passages、数据源、多 Agent 状态和跨框架自动转换等能力仍有限,不能等同于完整运行时快照。

.af 文件还存在一个容易被忽略的安全边界:它可能同时包含系统提示、用户信息和工具代码。导入不能等同于“打开一个文档”,而应经过来源校验、Schema 校验、工具权限审查、代码沙箱和密钥重新注入。尤其不能因为 secrets 被置为 null,就认为整个文件没有敏感信息;记忆块和历史消息本身仍可能包含个人数据、内部地址或业务机密。

5.3 两个项目与 OpenViking 的关系

三者可以按“运行时管理—记忆编辑—状态交换”划分,而不是简单按“谁更像文件系统”排序:

系统 主要回答的问题 状态边界 核心机制 最适合的场景
OpenViking 如何在大量上下文中发现、分层读取和治理内容 Resource、Memory、Skill、Session 及其索引 viking:// 命名空间、L0/L1/L2、向量检索、异步提交 长周期研发、跨会话记忆、多 Agent 共享资源
Letta MemFS Agent 如何以文件方式编辑和版本化自己的记忆 单个 Agent 的 Git-backed memory repository 真实工作区、Markdown、Git commit、branch/worktree 需要人工审阅、回滚和跨设备同步的 Agent
Agent File 如何把一个有状态 Agent 打包和迁移 Agent 配置、记忆、历史、工具和元数据 Schema 序列化、导出/导入、检查点 发布代理、环境迁移、实验复现和归档

一个更完整的组合架构可以是:用 .af 保存可迁移的 Agent 初始状态,用 MemFS 管理 Agent 的可审阅工作区,再用 OpenViking 承担跨 Agent、跨项目的长期资源检索。 这相当于把 Agent 状态拆为三层:

1
2
3
4
5
6
7
8
Agent File (.af)  ->  可迁移的初始快照:身份、工具、记忆块、历史
|
v
MemFS -> 可编辑的工作区:文件、提交、分支、审阅、回滚
|
v
OpenViking -> 可检索的上下文服务:URI、分层摘要、向量索引、跨范围召回

这种组合的收益不是简单叠加。.af 解决“带着 Agent 走”,MemFS 解决“看得见并改得回去”,OpenViking 解决“内容多了以后还能找得到”。但组合也引入了同步协议问题:.af 导入后的初始记忆与 MemFS 提交如何对应,MemFS 的文件修改何时进入 OpenViking 索引,OpenViking 召回的外部资源是否允许被重新导出,都需要明确版本号、来源和权限。

5.4 思想感悟:Agent 的“记忆”正在分化为多种可治理状态

这两个项目与 OpenViking 放在一起,最值得关注的并不是又出现了两个文件格式,而是 Agent 状态正在从一个模糊的“Memory”概念分化为至少四类对象:

  1. 工作记忆。 当前对话和当前上下文窗口中的内容,追求低延迟和任务相关性。
  2. 长期知识。 可以跨会话复用的事实、偏好、项目资料和经验,追求可发现性与更新质量。
  3. 行为程序。 System Prompt、技能、工具 Schema 和调用规则,决定 Agent 如何行动。
  4. 可迁移状态。 能被导出、审计、复制和恢复的配置与检查点,追求格式稳定性和边界清晰。

文件系统的启发在于:不同状态不必全部塞进同一个地址空间,可以通过目录、权限、版本和装载策略进行分层。但 LLM 又提出了一个经典文件系统没有的要求:内容不仅被读取,还可能被模型解释为指令。因此,“可寻址”不等于“可信”,“可恢复”也不等于“行为完全复现”。 文件路径解决的是找到什么,版本记录解决的是何时改变,安全策略和评测才解决应该不应该采用。

从工程角度看,未来更值得优先建设的不是统一一个巨大的 Agent 文件,而是统一以下元数据:来源、所有者、版本、有效期、敏感级别、可执行性、依赖模型和验证结果。这样,OpenViking 的检索、MemFS 的提交和 .af 的导入才能共享同一套治理语言。

5.5 可验证的扩展方向

可以围绕三类任务建立一个小型对照实验,而不是仅凭项目叙述判断优劣:

实验 对照 主要指标 预期观察
跨会话任务接续 OpenViking、MemFS、纯 Prompt 历史 任务完成率、首轮 Token、错误记忆率 长任务中,分层记忆应降低重复阅读;错误抽取率不能显著上升
Agent 迁移与恢复 .af 导入前后、不同模型端点 恢复成功率、工具调用正确率、人工修复项数 配置和记忆可恢复,但外部依赖与模型差异会造成部分降级
并发编辑与回滚 MemFS Git 提交、OpenViking 异步 Commit 冲突率、丢失更新数、索引陈旧时间 Git 更擅长发现冲突,OpenViking 更擅长集中检索;两者都需要一致性屏障

实验结论应分别报告检索效果、上下文成本、行为一致性和安全事件,不能只用“能否成功回答”一个指标概括。对 Agent 系统而言,真正的工程收益是让状态具有清晰的生命周期:能够找到、能够解释、能够修改、能够回滚,也能够在不可信时拒绝加载。