快速摘要: OpenViking 是由火山引擎 Viking 团队开源的一款 AI Agent 上下文数据库,它跳出了传统 RAG 的碎片化向量存储思路,创造性地引入"文件系统范式"来统一管理 Agent 所需的记忆(Memory)、资源(Resources)和技能(Skills)。 通过 L0/L1/L2 三层上下文分级、目录递归检索策略、可视化检索轨迹以及会话自动管理等核心机制,OpenViking 在大幅降低 Token 消耗的同时,显著提升了上下文检索的准确性和可观测性。如果你正在做 AI Agent 开发,并且被上下文管理的种种痛点困扰,这篇文章将从底层原理到实际操作,为你完整拆解 OpenViking 的设计哲学与使用方法——往下看有更详细的拆解。 本文由 莫潇羽@无忆研习社(www.wuyi.wiki)原创撰写,转载请注明出处。
为什么 AI Agent 的上下文管理如此困难
做过 AI Agent 开发的朋友应该深有体会,随着 Agent 的能力越来越强、任务越来越复杂,上下文管理正在变成一个"隐形天花板"。表面上看,大模型的上下文窗口越来越大(从最初的 4K 到现在的 128K 甚至更长),似乎已经"够用了"。但实际工程中,问题远比想象的复杂。
莫潇羽在日常做 Agent 开发时,遇到的典型困境大概可以归纳为以下几个方面。
上下文碎片化严重。 在一个稍微复杂一点的 Agent 系统中,用户的偏好记忆可能写在代码的某个角落,项目文档被切片后塞进了向量数据库,Agent 的技能和指令分散在各个配置文件中。这些上下文之间缺乏统一的组织方式,想要关联起来异常困难。就好比你桌上的文件散落一地,找一份特定的资料需要翻遍每一个角落。
长程任务的 Token 成本不可控。 当 Agent 需要处理跨多轮对话的长周期任务时,每一轮的对话历史、工具调用记录、中间结果都会不断累积。把所有上下文一股脑塞进 Prompt 里?Token 费用会让你心惊肉跳。简单粗暴地截断或压缩?对不起,关键信息可能就在被你丢弃的那一段里,而且这种信息损失是不可逆的。
传统 RAG 的检索瓶颈。 传统的 RAG(检索增强生成)方案把文档切片后存入向量数据库,通过语义相似度来召回相关片段。这种"扁平式"的存储和检索方式,在面对简单查询时尚可应付,但遇到复杂意图、多模态数据、或者需要理解信息层级关系的场景时,就显得力不从心了。它缺乏全局视野,无法理解一个信息片段在整体文档结构中的位置和语境。
检索链路的"黑箱"问题。 你问 Agent 一个问题,它给了你一个不太对的回答。到底是哪里出了问题?是检索的时候没找到正确的文档?还是找到了但排序不对?还是上下文组装环节出了差错?传统 RAG 的整个检索链路几乎是不透明的,排查问题就像大海捞针。
Agent 的"记忆"不会成长。 大多数现有方案中,Agent 的"记忆"仅仅是对用户对话历史的简单记录。Agent 在执行任务过程中积累的经验、踩过的坑、摸索出的技巧,并没有被有效沉淀下来。每次遇到类似的问题,Agent 都像是在从零开始,无法实现真正的"越用越聪明"。
这些痛点叠加在一起,使得 AI Agent 的上下文管理堪称开发中的一大难关。
莫潇羽@无忆研习社在跟一些做 Agent 开发的同行交流时发现,几乎每个团队在项目推进到一定阶段后,都会遇到上下文管理的"瓶颈期"。前期原型阶段,因为数据量小、任务简单,上下文管理的问题不明显。但一旦进入真实场景,当 Agent 需要处理大量文档、记住复杂的用户偏好、协调多个工具调用时,这些问题就会集中爆发。而且这些问题往往不是某个单一技术能解决的——你不能只靠扩大上下文窗口来解决成本问题,也不能只靠优化向量索引来解决碎片化问题。需要的是一套系统性的、从底层架构出发的解决方案。
这就是 OpenViking 出现的背景。它并不是又一个 RAG 框架的"改良版",而是试图从根本上重新定义 AI Agent 的上下文管理范式。
OpenViking 是什么:一句话定义
OpenViking 是一个开源的、专为 AI Agent 设计的上下文数据库(Context Database)。它由字节跳动旗下火山引擎的 Viking 团队发起并维护,项目采用开源协议,代码托管在 GitHub 上。
与传统的向量数据库或 RAG 框架不同,OpenViking 的核心创新在于:它用文件系统范式来统一管理 Agent 运行所需的全部上下文。你可以把它理解为"Agent 的大脑"——像管理本地文件一样,用建目录、读文件、搜索等最朴素的操作,来管理 Agent 的记忆、资源和技能。
项目的 GitHub 地址:https://github.com/volcengine/OpenViking
如果你用过 Linux,一定对"一切皆文件"这个经典理念不陌生。OpenViking 可以说是把这个理念搬到了 AI Agent 的上下文管理领域——一切上下文皆文件。这个思路看起来简单,但正如 Linux 用这个理念统一了硬件资源的管理一样,OpenViking 用它统一了 Agent 上下文的管理,背后的设计考量其实相当深刻。
设计哲学:为什么选择"文件系统范式"
在深入技术细节之前,莫潇羽觉得有必要先聊聊 OpenViking 为什么选择了文件系统作为其核心范式。这不是一个随意的决定,而是对行业多种实践经验的总结和提炼。
近年来,AI Agent 领域已经有不少团队在探索上下文工程(Context Engineering)的最佳实践。Manus 团队曾经提出"文件系统是上下文的终极形态"这一观点;Anthropic 的 Claude Code 产品验证了"文件系统 + Bash 命令"这种简洁方案在特定场景下甚至能超越复杂向量索引的潜力;而 Anthropic 的 Skills 系统也在用文件夹来组织能力模块。这些实践说明了一个趋势:文件系统是组织上下文的一种天然且高效的方式。
但是,这些实践也暴露了一个缺口——虽然文件系统很适合组织上下文,但市面上并没有一个类似"数据库"的工具,能够以文件系统的方式有效管理 Agent 所需的所有上下文,并系统性地解决前面提到的那些痛点。
OpenViking 就是为了填补这个缺口而诞生的。
选择文件系统范式有几个天然的优势。首先,开发者对文件系统的操作是极其熟悉的。建目录、浏览文件、搜索内容,这些都是每个开发者每天都在做的事情,学习成本几乎为零。其次,文件系统天然具备层级结构,这为上下文的层次化组织提供了完美的载体。最后,文件系统的操作语义是明确和可追溯的,ls、find、read 这些操作的含义没有任何歧义,这使得整个检索链路变得透明可观测。
除了上述直接优势之外,文件系统范式还有一个深层次的好处:它天然适配"渐进式"的上下文管理策略。在文件系统中,你可以先看到一个文件夹的名字,再打开看里面有什么文件,再选择性地打开某个文件查看内容——这是一个从粗到细、逐步深入的过程。这种"渐进式"的信息获取方式,恰好与大语言模型的最佳使用方式不谋而合:先给模型一个宏观的信息概览来做决策,再根据需要加载具体的详细内容来执行任务。OpenViking 的 L0/L1/L2 三层设计,正是这种"渐进式"理念的具体体现。
莫潇羽@无忆研习社觉得,OpenViking 的设计哲学可以用八个字来概括:以简驭繁,以熟化生。用最简单、最熟悉的概念(文件系统),来驾驭最复杂、最前沿的问题(AI Agent 上下文管理)。这种化繁为简的能力,往往是判断一个开源项目是否真正具有技术深度的标志。
五大核心机制详解
OpenViking 的设计围绕五个核心机制展开,它们分别对应前面提到的五大痛点,形成了一套完整的上下文管理解决方案。接下来,莫潇羽@无忆研习社将逐一为大家拆解这些机制的原理。
机制一:虚拟文件系统——统一上下文的"大一统"方案
OpenViking 的第一个核心机制,是将所有类型的上下文统一抽象到一个虚拟文件系统中。不再是记忆放一处、资源放一处、技能放一处的碎片化状态,而是将它们全部映射到 viking:// 协议下的虚拟目录,每个条目对应一个唯一的 URI(统一资源标识符)。
下面这个目录结构能帮助你直观理解这种组织方式:
viking://
├── resources/ # 资源:项目文档、代码库、网页等
│ ├── my_project/
│ │ ├── docs/
│ │ │ ├── api/
│ │ │ └── tutorials/
│ │ └── src/
│ └── ...
├── user/ # 用户:个人偏好、习惯等
│ └── memories/
│ ├── preferences/
│ │ ├── 写作风格
│ │ └── 编程习惯
│ └── ...
└── agent/ # Agent:技能、指令、任务记忆等
├── skills/
│ ├── search_code
│ ├── analyze_data
│ └── ...
├── memories/
└── instructions/
可以看到,无论是项目文档、用户偏好、还是 Agent 的技能模块,都被纳入到了统一的文件树结构中。每一个条目都有明确的路径和位置关系,就像你电脑上的文件系统一样清晰。
这种范式赋予了 Agent 前所未有的上下文操控能力。Agent 可以像开发者一样,通过 ls(列出目录)、find(搜索文件)、read(读取内容)等标准指令,来精确、确定性地定位和操作上下文信息。上下文管理从模糊的语义匹配,变成了直观、可追溯的"文件操作"。
对于开发者来说,这意味着你不需要再去学习复杂的向量数据库查询语法,也不需要理解各种抽象的检索概念。你只需要用最熟悉的文件操作思维,就能完成对 Agent 上下文的全部管理。
更重要的是,这种范式对 Agent 本身也非常友好。大语言模型在理解文件路径、目录结构这类概念上表现非常好(毕竟训练数据中有大量相关内容),因此 Agent 可以非常自然地使用文件系统的操作指令来管理自己的上下文。比如,Agent 可以主动执行"列出用户的偏好记忆目录"来获取用户画像,或者执行"在技能目录下搜索数据分析相关的技能"来为当前任务选择合适的工具。这种人机统一的操作语义,极大地简化了 Agent 系统的设计复杂度。
从实际工程的角度看,虚拟文件系统的另一个好处是天然支持权限控制和作用域隔离。你可以为不同的用户分配不同的记忆目录,为不同的 Agent 实例分配不同的技能目录。不同 Agent 之间可以共享 resources/ 目录下的公共资源,同时保持各自的 memories/ 目录相互隔离。这在多租户或多 Agent 协作的场景下尤为重要。
机制二:L0/L1/L2 三层上下文——像"金字塔"一样按需加载
这是 OpenViking 在降低 Token 消耗方面的核心设计。传统做法是把所有可能相关的上下文一股脑塞进 Prompt,不仅费用高昂,还容易超出模型的上下文窗口,引入大量噪声信息干扰模型的判断。
OpenViking 借鉴了计算机图形学中 LOD(Level of Detail,细节层次)的思想,在上下文写入时,就自动将其处理为三个层级:
L0 层(摘要 / Abstract): 大约 100 个 Token,是对内容的一句话高度概括。它的作用是在检索阶段用于快速筛选和判断相关性。你可以把它理解为一本书的书名和一句话简介——看一眼就知道这本书大概讲什么,值不值得翻开。
L1 层(概述 / Overview): 大约 2000 个 Token,包含了核心信息、结构要点和使用场景。它的作用是供 Agent 在规划阶段进行决策——了解这个资源的主要内容、包含哪些部分、适合在什么场景下使用。你可以把它理解为一本书的目录和内容提要。
L2 层(详情 / Details): 完整的原始数据,只在 Agent 确认需要深入阅读时才加载。这就是书的完整正文。
我们来看看这三层结构在文件系统中的具体体现:
viking://resources/my_project/
├── .abstract # L0 层:摘要(~100 tokens)——快速判断相关性
├── .overview # L1 层:概览(~2k tokens)——了解结构和要点
├── docs/
│ ├── .abstract # 每个子目录也有对应的 L0/L1 层
│ ├── .overview
│ ├── api/
│ │ ├── .abstract
│ │ ├── .overview
│ │ ├── auth.md # L2 层:完整内容——按需加载
│ │ └── endpoints.md
│ └── ...
└── src/
└── ...
注意一个精妙的细节:每个目录都有自己的 .abstract 和 .overview 文件。这意味着 Agent 可以从根目录开始,先通过 L0 快速扫描哪些目录可能与当前查询相关,再通过 L1 了解具体内容结构,最后只对真正需要的文件加载 L2 全文。
举一个实际的例子来帮助理解。假设你的 Agent 接收到一个用户提问:"API 的认证方式有哪些?"
在传统方案中,Agent 可能需要把整个项目文档全部加载进来(可能是几万甚至十几万 Token),然后让模型从中找答案。而使用 OpenViking 的分层加载策略后:
Agent 先读取项目根目录的 L0 摘要(约 100 Token),确认这个项目确实包含 API 文档。然后读取 docs/ 目录的 L1 概述(约 2000 Token),发现其中有一个 api/ 子目录。接着读取 api/ 目录的 L1 概述,发现里面有 auth.md 这个文件与认证相关。最后,只需要加载 auth.md 这一个文件的 L2 全文。
整个过程可能只消耗了原来十分之一甚至更少的 Token,却精准地找到了需要的信息。这种"先粗后细、逐级深入"的策略,在工程上的效果是非常显著的。
莫潇羽在实际测试中发现,分层加载策略对于那些"大资源库 + 精确查询"的场景效果尤为突出。比如一个包含几十万字技术文档的项目,如果用传统方式全量加载,可能需要消耗十万级别的 Token。而使用 L0/L1/L2 的分层策略,大多数查询只需要消耗几千个 Token 就能得到满意的答案。当然,对于那些需要全面了解整个项目的"宏观查询",Token 消耗会相对多一些,但仍然远低于全量加载的方式。
另一个值得关注的细节是,L0 和 L1 层的内容是在资源写入时就自动生成的,而不是在查询时才实时计算。这意味着查询时的响应速度不会受到摘要生成过程的影响。OpenViking 利用 VLM 模型来理解原始内容并生成不同层级的摘要,这个过程在 add_resource 之后异步完成。一旦处理完毕,后续的所有查询都能享受分层加载带来的性能优势。
这种设计思路其实借鉴了计算机科学中非常经典的"缓存层次"概念——CPU 的 L1/L2/L3 缓存就是类似的分层结构,越靠近处理器的缓存越小但越快,越远离处理器的缓存越大但越慢。OpenViking 的 L0/L1/L2 也是同样的道理:L0 最精简、检索最快;L2 最完整、但只在必要时才加载。
机制三:目录递归检索——不只是语义匹配,更是"结构化寻路"
传统 RAG 只依赖向量相似度进行语义匹配,这在面对复杂查询意图时往往力不从心。OpenViking 设计了一套创新的"目录递归检索策略",将目录结构定位与语义搜索深度融合。
这个检索过程可以分为五个步骤:
第一步:意图分析。 系统首先对用户的查询进行意图分析,从中提取出多个检索条件。比如用户问"怎么用 OAuth 2.0 做 API 认证",系统可能会生成"OAuth 2.0"、"API 认证"、"授权流程"等多个检索维度。
第二步:初始定位。 利用向量检索,快速在全局范围内定位得分最高的目录。这一步相当于先锁定"大方向"——确定答案最可能存在于哪个目录下。
第三步:精细探索。 在上一步定位的高分目录内,进行更精细的二次检索。这一步会将高分结果更新到候选集合中。
第四步:递归下探。 如果当前目录下还存在子目录,则继续向下逐层递归,重复上述的二次检索步骤。就像你在电脑上层层点开文件夹寻找目标文件一样。
第五步:结果汇总。 最终,从所有候选结果中筛选出最相关的上下文返回给 Agent。
用一段伪代码来描述这个过程可能更直观:
def recursive_retrieve(query, directory):
# 1. 在当前目录下进行语义检索
local_results = semantic_search(query, directory)
candidates.update(local_results)
# 2. 获取当前目录的子目录
subdirs = get_subdirectories(directory)
# 3. 对子目录进行评分排序
scored_dirs = score_directories(query, subdirs)
# 4. 对高分子目录递归深入
for subdir in scored_dirs.top_k():
recursive_retrieve(query, subdir)
return candidates.get_top_results()
这种"先锁定高分目录、再精细探索内容"的策略,相比传统的扁平检索有一个巨大的优势:它不仅能找到语义上最匹配的片段,还能理解这个片段在整体信息结构中的位置和语境。打个比方,传统 RAG 就像在图书馆里用关键词随机翻书,而 OpenViking 的目录递归检索则像先找到正确的书架、再找到正确的书、最后翻到正确的章节——效率和准确度完全不在一个层面上。
这种检索策略还有一个容易被忽略的优势:它天然具备"上下文感知"能力。传统的向量检索返回的是孤立的文本片段,你不知道这个片段来自哪篇文档的哪个章节,也不清楚它前后还有什么相关内容。但在 OpenViking 的目录递归检索中,每个检索结果都带有完整的路径信息。Agent 不仅知道"找到了什么",还知道"这个东西在哪个目录下、旁边还有哪些相关文件"。这对于 Agent 做出更准确的判断和更完整的回答至关重要。
举个具体例子。假设用户问"项目中的认证模块是怎么实现的"。传统 RAG 可能只返回认证相关的一两个文本片段。而 OpenViking 的目录递归检索会先定位到 docs/api/ 这个目录,然后发现这个目录下除了 auth.md 之外,还有 endpoints.md、errors.md 等文件。Agent 可以主动读取 auth.md 的完整内容来回答认证问题,同时知道如果用户后续问到 API 端点或错误码的问题,可以到哪里去找——这就是"上下文感知"的价值所在。
机制四:可视化检索轨迹——让"黑箱"变成"白箱"
这一点是很多现有 RAG 系统所欠缺的能力。在传统方案中,Agent 的检索过程完全是隐式的,你只能看到最终的输出结果,却无法知道中间发生了什么。一旦出错,排查问题的难度极高。
OpenViking 通过层次化虚拟文件系统结构来解决这个问题。由于所有上下文均以统一格式整合,并且每个条目对应唯一的 URI 路径,因此整个检索过程天然具备可追溯性。
具体来说,你可以清楚地看到:
Agent 在处理一个查询时,最初从哪个目录开始搜索;在搜索过程中,递归进入了哪些子路径;每个子路径的相关性得分是多少;为什么最终选择加载了某个特定的资源;整个检索链路是如何一步步展开的。
这种透明性对于调试和优化至关重要。想象一下,当你发现 Agent 给出了不准确的回答,你可以回溯整个检索过程,精确定位到底是哪个环节出了问题——是初始定位偏了?还是递归过程中错过了某个关键子目录?还是最终的排序逻辑有问题?有了这些信息,优化工作就变得有的放矢了。
莫潇羽@无忆研习社认为,这一点在实际工程中的重要性怎么强调都不为过。在传统 RAG 系统的开发过程中,最让人头疼的环节往往不是"怎么搭建",而是"搭建好之后怎么调优"。你知道检索结果不够好,但你不知道问题出在哪里。是切片策略不合理?是 Embedding 模型的效果不行?是检索 Top-K 的设置太小?这种"盲调"的过程极其低效。
而 OpenViking 的可视化检索轨迹,本质上是将整个检索过程"白箱化"了。你可以清楚地看到系统的每一步决策:先从哪个目录开始,为什么认为这个目录得分高,进入之后又发现了什么,最终为什么返回了这些结果。这就好比一个经验丰富的图书管理员在帮你找书时,会告诉你"我先去了二楼的计算机科学区,然后在编程语言这个书架上,找到了这三本可能相关的书"——你不仅得到了结果,还理解了整个寻找过程的逻辑。
对于团队开发来说,这种可观测性还有助于成员之间的协作和知识共享。当一个团队成员优化了某个场景的检索效果后,他可以通过可视化轨迹清晰地向其他成员解释"做了什么改动、为什么这么改"。这比在黑箱系统中反复试错然后说"我也不知道为什么调好了"要靠谱得多。
机制五:会话自动管理与记忆自迭代——让 Agent "越用越聪明"
这是 OpenViking 最具前瞻性的设计之一。传统方案中,Agent 的记忆基本上就是对用户对话历史的被动记录。而 OpenViking 在此基础上做了两件更高级的事情。
第一件事是会话内容的智能压缩。 在长期运行的 Agent 会话中,大量的对话内容、工具调用记录、资源引用信息会不断累积。OpenViking 内置了自动压缩机制,能够在保留核心信息的前提下,大幅减少冗余内容,避免上下文窗口被无关信息占满。
第二件事是长期记忆的自动沉淀。 OpenViking 内置了记忆自迭代闭环。在每次会话结束时,开发者可以通过调用 session.commit() 来主动触发记忆提取。系统会异步分析本次任务的执行结果和用户反馈,自动将有价值的信息更新到 User 和 Agent 的 /memory 目录下。
这个过程涵盖两个维度。一方面是用户偏好记忆的更新:比如用户在多次对话中表现出偏好简洁回答的风格,系统会自动将这个偏好沉淀为记忆,使后续的回答更贴合用户习惯。另一方面是任务经验记忆的沉淀:Agent 在执行任务中积累的操作技巧、工具使用经验、问题解决策略等,都会被自动提取并存储。下次遇到类似场景时,Agent 可以直接调取这些"实战经验"来辅助决策。
这就像一个人在工作中不断积累经验一样——新手做事需要查手册、问同事,而老手凭借丰富的经验就能快速判断和行动。OpenViking 让 Agent 也具备了类似的"经验积累"能力。
从技术实现的角度来看,这个记忆自迭代机制的精妙之处在于它是异步且非侵入式的。session.commit() 调用后,记忆提取在后台异步进行,不会阻塞 Agent 的正常运行。而且提取出的记忆以标准的文件形式存储在虚拟文件系统中,与其他上下文(资源、技能等)享有完全一致的管理方式。这意味着你可以像管理其他文件一样,查看、编辑、甚至删除这些自动生成的记忆——如果 Agent 学到了"错误的经验",你完全可以手动纠正。
另外值得一提的是,这个机制区分了"用户记忆"和"Agent 记忆"两个维度。用户记忆侧重于理解"这个用户是什么样的人、有什么偏好",属于个性化服务的基础。而 Agent 记忆侧重于积累"我在执行任务时应该怎么做才更高效",属于能力进化的基础。这两个维度的分离,使得系统在多用户场景下也能良好运作——不同用户可以有各自的偏好记忆,而 Agent 的任务经验则可以跨用户共享。
项目架构与代码结构
了解了核心机制后,我们来看看 OpenViking 的整体架构。以下是项目的主要目录结构(莫潇羽@无忆研习社根据 GitHub 仓库整理):
OpenViking/
├── openviking/ # 核心源代码目录
│ ├── core/ # 核心模块:客户端、引擎、文件系统等
│ ├── models/ # 模型集成:VLM 和 Embedding 模型的封装
│ ├── parse/ # 资源解析:文件解析、资源检测、OVPack 格式处理
│ ├── retrieve/ # 检索模块:语义检索、目录递归检索等
│ ├── storage/ # 存储层:向量数据库、文件系统队列、观察者模式
│ ├── session/ # 会话管理:对话历史、记忆提取等
│ ├── message/ # 消息处理:消息格式化、转换等
│ ├── prompts/ # 提示词模板:各类任务的提示词模板
│ ├── utils/ # 工具函数:配置管理、辅助工具等
│ └── bin/ # 命令行工具
├── docs/ # 项目文档
│ ├── zh/ # 中文文档
│ ├── en/ # 英文文档
│ └── images/ # 文档图片资源
├── examples/ # 使用示例
├── tests/ # 测试用例
├── src/ # C++ 扩展模块(高性能索引和存储)
├── pyproject.toml # Python 项目配置文件
├── setup.py # 安装脚本
├── LICENSE # 开源协议
├── CONTRIBUTING.md # 贡献指南
├── AGENT.md # Agent 开发指南
└── README.md # 项目说明文档
从这个结构可以看出几个要点。core/ 目录是整个系统的"骨架",包含了客户端接口、核心引擎和虚拟文件系统的实现。retrieve/ 目录实现了前面讲到的目录递归检索策略。session/ 目录负责会话管理和记忆提取。models/ 目录则通过 Provider Registry 机制实现了对多种模型服务商的统一访问。值得注意的是,src/ 目录包含了 C++ 编写的高性能索引和存储扩展模块,这说明 OpenViking 在性能方面也下了很大功夫。
环境准备与安装指南
接下来进入实操环节。莫潇羽@无忆研习社会尽可能详细地讲解每一步,确保即使是刚接触 Agent 开发的朋友也能顺利跑通。
环境要求
在开始安装之前,请确认你的开发环境满足以下条件:
- 操作系统: macOS 或 Linux(推荐)。Windows 用户可以通过 WSL2 来使用。
- Python 版本: 3.10 或更高版本。OpenViking 也支持 Python 3.13。
- 网络连接: 需要稳定的网络连接,用于下载依赖包和访问模型服务的 API。
- 模型服务 API Key: 至少需要一个 VLM(视觉语言模型)和一个 Embedding(向量嵌入模型)服务的 API Key。
第一步:安装 OpenViking
OpenViking 提供了两种安装方式。对于大多数开发者来说,推荐使用 Python 包安装,简单直接:
pip install openviking
如果你更习惯 Rust 工具链,或者想体验命令行操作方式,也可以安装 Rust CLI 版本:
curl -fsSL https://raw.githubusercontent.com/volcengine/OpenViking/main/crates/ov_cli/install.sh | bash
安装完成后,可以通过以下命令验证安装是否成功:
python -c "import openviking; print('OpenViking 安装成功!')"
第二步:获取模型服务的 API Key
OpenViking 需要两种模型能力来工作:
- VLM 模型: 负责对图像和文本内容进行理解和摘要生成。这是 L0/L1 分层处理的核心依赖。
- Embedding 模型: 负责将文本转化为向量表示,用于语义检索。
OpenViking 设计了一个非常灵活的 Provider Registry(服务商注册表)机制,统一管理不同模型服务商的访问。系统会根据你配置的模型名称自动检测对应的服务商,切换起来非常方便。
目前 OpenViking 支持的主要模型服务商包括:
|
服务商 |
模型关键词 |
获取 API Key 的位置 |
|
火山引擎 |
doubao |
火山引擎控制台 |
|
OpenAI |
gpt |
OpenAI Platform |
|
Anthropic |
claude |
Anthropic Console |
|
DeepSeek |
deepseek |
DeepSeek Platform |
|
|
gemini |
Google AI Studio |
|
月之暗面 |
kimi |
Moonshot Platform |
|
智谱AI |
glm |
BigModel |
|
通义千问 |
qwen |
DashScope Console |
|
MiniMax |
minimax |
MiniMax Platform |
|
OpenRouter |
任意模型 |
OpenRouter |
|
vLLM |
本地部署模型 |
无需 API Key |
你可以根据自己的实际情况选择合适的服务商。如果想在本地运行,选择 vLLM 方案即可。
第三步:创建配置文件
OpenViking 通过一个 JSON 格式的配置文件来管理模型服务的连接信息。配置文件的默认路径是 ~/.openviking/ov.conf。
首先创建配置目录:
mkdir -p ~/.openviking
然后创建配置文件。下面是配置文件的基本结构模板:
{
"embedding": {
"dense": {
"api_base" : "<API服务端点地址>",
"api_key" : "<你的API密钥>",
"provider" : "<服务商类型>",
"dimension": 1024,
"model" : "<Embedding模型名称>"
}
},
"vlm": {
"api_base" : "<API服务端点地址>",
"api_key" : "<你的API密钥>",
"provider" : "<服务商类型>",
"model" : "<VLM模型名称>"
}
}
接下来,莫潇羽给出几种常见的配置示例,你可以根据自己使用的服务商直接复制修改。
示例一:使用火山引擎(豆包模型)
这是官方推荐的配置方案。火山引擎的豆包模型在成本和性能方面表现出色:
{
"embedding": {
"dense": {
"api_base" : "https://ark.cn-beijing.volces.com/api/v3",
"api_key" : "你的火山引擎API-Key",
"provider" : "volcengine",
"dimension": 1024,
"model" : "doubao-embedding-vision-250615"
}
},
"vlm": {
"api_base" : "https://ark.cn-beijing.volces.com/api/v3",
"api_key" : "你的火山引擎API-Key",
"provider" : "volcengine",
"model" : "doubao-seed-1-8-251228"
}
}
示例二:使用 OpenAI 模型
如果你更熟悉 OpenAI 的生态,配置如下:
{
"embedding": {
"dense": {
"api_base" : "https://api.openai.com/v1",
"api_key" : "你的OpenAI-API-Key",
"provider" : "openai",
"dimension": 3072,
"model" : "text-embedding-3-large"
}
},
"vlm": {
"api_base" : "https://api.openai.com/v1",
"api_key" : "你的OpenAI-API-Key",
"provider" : "openai",
"model" : "gpt-4o"
}
}
示例三:使用 vLLM 本地部署
如果你有自己的 GPU 服务器,不想依赖外部 API,可以通过 vLLM 在本地部署模型:
首先启动 vLLM 服务:
vllm serve meta-llama/Llama-3.1-8B-Instruct --port 8000
然后配置 OpenViking 指向本地服务:
{
"vlm": {
"provider": "vllm",
"model": "meta-llama/Llama-3.1-8B-Instruct",
"api_base": "http://localhost:8000/v1"
}
}
需要注意的是,使用本地部署方案时,你还需要单独配置 Embedding 模型服务。可以使用支持 OpenAI API 格式的本地 Embedding 服务,或者搭配一个云端 Embedding 服务使用。
配置文件创建完成后,可以通过以下 Python 代码快速验证配置是否正确:
import openviking as ov
client = ov.SyncOpenViking(path="./test_data")
try:
client.initialize()
print("配置验证成功!OpenViking 已准备就绪。")
client.close()
except Exception as e:
print(f"配置有误,请检查:{e}")
实战演练:从零开始使用 OpenViking
配置完成后,我们来通过一个完整的示例,走通 OpenViking 的核心操作流程。莫潇羽@无忆研习社把这个过程拆解成几个关键步骤来讲解。
第一步:初始化客户端并添加资源
创建一个名为 demo.py 的脚本:
import openviking as ov
# 初始化 OpenViking 客户端
# path 参数指定本地数据存储目录
client = ov.SyncOpenViking(path="./my_agent_data")
try:
# 初始化客户端(加载配置、建立连接)
client.initialize()
print("OpenViking 客户端初始化成功!")
# 添加资源——支持 URL、本地文件或目录
# 这里以 OpenViking 项目自身的 README 为例
add_result = client.add_resource(
path="https://raw.githubusercontent.com/volcengine/O