寫過 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 可以用 ls、cd、cat、find 之類它原本就熟的指令操作自己的長期記憶。到撰文的 2026-04-29 為止,這個 repo 已經累積 23K+ stars、1.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 的差異一次拆清楚。

一、為什麼向量 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 從訓練資料裡看過幾百萬次 ls、cd、cat、grep 的操作模式,那麼讓它用這套介面操作自己的記憶,對 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 任務時的行為完全一樣——它原本就會 ls、cat、grep 你的 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:
- 意圖分析:LLM 先讀使用者請求,判斷大致要找什麼類型(preferences? events? configs?)
- 目錄定位:到對應的 root 目錄底下做一次 vector 排序——但是排的是目錄本身的描述,不是底下的 chunk
- 遞迴下探:選分數最高的目錄,重複步驟 2,直到走到具體檔案
- 逐層展開:先讀 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+或 Clang11+) - 一個 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-text 跟 llama3.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_find、viking_cat、viking_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 完全不一樣的設計優先順序,值得提早建立判斷力。
參考資料
- OpenViking 官方 repo:github.com/volcengine/OpenViking
- 官方文檔:volcengine-openviking.mintlify.app
- 官方網站:openviking.ai
- FAUN 技術解析:OpenViking Explained: Reinventing Memory and Context for AI Agents
- Emelia 概覽:OpenViking: Context Database for AI Agents


發佈留言