GEOZ

OpenViking如何管理AI Agent上下文?分层抽象与递归检索解析

2026/3/29
OpenViking如何管理AI Agent上下文?分层抽象与递归检索解析
OpenViking is an open-source context database for AI Agents that organizes context like a file system, using hierarchical abstraction (L0/L1/L2) and recursive retrieval to reduce token costs and improve task completion rates in long-running, multi-step agent scenarios. 原文翻译: OpenViking 是一个面向 AI Agent 的开源上下文数据库,它将上下文组织成文件系统,采用分层抽象(L0/L1/L2)和递归检索,旨在降低长任务、多步骤 Agent 场景中的 token 成本并提升任务完成率。

OpenViking 值得分析,不是因为它最近热,而是因为它踩中了 Agent 系统里最难啃的一块:上下文管理

模型这两年进步很快,但一个真正能连续工作的 Agent,问题常常不出在模型本身,而出在下面这些地方:

  • 用户偏好放哪儿
  • 历史任务怎么留
  • 项目文档和代码怎么组织
  • 当前会话里的临时信息怎么接住
  • 做完任务以后,哪些东西该沉淀成长期记忆

传统 RAG 更像一个"文本碎片检索器":把文档切块、向量化,再从一堆 chunk 里挑若干片段塞进 prompt。这个办法做 FAQ 或单轮问答没什么问题,但场景换成长任务、多步骤执行,问题就会变得很具体:

  1. 目录结构和上下文边界被切碎了。
  2. 检索拿到的内容局部相关,全局却可能跑偏。
  3. 为了保险,系统容易把太多文本塞进模型,token 成本一路涨。
  4. 出了问题不好查,因为很难解释检索链路到底是怎么走偏的。

OpenViking 想处理的就是这一类问题。它没有沿着"做一个更强的向量库"这条路继续卷,而是换了个抽象:把 Agent 的上下文当成文件系统来组织。

官方对它的定义是 open-source context database for AI Agents。这个定义里最值得看的是后半句——它并不把上下文理解成一堆孤立文本,而是理解成一个有目录、有层次、能递归导航的空间。

先看一张总览图:

Image 1: OpenViking 上下文文件系统总览图

  • Unified namespace

我更愿意把 OpenViking 看成一层上下文操作层。它上面接 Agent 或应用,下面接 embedding、模型服务和本地存储,中间负责三件事:

  • 统一命名空间
  • 分层加工上下文
  • 按路径把正确内容送到模型面前

Core Concept: Stop Treating Context as Just a Chunk Pool

  • Document
  • Chunk splitting
  • Embedding
  • TopK prompt assembly

OpenViking 的关键变化,不是检索接口换了个名字,而是上下文抽象变了。

在传统 RAG 里,一份知识通常会经历这样的路径:

  • 文档
  • chunk 切分
  • embedding
  • 全局相似度检索
  • TopK 拼 prompt
    在 OpenViking 里,更接近下面这个过程:
  • 资源进入 viking:// 命名空间
  • 资源被组织成目录和文件
  • 每一层目录都生成摘要和概览
  • 查询先定位目录,再逐层下钻
  • 最后只读取真正要看的细节

这两个思路的区别,看起来只是"多了一层目录",其实差别很大。

很多 Agent 任务,本来就不是"找到最像的三段文本",而是:

  • 先找到正确的项目空间
  • 再找到正确的模块或资料目录
  • 再决定读哪几个文件
  • 最后把少量细节交给模型
    人类处理复杂项目资料时,基本也是这么干的。先找位置,再看内容。OpenViking 只是把这个过程做成了系统能力。

Architectural Design: What Components Make Up OpenViking?

Namespace Layer: viking://

viking://
├── resources/
│   └── my_project/
├── user/
│   └── memories/
└── agent/
    ├── skills/
    ├── memories/
    └── instructions/

第一层是统一寻址。官方示例中,所有上下文都放在 viking:// 协议下,大致长这样:

viking://
├── resources/
│   └── my_project/
├── user/
│   └── memories/
└── agent/
    ├── skills/
    ├── memories/
    └── instructions/

这层设计看起来简单,但非常关键。

它至少解决了三个工程问题:

  • 资源、记忆、技能不再散落在不同后端,地址统一了。
  • 目录关系能保留下来,不会一上来就被切成无父无子的碎片。
  • 后面的递归检索终于有了真正可以走的路径。

Representation Layer: L0 / L1 / L2

这是 OpenViking 公开资料里出现最频繁的一组概念:

  • L0:一句摘要,官方给出的量级大约是 100 tokens。
  • L1:结构化概览,量级大约是 2k tokens。
  • L2:完整内容,只有真的需要时才加载。
    这不是普通的"摘要 + 原文"两层结构,而更像一个分辨率切换机制。
  • 系统刚开始判断相关性时,看 L0 就够了。
  • 进入规划或决策阶段时,再看 L1。
  • 需要实现细节、代码或完整上下文时,才读 L2。
    真正有意思的是,README 里给出的例子不只给文件生成 .abstract.overview,目录本身也会有自己的摘要和概览。这样一来,目录不是静态容器,而成了可检索节点。

Retrieval Layer: Recursive Retrieval Engine

def recursive_retrieve(query, node):
    intents = expand_query_intent(query)
    candidates = semantic_search(node.children_summaries(), intents)

    hits = []
    for child in top_k(candidates):
        if child.is_directory:
            hits.extend(recursive_retrieve(query, child))
        else:
            hits.append(child)

    return rerank_and_load_details_on_demand(hits)

OpenViking 最像它自己的地方,就在这儿。

它不是一上来就在全局语料里捞 TopK,而是先找高分目录,再进目录里继续找。如果还有更细的子目录,就继续往下走。

这条链路可以概括成下面几步:

  1. 分析查询意图,扩展检索条件。
  2. 在 L0 / L1 层定位高相关目录。
  3. 进入目录后继续检索子目录和文件。
  4. 在更小的候选集合里继续筛选。
  5. 只在最后阶段读取 L2 详情。
    对应的思路,可以用一段很短的伪代码说明:
def recursive_retrieve(query, node):
    intents = expand_query_intent(query)
    candidates = semantic_search(node.children_summaries(), intents)
>
    hits = []
    for child in top_k(candidates):
        if child.is_directory:
            hits.extend(recursive_retrieve(query, child))
        else:
            hits.append(child)
>
    return rerank_and_load_details_on_demand(hits)

这不是源码,只是把 README 里的公开思路压成了一个更好懂的形状。重点不在代码,而在背后的策略:先收缩搜索空间,再读细节。

Session and Memory Layer

很多检索系统擅长"查",但不太擅长"用完以后怎么办"。Agent 系统不一样,它必须处理回写问题:

  • 用户偏好要不要沉淀成长期记忆
  • 新生成的文档要不要进入项目资源
  • 这次任务学到的执行经验要不要被 Agent 复用
    OpenViking 的公开说明里提到自动会话管理、记忆压缩和长期记忆抽取。换句话说,它不只是 retrieval store,还试图负责记忆的回流。

Engineering Form: Not a Single-Language Project

从仓库结构能看到,OpenViking 并不是把所有东西都塞在一个 Python 包里:

  • openviking:核心 Python 包
  • crates/ov_cliopenviking_cli:Rust CLI
  • AGFS:README 提到需要 Go 1.22+ 构建
  • src 和 native extension:承接性能敏感部分
  • bot:面向 Agent / Bot 的接入层
    这套拆法挺务实。Python 负责生态集成和开发效率,Rust 适合做 CLI,Go 负责部分系统能力,底层扩展则用来处理性能热点。

Workflow: How a Query Travels Through OpenViking

下面这张图可以先把检索路径看清楚:

Image 2: OpenViking 递归检索流程图

Resource Ingestion

openviking-server
ov add-resource https://github.com/volcengine/OpenViking --wait
ov tree viking://resources/volcengine -L 2

第一步通常是把外部资料收进 viking://resources/。官方 CLI 示例里,直接把一个 GitHub 仓库加进来就行:

openviking-server
ov add-resource https://github.com/volcengine/OpenViking --wait
ov tree viking://resources/volcengine -L 2

这一步背后通常会发生几件事:

  • 拉取或解析外部资源
  • 把内容映射为目录和文件
  • 为目录和文件生成 L0 / L1 表示
  • 为后续检索建立向量表示

Query Entry into the System

当 Agent 抛出一个问题,比如"这个项目的上下文加载机制怎么做",OpenViking 不会立刻把一大段正文推给模型。它先会在摘要层做粗定位,先判断:

  • 相关信息更可能在 resources/user/ 还是 agent/
  • 哪个目录最值得先进去看
  • 哪些目录可以直接排除

Further Refinement Within Directories

  • Subdirectory summaries
  • File summaries

一旦命中了某个目录,检索空间就从全局语料缩到局部子树。接下来的步骤不是"重复全局搜索",而是在目录内部继续看:

  • 子目录摘要
  • 文件摘要
  • 局部候选的相关性
    如果信息还不够,就继续往下钻。

On-Demand L2 Reading

A typical problem with

常见问题(FAQ)

OpenViking 如何降低 AI Agent 的 token 成本?

OpenViking 通过分层抽象(L0/L1/L2)和递归检索,避免将大量无关文本塞入提示词。它像文件系统一样组织上下文,让 Agent 按需获取必要内容,从而显著减少 token 使用。

OpenViking 与传统 RAG 在上下文管理上有何根本区别?

传统 RAG 将文档切块后做全局相似性检索,容易破坏目录结构和上下文边界。OpenViking 则将上下文视为有目录、有层次的空间(viking:// 命名空间),支持按路径递归导航和分层加工。

OpenViking 的分层抽象(L0/L1/L2)具体指什么?

这是 OpenViking 的核心设计。它代表上下文的不同抽象级别:L0 可能是原始细节,L1 是章节或模块摘要,L2 是更高层概述。这种结构支持从目录定位开始,层层下钻的检索方式。

Roger深圳
本文由 Roger 审核,最后更新于 2026年7月24日
联系编辑 →
← 返回文章列表
分享到:微博

版权与免责声明:本文仅用于信息分享与交流,不构成任何形式的法律、投资、医疗或其他专业建议,也不构成对任何结果的承诺或保证。

文中提及的商标、品牌、Logo、产品名称及相关图片/素材,其权利归各自合法权利人所有。本站内容可能基于公开资料整理,亦可能使用 AI 辅助生成或润色;我们尽力确保准确与合规,但不保证完整性、时效性与适用性,请读者自行甄别并以官方信息为准。

若本文内容或素材涉嫌侵权、隐私不当或存在错误,请相关权利人/当事人联系本站,我们将及时核实并采取删除、修正或下架等处理措施。也请勿在评论或联系信息中提交身份证号、手机号、住址等个人敏感信息。