news 2026/9/10 2:42:27

OpenViking 存储架构解析:VikingFS URI 抽象层、AGFS 内容存储与向量库索引的双层设计

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
OpenViking 存储架构解析:VikingFS URI 抽象层、AGFS 内容存储与向量库索引的双层设计

OpenViking 存储架构解析:VikingFS URI 抽象层、AGFS 内容存储与向量库索引的双层设计

【免费下载链接】OpenVikingSelf-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.项目地址: https://gitcode.com/GitHub_Trending/op/OpenViking

本文基于 OpenViking 概念文档「存储架构」展开,完整解析其双层存储模型:VikingFS(URI 抽象层)如何屏蔽底层差异、AGFS 如何作为唯一内容数据源、向量库如何只存引用不存内容,以及 VikingFS 如何在删除/移动时自动同步向量索引。读完本文,你将理解 OpenViking 上下文数据的落盘结构、上下文集合的完整 Schema、向量库多后端接入机制,以及多写模式的配置要点,足以支撑你针对自己的部署场景选择合适的存储后端并保持索引与内容的一致性。

概览:双层存储架构

OpenViking 采用双层存储架构,分离内容存储和索引存储。整体结构如下:

┌─────────────────────────────────────────┐ │ VikingFS (URI 抽象层) │ │ URI 映射 · 层级访问 │ └────────────────┬────────────────────────┘ ┌────────┴────────┐ │ │ ┌───────▼────────┐ ┌─────▼───────────┐ │ 向量库索引 │ │ AGFS │ │ (语义搜索) │ │ (内容存储) │ └────────────────┘ └─────────────────┘

上层是 VikingFS 提供的统一 URI 抽象层,负责 URI 映射与层级访问;下层则分为两个独立角色:

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

设计优势

  1. 职责清晰:向量库只负责检索,AGFS 负责存储
  2. 内存优化:向量库不存储文件内容,节省内存
  3. 单一数据源:所有内容从 AGFS 读取,向量库只存引用
  4. 独立扩展:向量库和 AGFS 可分别扩展

注:AGFS 已经重写为 Rust 实现(RAGFS),对应仓库中的crates/ragfscrate 及其 Python 绑定crates/ragfs-python

这一「内容与索引分离」的取舍在源码中体现得非常直接:向量记录中的content字段只写入截断后的文本(受VIKINGDB_CONTENT_MAX_SIZE约束,见 collection_schemas.py 中TextEmbeddingHandler._materialize_content),用于 VikingDB 系后端的服务端全文检索,而文件的完整内容始终留在 AGFS 一侧,检索命中后通过 URI 回到 AGFS 读取原文。

VikingFS 虚拟文件系统

VikingFS 是统一的 URI 抽象层,屏蔽底层存储细节。它的实现位于 openviking/storage/viking_fs 目录,按职责拆分为多个模块:_base.py(基础操作)、_access.py(访问控制)、_vector.py(向量同步)、_semantic.py(语义检索)、_sync.py(目录同步原语)等,对上层 SDK、HTTP API 和 CLI 暴露一致的文件系统接口。

URI 映射

viking://resources/docs/auth → /local/{account_id}/resources/docs/auth viking://~/memories → /local/{account_id}/user/{user_id}/memories viking://~/skills → /local/{account_id}/user/{user_id}/skills

可以看到 URI 映射隐含了租户隔离:resources挂在账号(account_id)维度,~/开头的个人空间则进一步按user_id隔离。完整的 URI 规范见 Viking URI。

核心 API

方法说明
read(uri)读取文件内容
write(uri, data)写入文件
mkdir(uri)创建目录
rm(uri)删除文件/目录(同步删除向量)
mv(old, new)移动/重命名(同步更新向量 URI)
abstract(uri)读取 L0 摘要
overview(uri)读取 L1 概览
find(query, uri)语义搜索

其中abstractoverview对应上下文层级的 L0/L1 两层(详见 上下文层级),find则是走向量库的语义搜索入口。

AGFS 底层存储

AGFS 提供 POSIX 风格的文件操作,支持多种后端。Python 侧的客户端接口封装在 openviking/pyagfs,包含async_client.pyprotocols.py等模块。

单后端与多写模式

默认情况下,AGFS 使用一个后端作为内容存储。配置storage.agfs.backups后,OpenViking 会启用多写模式:

  • 顶层storage.agfs.backend是 primary,作为权威写入目标。
  • storage.agfs.backups.items[]是 backup,用于副本、迁移或读加速。
  • Python SDK、HTTP API 和 CLI 的文件系统接口保持不变。
  • 多写内部使用.redirect.json.sync_log.json维护 redirect 映射与同步进度,这些文件对用户不可见。

更多概念说明见 多写存储,配置示例见 多写存储指南。

后端类型

后端说明配置
localfs本地文件系统path
s3fsS3 兼容存储bucket,endpoint
memory内存存储(测试用)-

目录结构

每个上下文目录遵循统一结构:

viking://resources/docs/auth/ ├── .abstract.md # L0 摘要 ├── .overview.md # L1 概览 └── *.md # L2 详细内容

L0/L1/L2 的命名规则与向量集合中的level字段一一对应:level=0对应{目录}/.abstract.mdlevel=1对应{目录}/.overview.mdlevel=2(默认)对应实际文件路径。这一约定直接写在集合 Schema 的字段注释中(见 collection_schemas.py 的CollectionSchemas.context_collection)。

向量库索引

向量库存储语义索引,支持向量搜索和标量过滤。

Context 集合 Schema

概念文档给出的核心字段如下:

字段类型说明
idstring主键
uristring资源 URI
parent_uristring父目录 URI
context_typestringresource/memory/skill
is_leafbool是否叶子节点
vectorvector密集向量
sparse_vectorsparse_vector稀疏向量
abstractstringL0 摘要文本
namestring名称
descriptionstring描述
created_atstring创建时间
active_countint64使用次数

对照当前仓库的实现,collection_schemas.py 中context_collection的 Schema 在上述基础上还有几处值得注意的细节:

  • 字段类型uriFieldTypepath(而非普通 string),vector字段声明了Dim(由config.embedding.dimension决定);
  • context_type的推导规则(源码注释):URI 位于 user skills 目录下 →"skill";URI 包含"memories""memory";其他情况 →"resource"
  • 额外的标量字段level(L0/L1/L2 层级)、tagssearch_tagslist<string>)、content(text 类型)、account_idowner_user_id,以及一组 ACL 相关字段(acl_mode及 grant 字段);
  • ScalarIndexuritypecontext_typecreated_atupdated_atactive_countlevelnametagssearch_tagsaccount_idowner_user_id及 ACL 字段均建有标量索引,保证「向量召回 + 标量过滤」的复合查询可以下推到向量库执行;
  • FullTextcontent字段配置了全文索引(standard分词器,过滤 symbol 停用词)。collection_schemas.py 中init_context_collection还有一段兼容逻辑:若既有集合缺少content/FullText 配置,只会在grep engine=auto时回退到文件系统 grep,而不是阻止服务启动。

此外,集合创建时还会把当前嵌入模型的元数据(provider/model/dimension/model_identity)编码进集合描述中。后续启动时若发现元数据与当前配置不一致,会抛出EmbeddingRebuildRequiredError要求重建;若仅 provider/model 变化而维度不变,可通过embedding.allow_metadata_override=true显式保留既有向量。

索引策略

index_meta = { "IndexType": "flat_hybrid", # 混合索引 "Distance": "cosine", # 余弦距离 "Quant": "int8", # 量化方式 }

从源码看,IndexType 的实际取值只有两种(见 validation.py):

  • flat:仅密集向量的 flat 索引;
  • flat_hybrid:密集 + 稀疏混合索引。

在 vectordb_adapters/base.py 中可以看到默认策略:index_type = "flat_hybrid" if use_sparse else "flat",即是否启用混合索引取决于稀疏向量(sparse embedding)是否开启。

后端支持

后端说明
local本地持久化
httpHTTP 远程服务
volcengine火山引擎 VikingDB

当前仓库的适配层位于 openviking/storage/vectordb_adapters,factory.py 中的注册表实际包含五个内置后端:

_ADAPTER_REGISTRY: dict[str, type[CollectionAdapter]] = { "local": LocalCollectionAdapter, "cuvs": CuVSCollectionAdapter, "http": HttpCollectionAdapter, "volcengine": VolcengineCollectionAdapter, "vikingdb": VikingDBPrivateCollectionAdapter, }

即除了文档列出的三个,还支持cuvs(本地 GPU 索引)与vikingdb(私有化部署)。create_collection_adapter(config)config.backend路由;若 backend 值包含.,则按完整类路径动态加载第三方 Adapter,并可通过custom_params传递自定义参数。完整的接入步骤(新增 Adapter 类、实现from_config/_load_existing_collection_if_needed/_create_backend_collection、注册到 factory、补充配置)见 vectordb_adapters/README.md。

两点实现细节:

  • 懒加载集合:各 Adapter 通过_load_existing_collection_if_needed懒加载已存在的 collection handle,不存在时保持为空,后续按需创建;
  • content 字段策略:Adapter 基类的USE_CONTENT_FIELD类属性默认为False,仅 VikingDB 系后端开启,写入时其他后端会自动跳过content字段,避免无谓的全文存储开销。

向量同步

VikingFS 自动维护向量库与 AGFS 的一致性,相关逻辑收敛在openviking/storage/viking_fs/_vector.py(向量读写同步)与_sync.py(目录级 diff 与 mv/rm 合并原语)中。

删除同步

viking_fs.rm("viking://resources/docs/auth", recursive=True) # 自动递归删除向量库中所有 uri 以此开头的记录

即删除 AGFS 侧目录时,向量库中所有uri以该路径为前缀的记录会被一并清理,不会出现「幽灵向量」指向已删除内容的问题。

移动同步

viking_fs.mv( "viking://resources/docs/auth", "viking://resources/docs/authentication" ) # 自动更新向量库中的 uri 和 parent_uri 字段

mv在重命名目录后会自动把受影响向量记录的uriparent_uri字段更新为新路径,保证向量库中的引用链与 AGFS 目录树始终对应。从_sync.py的实现可以看到,目录级同步(sync_tree)采用「自上而下的递归 diff + 移动合并」策略:对可见子节点做增/删/改对比(.开头的隐藏文件被跳过,parser 副产物如.image_mappings.json由调用方显式携带),并通过SyncDiff结构返回目标侧的变更清单,供增量重建索引的管线消费。

总结与延伸阅读

回到双层架构的四个核心收益:向量库只管检索、内容统一从 AGFS 读取、引用与原文一一对应、两层可独立扩展。理解这套架构后,再结合以下几个文档可以补全全貌:

  • 架构概述 - 系统整体架构
  • 上下文层级 - L0/L1/L2 模型
  • Viking URI - URI 规范
  • 多写存储 - primary/backup、多写路由与一致性
  • 检索机制 - 检索流程详解

【免费下载链接】OpenVikingSelf-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.项目地址: https://gitcode.com/GitHub_Trending/op/OpenViking

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 2:41:59

冬季电脑故障高发?防静电与低温防护实操指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 2:40:03

Python数据类型全解析:从对象模型到性能优化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/10 2:36:15

SpringBoot+Vue健康饮食系统调试实战指南

简介&#xff1a;这是一套面向计算机专业本科生的Java全栈毕设实战项目&#xff0c;聚焦智能健康饮食场景&#xff0c;专为毕业设计、课程设计及期末大作业打造&#xff0c;兼顾SpringBoot后端开发与Vue前端工程化实践能力训练。资源包共353个文件&#xff0c;涵盖88个核心Java…

作者头像 李华