OpenViking 上下文数据库复习笔记
火山引擎开源的 AI Agent 上下文数据库:viking:// 文件系统范式、L0/L1/L2 分层加载、目录递归检索、三种上下文类型、会话与记忆提炼,以及 Go 客户端/Agent 的实现八股。
目录 · 32 节
- 1. 一句话定义 + 四个痛点
- 1.1 公开 benchmark:LoCoMo10 数据(面经常考数字)
- 1.2 工程形态:不是单语言项目 + 一句金句
- 2. 核心概念
- 2.1 viking:// URI:一切上下文都是路径
- 2.2 L0/L1/L2:分层加载
- 2.3 目录递归检索:先锁目录,再逐层下钻
- 2.4 三种上下文类型:Resource / Memory / Skill
- 2.5 Session 与记忆提炼
- 3. 存储与检索架构
- 3.1 AGFS + Vector Index 双存储
- 3.2 find vs search
- 3.3 Rerank
- 3.4 事务模型:路径锁与崩溃恢复
- 4. 多租户与鉴权
- 5. Go 集成与源码八股
- 5.1 统一 do 方法(极简 stdlib 客户端)
- 5.2 业务错误码
- 5.3 超时与优雅退出(cmd/agent/main.go)
- 5.4 分层加载的实现
- 5.5 最小闭环
- 5.6 生产接入模式(官方 Go SDK)
- 6. 经典相关八股
- 6.1 Embedding:dense / sparse / hybrid
- 6.2 两阶段检索:召回 + Rerank
- 6.3 Token 成本优化
- 6.4 记忆系统与去重
- 6.5 MCP 集成
- 6.6 自进化闭环与周边生态
- 7. 常见坑 Top5
- 8. 速记版:背这些就够
- 参考资料
OpenViking 上下文数据库复习笔记
这份笔记围绕 OpenViking(火山引擎开源的 AI Agent 上下文数据库)展开:它是什么、解决什么问题、核心概念怎么串,以及用 Go 接入时的实现细节。内容基于官方文档(docs.openviking.ai,逐页核对)、GitHub 仓库,以及本仓库 viking/client.go、viking/extra.go、cmd/agent/main.go 的源码,并对照了生产侧 final_sys_agent 里基于官方 Go SDK 的接入实现。
主要模块:
- 一句话定义、四个痛点、与传统向量库/RAG 的本质区别
- 核心概念:
viking://URI、L0/L1/L2 分层、目录递归检索、三种上下文类型、会话与记忆提炼 - 存储与检索架构:AGFS + Vector Index 双存储、find vs search、rerank、事务模型与路径锁
- 多租户与鉴权:account/user/peer、三种 auth 模式、两类 key
- Go 集成与源码八股:统一
do方法、错误处理、超时与优雅退出、分层加载、生产接入模式 - 经典相关八股:embedding 与 rerank、token 成本优化、记忆系统、MCP
- 常见坑与速记
1. 一句话定义 + 四个痛点
一句话:OpenViking 是火山引擎开源的 AI Agent 上下文数据库(Context Database)——把记忆(memory)、资源(resource)、技能(skill)统一组织成 viking:// 虚拟文件系统,让 Agent 像操作文件一样管理上下文,而不是对着一个黑盒向量库发查询。
传统 RAG 在 Agent 场景下的四个痛点,以及 OpenViking 的对应:
| 痛点 | 传统 RAG | OpenViking 的应对 |
|---|---|---|
| 上下文碎片化 | 向量切片没结构,召回结果丢了周围上下文 | 文件系统范式:一切上下文都有 viking:// URI,用 ls/tree/find/read 确定性操作 |
| Token 成本失控 | 要么全量塞 prompt,要么手动截断 | L0/L1/L2 分层加载:写入时自动生成摘要/概览/原文,按需加载 |
| 记忆不进化 | 对话结束就结束,偏好与经验不沉淀 | 会话变记忆:commit 后异步提炼用户偏好与 Agent 经验到长期记忆 |
| 检索黑盒 | 结果错了不知道哪条路径召回 | 目录递归检索:先锁高分目录再逐层下钻,结果自带上下文,轨迹可回看 |
本质区别(对照官方 FAQ 对比表):存储模型(扁平向量存储 vs 层级化文件系统 AGFS)、检索方式(单一向量相似度 vs 目录递归检索 + 意图分析 + Rerank)、输出形式(原始分块 vs L0/L1/L2 结构化上下文)、记忆能力(无 vs 内置多种记忆类型自动提取持续迭代)、可观测性(黑箱 vs 检索轨迹可追溯)、上下文类型(仅文档 vs Resource + Memory + Skill)。
1.1 公开 benchmark:LoCoMo10 数据(面经常考数字)
OpenViking 用 ACL 2024 的 LoCoMo10 长期对话记忆基准(Snap Research,1,540 条长对话)做对比,挂在 OpenClaw 上测:
| 配置 | 任务完成率 | 输入 Token 成本 |
|---|---|---|
| OpenClaw 原生 memory(基线) | 35.65% | 24.6M |
| OpenClaw + LanceDB(关原生) | 44.55% | 51.6M |
| OpenClaw + OpenViking(关原生) | 52.08% | 4.3M |
| OpenClaw + OpenViking(开原生) | 51.23% | 2.1M |
结论:完成率相对提升约 4 成(开原生口径约 +43%),输入 token 降约 8–9 成(关原生 −83%、开原生 −91%)。各文章宣传口径略有差异(43% / 49%),以 README 表格为准。
面试必追问「为什么完成率也跟着涨」:答案不在召回率本身,而在 Agent 拿到的是结构化、带目录上下文的检索结果而非孤立碎片,生成质量更高;同时记忆回写让后续任务少做无效检索。注意 LanceDB 那一行——token 反而从 24.6M 涨到 51.6M,说明「换个向量库」解决不了上下文问题,这正是 OpenViking 换抽象的原因。
1.2 工程形态:不是单语言项目 + 一句金句
仓库不是单语言 Python 包:openviking(核心 Python 包)+ crates/ov_cli(Rust CLI)+ AGFS(Go 1.22+ 构建)+ src/native extension(性能热点)+ bot(Agent 接入层)。分工务实:Python 管生态与开发效率,Rust 做 CLI,Go 做系统能力,native 承接性能敏感部分。
CLI 入门四件套:
pip install openviking --upgrade
openviking-server # REST + /mcp 同进程启动
ov add-resource <url|path> --wait # 加资源并等待语义处理完成
ov tree viking://resources/xxx -L 2 # 浏览目录树
ov chat # 内置 VikingBot 直接对话
面试金句:「上下文管理是数据库问题,不是 prompt engineering 问题。」 一句话说清 OpenViking 的定位和它跟 RAG 的关系,比背一堆接口名更有说服力。
2. 核心概念
2.1 viking:// URI:一切上下文都是路径
格式 viking://{scope}/{path}。顶层布局:
viking://
├── resources/ # 共享知识库:文档、代码、网页(客观知识)
├── user/{user_id}/
│ ├── profile.md # 用户画像
│ ├── memories/ # 长期记忆:preferences/entities/events/...
│ ├── resources/ # 用户私有资源
│ ├── skills/ # 用户技能
│ ├── peers/{peer_id}/ # 关于某交互对象的记忆/资源
│ └── sessions/{session_id}/ # 会话与历史归档
└── agent/ # account 全局共享:skills/、endpoints/、tools/、payments/
作用域(scope)规则:
| 作用域 | 放什么 | 生命周期 | 可见性 |
|---|---|---|---|
resources | 客观知识(文档、代码、规范) | 长期 | account 全局 |
user | 用户级数据(记忆、私有资源、技能、会话) | 长期或会话期 | 当前用户 |
agent | Agent 能力与配置(技能、端点、工具、支付) | 长期 | account 全局 |
temp/queue/upload | 内部临时 | 临时 | 内部,公开 API 不可访问 |
三条必须记住的规则:
viking://user/...是短路径:服务端按当前请求身份展开为viking://user/{user_id}/...;旧的viking://session/{id}只是当前用户 session 路径的向后兼容别名,不是独立存储根。resources作用域只放知识类数据;技能/工具/支付配置属于agent作用域。POST /resources的target只能在viking://resources/下(0.1.18 起),写用户内容走 Session API 或user作用域 URI。
2.2 L0/L1/L2:分层加载
每个目录/文件写入时自动生成,按需加载省 token:
| 层级 | 特殊文件 | 内容 | 规模 | 用途 |
|---|---|---|---|---|
| L0 | .abstract.md | 一句话摘要 | ~100 token | 向量召回、快速过滤相关性 |
| L1 | .overview.md | 结构与要点、导航 | ~1k–2k token | Rerank、内容导航、任务规划 |
| L2 | 原文 | 完整内容 | 无限制 | 确认需要细节时才读 |
生成机制:资源添加时 Parser 解析 → SemanticQueue 自底向上(叶子 → 父目录 → 根)逐目录生成 L0/L1 → 写入向量索引;session 归档时同样为归档段生成 L0/L1。子目录的 L0 会聚合进父目录的 L1,形成层级导航。目录自身也带 .abstract/.overview,所以在读到任何原文之前就能判断相关性。多模态内容(图片/视频/音频)的 L0/L1 也是文本描述。
一句话记忆:L0 判断要不要,L1 判断读哪个,L2 才花钱读全文。 典型顺序:先 L0 批量粗筛 → 对候选读 L1 看结构 → 真正要引用原文时才 read L2,比一次性塞全文通常省 50%+ token。
2.3 目录递归检索:先锁目录,再逐层下钻
平铺向量检索只返回「语义最像的碎片」,碎片一旦离开所在目录就丢了上下文。目录递归检索分五步:
- 意图分析:拆解查询生成多个检索条件(只有
search()才用 LLM 做这步,生成 0–5 个 TypedQuery;find()不做,直接向量检索,延迟更低); - 初始定位:全局向量检索定位初始切片所在的高分目录;
- 精细探索:在目录内二次检索,更新候选集合;
- 递归下探:子目录逐层递归(优先队列驱动),直到 top-k 连续 3 轮不变收敛;
- 结果汇总:返回最相关上下文。
分数传播:final_score = α × 向量相似度 + (1 − α) × 父目录分。官方 FAQ 常用 α=0.5 举例(0.5/0.5 加权);实际由 retrieval.score_propagation_alpha 配置,默认 1.0(只取子项自身分数、忽略父目录分)。核心思想:高分目录下的内容天然加权,这正是「结果自带上下文」的来源。每次检索保留目录浏览轨迹,结果不对时可以回看走哪条路径召回的。
2.4 三种上下文类型:Resource / Memory / Skill
| 类型 | 用途 | 生命周期 | 谁来写 |
|---|---|---|---|
| Resource | 知识与规则(API 文档、代码仓库、论文、FAQ) | 长期、相对静态 | 用户添加 |
| Memory | Agent 的认知(偏好、实体、事件、经验) | 长期、动态更新 | Agent 记录 |
| Skill | 可调用的能力定义(.abstract.md L0 + SKILL.md L1 + scripts L2) | 长期、静态 | 用户或系统添加 |
内置记忆类型(按用途分组):用户/环境理解(profile、preferences、entities、events),助手身份/连续性(identity、soul),任务执行/学习(cases、trajectories、experiences、tools、skills)。应用可扩展或调整记忆类型。一次 find() 同时返回 memories/resources/skills 三类结果。
2.5 Session 与记忆提炼
生命周期 create → add messages → commit:
POST /sessions 创建会话,拿 session_id
POST /sessions/{id}/messages 逐条追加 user/assistant 消息(可带结构化 parts)
POST /sessions/{id}/commit 归档 + 触发异步记忆提炼
│
├─ Phase 1(同步):写 messages.jsonl,清空当前消息,返回 task_id
└─ Phase 2(异步后台):生成归档段 .abstract/.overview → 提炼长期记忆
→ 写 memory_diff.json(变更审计)→ 写 .done
记忆提炼内部流:Messages → LLM 抽取候选记忆 → 向量预筛找相似记忆 → LLM 去重决策(skip/create/merge/delete)→ 写入 AGFS → 向量化。memory_diff.json 每次 commit 都写,记录 adds/updates/deletes,支持审计与回滚。
结构化消息:messages 支持 parts 数组(text/context 引用/tool 调用轨迹),让记忆提炼能看到 Agent 实际用过的上下文与工具——Go 端封装为 Session.AddPartsMessage,Part 结构见 viking/extra.go。
3. 存储与检索架构
3.1 AGFS + Vector Index 双存储
VikingFS (URI 抽象:URI 映射、层级访问、关系管理)
├── Vector Index(语义检索:URI、向量、元数据,不含文件内容)
└── AGFS(内容存储:L0/L1/L2 全文、多媒体、关系)
设计收益:职责清晰;索引不含内容省内存;单一数据源(一切内容从 AGFS 读,向量索引只存引用);可独立扩容。核心原则:FS 是 source of truth,VectorDB 是 derived index——索引丢了能重建,源数据丢了不能。所以设计哲学是 「宁漏检,不误检」(Better to miss a search result than return a bad one)。AGFS 已用 Rust 重写为 RAGFS。
3.2 find vs search
| 特性 | find() | search() |
|---|---|---|
| 会话上下文 | 不需要 | 需要 |
| 意图分析 | 无(直接向量检索) | LLM 分析,生成 0–5 个 TypedQuery |
| 延迟 | 低 | 高 |
| 适用 | 简单查询、明确目标 | 复杂任务、多上下文类型 |
一句话:明确找什么用 find();复杂任务需要拆意图、跨 memory/resource/skill 用 search()。
3.3 Rerank
两阶段检索:向量召回(L0)→ Rerank 精排(L1)。rerank 需要配置 rerank 模型(如 doubao-seed-rerank),在全局候选评估与每层子目录评估两处使用;未配置或失败时回退到向量分数。
3.4 事务模型:路径锁与崩溃恢复
写独占通过 路径锁(PathLock)保证:
- 两种锁:
EXACT(单路径:文件写、单文件删除、sidecar 回写)和TREE(子树:目录删除、资源生命周期、子目录保护); - fencing token(
{handle_id}:{time_ns}:{lock_type}写入锁文件)防止 TOCTOU 竞态; - 过期锁自动清理(默认
lock_expire1800s / 30min;LockManager 每 60s 扫描); rm反向删除:先删 VectorDB 索引再删文件(索引消失即不可见,FS 删除失败重试安全);mv先拷贝再更新索引再删源。
session commit 之所以两阶段,是因为 LLM 提炼延迟 5s–60s+ 不能占着锁:Phase 1 归档(无锁)→ Phase 2 记忆提取走持久化 session_commit 队列(SQLite 持久化,崩溃后重启继续跑,幂等)。
4. 多租户与鉴权
身份边界是 account(外层租户:团队/客户)与 user(账号内用户),peer_id 只是 user 内部的内容作用域(交互对象),不改变身份。
三种角色:ROOT(全局:建/删 account、跨租户、用户管理)、ADMIN(单 account:管用户、重置 user key)、USER(单 account:自己的 user/peer/session 数据 + 共享 resources)。
三种 auth 模式(server.auth_mode):
| 模式 | 身份来源 | 适用 |
|---|---|---|
api_key | root key / user key | 标准部署(配了 root_api_key 自动进入) |
trusted | 上游网关注入 X-OpenViking-Account/X-OpenViking-User 头 | 受信网关之后 |
dev | 无鉴权,一律 ROOT,身份 default/default | 未配 key 时自动进入,只允许回环地址 |
两类 key:root_key 只管 Admin API 和管理操作,不能访问租户数据接口(api_key 模式下会 PERMISSION_DENIED);日常数据接口(find/ls/sessions)要用 Admin API 签发的 user_key。/health、/ready 从不要求鉴权。请求头 X-API-Key: <key> 或 Authorization: Bearer <key>。
一个常见误解:root key 不是业务访问 key;没有 root_api_key 不等于单租户生产(那是 dev 模式)。
5. Go 集成与源码八股
5.1 统一 do 方法(极简 stdlib 客户端)
viking/client.go 的核心是一个统一方法,处理鉴权、编码、统一响应、业务错误:
func (c *Client) do(ctx context.Context, method, path string, query url.Values, body any, out any) error
几个值得背的点:
- 鉴权:
apiKey != ""时才带X-API-Key头(服务端未配 key 时不带); - 请求编码:
json.Marshal(body)→bytes.NewReader→http.NewRequestWithContext(context 贯穿,超时/取消可传导); - 响应大小上限:
maxResponseBytes = 32 << 20(32MB),io.LimitReader读,超限直接报错——防止异常大包耗尽内存; - 统一响应解析:
{"status","result","error","time"},status != "ok"时转成*Error{Code, Message}; - 非 2xx 且非 JSON:返回带状态码的明确错误,而不是糊一个 decode 错。
5.2 业务错误码
type Error struct { Code, Message string }
func (e *Error) Error() string { return fmt.Sprintf("openviking %s: %s", e.Code, e.Message) }
调用方用 errors.As(err, &ve) 取出 *viking.Error,读 ve.Code/ve.Message。常见错误码:UNAUTHENTICATED(401)、INVALID_ARGUMENT/INVALID_URI(400)、NOT_FOUND(404)、ALREADY_EXISTS(409)、SESSION_EXPIRED(410)、DEADLINE_EXCEEDED(504)、UNAVAILABLE(503)。
5.3 超时与优雅退出(cmd/agent/main.go)
- 启动即校验:
checkLLMEnv检查LLM_BASE_URL/LLM_API_KEY/LLM_MODEL,缺失直接os.Exit(1),不浪费请求; - 分层超时:客户端
http.Client{Timeout: 120s}(整体),每轮召回与 LLM 调用各有context.WithTimeout(..., 60s); - 优雅退出:
signal.NotifyContext(ctx, os.Interrupt, syscall.SIGTERM)捕获 Ctrl+C,退出循环后走defer里的session.Commit(独立 30s 超时),保证记忆提炼照常触发; - 召回降级:
buildContext失败不丢这一轮,stderr 警告后降级为无上下文继续对话。
5.4 分层加载的实现
buildContext 里 find 命中的 abstract 就是 L0 摘要,命中列表本身不额外花 token;命中没摘要就降级读 L1 概览:
for _, h := range hits {
if h.Abstract != "" { /* 直接用 L0 摘要 */ } else { /* 降级读 Overview(L1) */ }
}
5.5 最小闭环
recall → generate → record → commit:Find 召回 → 拼 system prompt 调 LLM → AddMessage 写回会话 + 本地历史 → 退出 defer Commit,服务端异步提炼记忆。
5.6 生产接入模式(官方 Go SDK)
生产侧(final_sys_agent/internal/knowledge/openviking)不自己拼 HTTP,而是包官方 SDK github.com/volcengine/OpenViking/sdk/go,做 provider-neutral 的 adapter。几个值得背的工程判断:
- find vs search 按需选:无痕检索
Retrieve走Find();带 incident session 的追踪检索RetrieveWithTrace走Search(),保留query_plan/query_results。检索与追踪只在 session telemetry 上有别,其余契约一致。 - L2 水合有降级:
hitsFromResources优先Read()全文,但某个已索引资源Read报NOT_FOUND时,退回该命中自带的overview/abstract,不让一条资源失败拖垮整次查询。 - peer-scoped 记忆:
memory.Write只写到「确切的 peer/kind 子树」下,Search用context_type=memory只查该子树;写入时encodeMemoryDocument把 provenance 留在可读的 L2 内容里,再套 OpenViking 要求的元数据信封。 - archive-only 记忆策略:incident 场景
CommitIncident用archiveOnlyMemoryPolicy()——只归档不提炼,避免把一次性排障过程污染长期记忆。 - 异步任务轮询:
waitTask用 250ms ticker 轮询GetTask,直到completed/failed/未知状态/ctx 取消;add_resource导入仓库后拿到root_uri+task_id就靠它等语义处理完成。 - 写入后校验:
Write(wait=true)后校验返回的semantic_status/vector_status都complete,才认为入库完成。 - URI scope 钳制:
scopedURI用 segment-boundary 检查(viking://resources/redcart-secret不能匹配viking://resources/redcart的裸前缀),把用户输入钳回授权的资源子树,防止工具越权浏览。
6. 经典相关八股
6.1 Embedding:dense / sparse / hybrid
- dense:稠密向量,语义相似度(余弦),主流 embedding 模型(doubao、openai、jina、voyage 等),维度如 1024;
- sparse:稀疏向量(词项级),适合精确词匹配,只有
volcengine/vikingdb实现,无 BM25 回退; - hybrid:dense + sparse 混合,需要
storage.vectordb.sparse_weight > 0才生效。
索引策略默认 flat_hybrid、Distance: cosine、Quant: int8(量化省内存)。
6.2 两阶段检索:召回 + Rerank
向量召回(粗筛,L0)→ Rerank 精排(L1)。rerank 模型对候选重排,比纯向量相似度准;未配置/失败时回退向量分。这是「检索质量」与「成本」的经典平衡。
6.3 Token 成本优化
省 token 不是「因为有摘要」这么简单,而是四个机制叠加(面试答到这里比只答「分层加载」更有深度):
- 目录摘要先挡无关区域:很多无关内容在目录层就被刷掉,根本轮不到 L2;
- L0/L1 缩小平均读取粒度:不少问题到 L1 就够判断下一步,不需要原文;
- 递归下钻逐层缩小候选集合:候选越缩越小,rerank 更容易做准;
- 记忆回写减少重复检索:结果沉淀成 user/agent 记忆后,不用每次翻原始资源。
本质是上下文只装任务需要的层级:L0 批量筛 → L1 看结构 → L2 按需读全文,配合 session 归档压缩(近期保留、远期摘要),比「全量塞 prompt」或「手动截断」更省也更准。
6.4 记忆系统与去重
记忆提炼不是「存最新的」就完事,而是一个有状态的写路径:新记忆入库前先向量预筛语义相近的旧记忆,再由 LLM 判定 skip/create/merge/delete——和数据库事务的「读-改-写」一个思路。memory_diff.json 记录每次变更,支持审计与回滚。
6.5 MCP 集成
OpenViking 内置 /mcp 端点(和 REST 同进程同端口),任何 MCP 客户端(Claude Code、Cursor、ChatGPT、Manus 等)直接挂载,模型自主调 find/search/read/ls/grep/recall 等工具,省去手写召回逻辑。也提供各 Agent 运行时插件(Claude Code Memory Plugin、LangChain/LangGraph 集成等)。
6.6 自进化闭环与周边生态
- 自进化闭环:session 结束 → 抽取长期记忆 → 写
viking://user/memories+viking://agent/memories——用系统自动压缩取代手写MEMORY.md; - VikingBot:
openviking[bot]内置的 Agent 框架,开箱即用(openviking-server --with-bot→ov chat); - ME.md:人/Agent 可携带的上下文协议(一个文件描述「我是谁、我的栈、我的反模式」),
ov add-resource直接入库; - ACP:Agent 上下文交接协议;OpenViking 是 ME.md / ACP 底下的存储层。
这些是 OpenViking 生态里常被问到的名词,知道它们和 OpenViking 的关系即可,不必深挖。
7. 常见坑 Top5
INVALID_ARGUMENT: add_resource only supports resources scope:POST /resources的target只能在viking://resources/下;写用户内容走 Session API 或user作用域 URI。- 检索不到刚写入的资源:语义处理是异步的——写入传
"wait": true,或调POST /api/v1/system/wait补等(Go 端vc.Wait(ctx))。 - 401 UNAUTHENTICATED:服务端配了
root_api_key而请求没带X-API-Key;或者拿 root key 调数据接口(该用 user key)。 - dev 模式只监听回环:未配
root_api_key时只允许127.0.0.1,局域网访问会失败;要对外暴露就配server.auth_mode="api_key"+root_api_key。 - 响应字段与部署版本对不上:
find返回的results[].uri/score/abstract以官方 Python SDK 行为为准;版本不符用curl实测一次响应体再调结构体。
8. 速记版:背这些就够
- OpenViking = AI Agent 上下文数据库:记忆/资源/技能统一成
viking://文件系统。 - 最小闭环:
recall(find)→ generate(LLM)→ record(add message)→ commit(提炼记忆)。 - L0 摘要 ~100 token 判相关性,L1 概览 ~1k–2k token 看结构,L2 原文按需读。
find= 先锁高分目录、再逐层下钻的目录递归检索;final_score = α×向量相似度 + (1−α)×父目录分(默认 α=1.0)。- 三种上下文类型:Resource(客观知识)/ Memory(动态认知)/ Skill(能力定义)。
findvssearch:前者纯向量快,后者加意图分析(0–5 查询)+ 会话上下文。- 双存储:AGFS 存内容(truth),Vector Index 存引用(derived)——「宁漏检,不误检」。
commit两阶段:同步归档 + 异步记忆提炼(LLM 抽取 → 向量预筛 → LLM 去重)。- 多租户:account/user 身份边界 + peer 内容作用域;三种 auth(api_key/trusted/dev)、两类 key(root/user)。
- 语义处理异步:写入带
wait=true或调system/wait补等;服务端配了 key 就带X-API-Key。
参考资料
- volcengine/OpenViking - GitHub
- 官方文档 docs.openviking.ai(概念:viking-uri / context-types / context-layers / retrieval / session / multi-tenant;API Overview)
- 本仓库:
README.md(9 节教程)、viking/client.go、viking/extra.go、cmd/agent/main.go、docs/openviking-101.md(八股速查) - 生产接入:
final_sys_agent/internal/knowledge/openviking/(官方 Go SDK adapter) - 面经 / 深度分析参考:IceYao《从原理到落地:基于OpenViking构建多模态RAG方案》、mager.co《OpenViking: The Open-Source Context Database Your Agents Have Been Waiting For》、知乎《Openviking详解》、CSDN《字节开源OpenViking全解》、DeepWiki/Zread《LoCoMo Long-Term Memory Benchmark》
说明:文中「~100 token / ~1k–2k token」「0.5 × Embedding + 0.5 × 父目录分」「0.1.18 起」「0–5 个查询」「32MB / 120s / 60s」等数字均来自官方文档或本仓库源码/README 的既有表述;
score_propagation_alpha默认 1.0 以官方检索文档为准。具体版本行为若有出入,以官方文档和你部署版本的实测为准。