← 返回上一頁
Agent AI

OpenViking:用檔案系統取代 vector RAG 的 agent context DB

本頁目錄

寫過 long-running agent 的人都遇過同一個現象:對話一長,agent 開始忘事。早上交代它的 coding convention,下午就完全消失;上週做的需求討論,這週問完全當沒發生過。換 vector RAG 接 Mem0、Letta、Zep 之類的記憶層通常能止血,但用一段時間之後,新的問題冒出來——embedding 召回常常拿錯片段、context 越拉越大、token 帳單跟著一路長、要 debug 哪段記憶有問題還得撈 vector DB 看相似度分數。

2026-01 由 ByteDance 旗下 Volcano Engine(火山引擎)的 Viking 團隊開源了一個解法不太一樣的東西,叫 OpenViking,明確自稱是「給 AI agent 用的 context database」。它沒有用大家熟悉的向量 RAG 範式,而是把所有記憶、資源、技能組織成一個虛擬檔案系統——agent 可以用 lscdcatfind 之類它原本就熟的指令操作自己的長期記憶。到撰文的 2026-04-29 為止,這個 repo 已經累積 23K+ stars1.7K+ forks,主程式採 AGPL-3.0、CLI 跟範例 Apache 2.0。

更有意思的是它在 OpenAI 自家的 OpenClaw 框架上跑出來的數字:input token 從 2460 萬掉到 430 萬、降幅超過 80%;任務完成率從 35.65% 拉到 52.08%。這篇就把它怎麼設計、為什麼選 file-system 而非 vector、實際接到 Claude Desktop 的步驟、跟 Mem0 / Letta / Zep 的差異一次拆清楚。

OpenViking 架構:file-system paradigm 三層 memory + 自我演化 reflection

一、為什麼向量 RAG 對 agent 一直不太對

要先講清楚一件事:vector RAG 不是不好,它在「文件問答」場景(給定一篇 PDF,回答其中的問題)做得很好。問題是 agent 場景跟文件問答其實差很遠。

文件問答的記憶單位很乾淨——一塊一塊的 chunk,每塊 200~500 token,互相獨立,召回時拿前 K 個最相似的丟進 context 就好。Agent 的記憶單位則是高度結構化的:

  • 使用者偏好:「我的時區是 UTC+8」「我習慣用 pnpm 不用 npm」
  • 過往會話事件:「上週三我們決定把 service A 拆成兩個 microservice」
  • 技能(skills):「呼叫公司內部 API 時要先打 auth endpoint 拿 token」
  • 資源(resources):「/etc/nginx/nginx.conf 的當前內容」「docker-compose.yml 的服務清單」

這些東西用 chunk 切開來丟向量庫之後會發生什麼?答案是 retrieval 召回經常拿錯——你想問「我的時區是什麼」結果它召回了一堆「上次討論時區的會議記錄」,因為兩者 embedding 距離差不多。也常召回語義相關但邏輯不適用的片段,比如問 nginx config 它撈了 apache config 的範例給你。

這個問題的本質是:embedding 表達的是「語義相近」,但 agent 真正需要的是「結構性對應」——使用者偏好就該去 user/preferences 找、nginx config 就該去 resources/configs/nginx.conf 看,不是丟進向量空間搜近鄰。

OpenViking 的判斷是:既然 agent 本來就是 LLM,LLM 從訓練資料裡看過幾百萬次 lscdcatgrep 的操作模式,那麼讓它用這套介面操作自己的記憶,對 agent 而言反而比向量召回更直觀。這個切入點蠻反直覺但實際很有道理。

1.1 file-system paradigm 怎麼長

OpenViking 把所有 context 組織成 viking:// 開頭的虛擬路徑,三個 root 目錄:

viking://resources/   # 原始資料:檔案內容、文檔、設定檔、API schema
viking://user/        # 使用者層級:profile、preferences、entities、events
viking://agent/       # agent 層級:skills、cases、patterns、operating procedures

Agent 想拿東西的時候,會用很自然的指令操作:

ov ls viking://user/preferences
ov cat viking://user/preferences/timezone
ov find viking://resources --pattern "nginx.conf"
ov grep "rate_limit" viking://resources/configs

這跟 agent 在解一個普通 coding 任務時的行為完全一樣——它原本就會 lscatgrep 你的 codebase,只是現在這些指令也能用在自己的長期記憶上。對 LLM 而言,介面越一致,工具呼叫的錯誤率越低。

二、L0 / L1 / L2 三層 progressive loading

光是把資料組成檔案系統還不夠,因為一份 context 可能很大——一個會議記錄 5000 token、一個 nginx.conf 8000 token,全載進去 token 馬上爆。OpenViking 的第二個關鍵設計是把每一個檔案切成三層:

層級 內容 Token 量 用途
L0 一句話摘要 ~100 快速 scan 目錄、決定要不要看
L1 核心摘要 ~2000 規劃決策時讀
L2 完整原文 on-demand 真的需要細節時才載

Agent 走訪目錄時預設只看 L0;判斷某個檔案值得深入再讀 L1;只有 L1 還不夠才會展開 L2。這套機制叫 progressive loading(漸進式載入),有點像 IDE 的 lazy code lens——能省大量 token,又不會讓 agent 當下漏資訊。

實際數字(出自 OpenViking 官方在 OpenClaw 上的測試):
- 純 baseline:2460 萬 input token
- 接 OpenViking(progressive loading 開):430 萬 token,降 82%
- 加上 memory optimization:210 萬 token,降 91%
- 任務完成率從 35.65% 提升到 52.08%,跟 LanceDB 的 vector RAG 比則高出 17%

降 token 這件事大家都知道很重要,但有人會問:那任務完成率為什麼也跟著漲?OpenViking 給的解釋是——以前 agent 拿到一坨 chunk 進 context window,相關不相關的混在一起、互相干擾推理;現在每一層 context 都是結構化載入的,agent 能「看清楚」自己手上有什麼,自然推理品質就上來。這個跟去年看到的 context engineering 研究結論一致:context 不是越多越好,是「乾淨且分層」越好。

2.1 retrieval 怎麼做 — Directory Recursive Retrieval

OpenViking 的檢索流程跟 vector RAG 完全不同,它叫 Directory Recursive Retrieval Strategy

  1. 意圖分析:LLM 先讀使用者請求,判斷大致要找什麼類型(preferences? events? configs?)
  2. 目錄定位:到對應的 root 目錄底下做一次 vector 排序——但是排的是目錄本身的描述,不是底下的 chunk
  3. 遞迴下探:選分數最高的目錄,重複步驟 2,直到走到具體檔案
  4. 逐層展開:先讀 L0,必要時 L1,最後才 L2

這樣的好處是每一層只比較少數候選(一個目錄底下通常不超過幾十個子節點),向量比對的準確率比平鋪幾萬個 chunk 高很多。代價是檢索路徑變長——一次 query 可能跑 3~5 次 LLM call 來決定下一步走哪。但因為每次 call 的 context 很小,整體 token 還是省。

三、實際接 Claude Desktop 的最小步驟

OpenViking 內建了 MCP server adapter,可以直接掛上 Claude Desktop 或任何支援 MCP 的客戶端。下面是一個從 0 到能用的最短路徑(macOS 為例):

3.1 環境前置

  • Python 3.10+
  • Rust toolchain(CLI 部分用 Rust 寫的)
  • C++ compiler(GCC 9+ 或 Clang 11+
  • 一個 embedding model(OpenAI、火山引擎 Doubao、本地 Ollama 都行)
  • 一個 VLM 視覺語言模型(如果要處理圖片資料)

3.2 安裝

# Python 套件
pip install openviking --upgrade

# Rust CLI(optional,但強烈建議)
curl -fsSL https://raw.githubusercontent.com/volcengine/OpenViking/main/crates/ov_cli/install.sh | bash

# 互動式設定
openviking-server init

# 健康檢查
openviking-server doctor

init 會引導你填 embedding provider 跟 VLM provider。如果只是要本機跑、不想付費,可以兩個都填 Ollama,模型用 nomic-embed-textllama3.2-vision,效果是堪用的(不到雲端 API 那麼準,但 demo 夠)。

3.3 寫一個最小範例

from openviking import OpenViking

client = OpenViking(path="./my-agent-data")

# 寫入一筆 user preference
client.write(
    "viking://user/preferences/timezone",
    content="UTC+8 Asia/Taipei"
)

# 寫入一筆 agent skill
client.write(
    "viking://agent/skills/deploy-staging",
    content="先打 /api/auth 拿 token,再 POST /api/deploy 帶 token,最後 GET /api/status 確認",
)

# 開一個 session、自動萃取記憶
session = client.session()
session.add(role="user", content="今天下午幫我把 service A deploy 到 staging")
session.add(role="assistant", content="好的,我會用既定流程部署,預估 5 分鐘完成")
session.commit()

# 之後 agent 在新對話裡就能 find 到
results = client.find("staging deployment")

session.commit() 是關鍵——它會觸發背景的 memory extraction,自動從這次對話裡萃出 6 類記憶(profile / preferences / entities / events / cases / patterns),寫入對應的 viking 路徑。下次 agent 開新 session,就能透過 retrieval 找回來。

3.4 接到 Claude Desktop

在 Claude Desktop 的 ~/Library/Application Support/Claude/claude_desktop_config.json 加:

{
  "mcpServers": {
    "openviking": {
      "command": "openviking-server",
      "args": ["mcp", "--data-path", "/Users/me/openviking-data"]
    }
  }
}

重啟 Claude Desktop 後,工具列表會多出 viking_findviking_catviking_write 之類的 tool,Claude 就能在對話過程中自己讀寫長期記憶了。

四、跟 Mem0 / Letta / Zep 的差異

寫到這裡會有人問:那它跟 Mem0、Letta、Zep 這些既有的 agent memory 框架到底差在哪?把核心抽象拉開來比:

框架 儲存範式 檢索方式 結構性
Mem0 flat vector + metadata filter semantic search low
Letta LSM-tree + tool-managed memory blocks tool call 直接讀寫 block medium
Zep knowledge graph (entities + relations) graph traversal + vector medium
OpenViking hierarchical filesystem + L0/L1/L2 directory recursive retrieval high

幾個值得注意的對比點:

  • 可觀測性:OpenViking 的 viking 路徑可以直接 git diff——看 agent 上週到本週新學到了什麼、忘了什麼,紅藍隊都能用。Mem0、Zep 因為是 vector 或 graph,要看「記憶演化」得寫 query 撈,沒那麼直觀
  • debug 友善度:OpenViking 的 retrieval 失敗時,可以直接 ov cat 看那個檔案是不是真的存在、L0 摘要寫得對不對;vector 失敗只能看 cosine similarity 分數
  • agent ergonomics:Letta 的 memory block 介面對 LLM 來說稍微陌生(要學特定 tool API);OpenViking 的 ls/cat/grep 是 LLM 訓練資料裡看過幾百萬次的指令,幾乎不需要 prompt engineering 就能用對
  • token 效率:OpenViking 的 progressive loading 在多輪對話 agent 上能省 30~60% token(依負載而定,coding agent 場景可達 80%+);Mem0 的 flat retrieval 拉一堆相關 chunk 進來,token 通常比較重

當然 OpenViking 也不是萬能:

  • 寫入成本較高:每次 commit 要做 memory extraction、產生 L0/L1 摘要、更新目錄索引,比單純塞 vector 慢一截
  • 冷啟動需要規劃目錄結構:vector DB 是丟進去就能用,OpenViking 至少要先想好目錄怎麼分(雖然 init 有 default schema)
  • GPL 主程式:商業整合要注意授權,純 SDK 用倒是 OK(用 viking-server 對接,自家 agent 不算 derivative work),但企業內部直接 fork 主程式的話得評估

五、適合用、不適合用的場景

從實戰角度,OpenViking 真正能發揮價值的場景大概是:

  • 長期駐點 agent:客服機器人、個人助理、開發助理這類跑數週數月的 agent,使用者偏好跟過往事件累積得很多
  • coding agent:codebase 本身就是樹狀結構,跟 viking 的目錄範式天然對得上;「上週改了什麼」可以直接 git log,跟 viking 的演化追蹤思路一致
  • 多 agent 協作:viking 路徑可以當共用 namespace,多支 agent 透過讀寫同一棵 file tree 交換上下文,比 message passing 直觀

不太適合的場景:

  • 單次 RAG 問答:給一份 PDF 問五個問題就退場的場景,OpenViking 的 init 跟目錄規劃成本不划算,直接用 LangChain + Pinecone 還比較快
  • 超大規模語料:viking 不是設計來存幾億份文件的,它是 agent 私有記憶層;要做 web-scale RAG 還是 vector DB 適合
  • 需要極低 write latency:每次 commit 都要做 extraction,p99 通常 1~3 秒,不適合 high-throughput 寫入

六、把 file-system paradigm 當成一個更大的訊號

這篇文章最後想拉高一個層級:OpenViking 真正的意義可能不只是「又一個 agent memory 框架」,它代表的是 2026 年下半年開始浮現的一個新趨勢——agent-native architecture

過去兩年所有 agent 周邊的工具(向量庫、knowledge graph、memory framework)都是把人類為傳統應用設計的 infra「轉接」給 agent 用。Vector DB 原本是為了搜尋引擎設計,knowledge graph 原本是為了資料分析設計,工程師再把它們適配到 agent 場景。OpenViking 的選擇很不一樣——它直接從「LLM 最熟什麼介面」回推設計:LLM 從訓練資料裡看過幾億次的 bash 操作,所以記憶層用 file-system 介面;LLM 自然會 git diff 看歷史,所以記憶演化用 commit log 表達。

這套思路在 2026 年也出現在其他幾個專案上:把 agent memory 當成 git repo、把 agent skill 當成 shell script、把 agent 的世界觀當成 unix /proc 介面。Anthropic、ByteDance、OpenAI 都在不同切面提出類似的設計。OpenViking 是這套哲學在「記憶層」的一個成熟實作。

對工程團隊的實務含意是:未來幾年挑 agent infra 的時候,「對 LLM 而言介面是否直觀」可能會比「對人類工程師是否直觀」更重要。這是一個跟過去十年 cloud-native 完全不一樣的設計優先順序,值得提早建立判斷力。

參考資料

分享這篇
X LinkedIn Facebook Hacker News Reddit

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料