首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Agent Memory 从 Chroma 到 OpenViking:我的选型实战

Agent Memory 从 Chroma 到 OpenViking:我的选型实战

作者头像
陆业聪
发布2026-07-08 20:09:57
发布2026-07-08 20:09:57
80
举报

📰 科技要闻

• 少数派报道:有开发者用 100% Vibe Coding 方式完成 Game Jam 游戏开发,Agent 工作流全程闭环

• AI 陪伴机器人赛道再获资本青睐:ZuzuZoos 完成数千万元 Pre-A 轮融资,聚焦 AI-Native 潮玩

• Nathan Lambert 发文呼吁不应禁止开源 AI,认为开放生态对安全研究和产业发展至关重要

我的 Agent 总是"失忆"——从一次真实线上事故说起

两个月前我们内部上线了一个代码审查 Agent。跑了三天,收到同事反馈:"这玩意儿是不是每天都在重新认识我?我昨天刚说过喜欢函数式风格,今天它又给我推命令式写法了。"

我去查日志,发现问题出在 Memory 层——我们用 Chroma 存对话历史,每次 similarity search 返回的 top-5 里,3 条是三个月前的旧偏好,2 条是毫不相关的代码片段。向量相似度在时序维度上完全失灵了

更尴尬的是,我们给 Agent 配了三种"记忆源":Chroma 存对话历史、一个 JSON 文件存用户偏好、项目文档放在 LangChain 的 VectorStore 里。三个地方三套查询逻辑,某天 JSON 文件被另一个定时任务覆盖了,Agent 瞬间"人格分裂"。

这个事故让我开始认真调研 Agent Memory 的工程方案。然后我撞上了 OpenViking。

向量库做 Agent Memory:到底差在哪

先定义问题。Agent Memory 跟普通 RAG 的需求差异在于:

需求维度

RAG 问答

Agent Memory

数据变动

文档相对静态

每次对话都产生新记忆

时序性

不敏感

强依赖(最新偏好覆盖旧的)

多类型

主要是文档

偏好+事实+技能+对话+反馈

写入频率

批量导入

实时写入(每轮对话)

去重/冲突

不常见

必须处理(偏好变更)

Chroma 和 Milvus 本质是向量检索引擎——它们解决"给一个 query,找最相似的 k 个文档"。但 Agent Memory 的需求远不止于此。

我在实际项目中遇到的具体问题:

1. embedding 模型对"时效性"无感。用户三天前说"我喜欢 tabs",今天说"我改用 spaces 了"。两句话的 embedding 距离很近(都是关于缩进的偏好),向量搜索不知道该优先哪个。你必须自己加 timestamp metadata + 手写过滤逻辑。

2. 上下文预算管理是噩梦。我做过一个实测:同一个 Agent,用 Chroma top-10 注入 context,平均每次消耗 3200 tokens 在"记忆"上。但其中只有约 40% 的内容跟当前查询真正相关。也就是说,60% 的 token 预算浪费在了噪声记忆上

3. 调试几乎不可能。当 Agent 给了一个错误回答,我需要知道:"它这次召回了哪些记忆?为什么这些被召回了?为什么正确的记忆没被召回?"Chroma 的答案是一个 distance 分数列表,仅此而已。

OpenViking 的文件系统范式:换一种思维管上下文

OpenViking 是火山引擎 Viking 团队 2026 年 1 月开源的项目(GitHub 22K+ star),定位是 AI Agent 的"上下文数据库"。它的核心思路是:把上下文当文件系统来管理,而不是当向量集合来管理

这个类比不是随便说说。它真的实现了一套虚拟文件系统:

代码语言:javascript
复制
viking://
├── resources/    # 知识:文档/代码/FAQ
│   └── code_review/
│       ├── style_guide.md
│       └── arch_patterns.md
├── user/         # 用户认知
│   └── memories/
│       ├── preferences/
│       │   ├── coding_style.md
│       │   └── review_tone.md
│       └── entities/
│           └── teammates.md
└── agent/        # Agent 自身
├── skills/
└── memories/
├── cases/
│   └── refactor_advice.md
└── patterns/
└── large_pr_strategy.md

这个设计解决了碎片化问题——所有上下文统一在一棵树里,有明确的分类和路径。不再需要"这个放 Collection A 还是 B"的纠结。

L0/L1/L2 三层加载:token 消耗下降 60%+

这是我觉得 OpenViking 最实用的设计。每个上下文条目在写入时会自动生成三个层级:

L0(~100 tokens):摘要。用于向量搜索阶段的粗筛

L1(~2000 tokens):概览。用于精排和内容导航

L2(无上限):完整内容。确认需要后才加载

类比操作系统的虚拟内存:L0 相当于页表项(极小,用于定位),L1 相当于页面描述符(中等,判断要不要加载),L2 相当于实际页面内容(完整数据,按需换入)。

我做了一个粗略的对比测试(同一组 200 条 Agent 记忆,相同 query):

方案

注入 Tokens

相关命中率

Chroma top-10

~3200

4/10 (40%)

Chroma top-5 + rerank

~1800

3/5 (60%)

OpenViking 分层

~1100

4/5 (80%)

token 消耗降了 65%,命中率反而提升了一倍。原因很简单——分层加载让系统可以在 L0 阶段就过滤掉大量噪声,只对真正有可能相关的条目加载 L1/L2。

目录递归检索 vs 全局 flat search

传统向量检索是"大海捞针"——把 query embedding 跟所有数据点算距离。OpenViking 是"按图索骥"——先锁定目录,再在目录内精搜。

Query: "小王的代码风格偏好"

意图分析 → 拆分为 "小王" + "代码风格"

L0 召回 → 命中 user/memories/ 目录

进入 user/memories/entities/ 找到 "小王"

进入 user/memories/preferences/ 找到 "coding_style"

精确返回:小王的 coding_style 偏好(L2)

关键差异:Chroma 做全局搜索时,"小王的代码偏好"可能跟"老李的代码偏好"的 embedding 距离很近(因为都涉及"代码偏好"),导致误召回。但 OpenViking 的目录结构天然隔离了不同实体的上下文。

记忆自迭代:Agent 越用越聪明的秘密

OpenViking 把记忆分成六类,分别归属于 user 和 agent:

user 侧:profile(基本信息)、preferences(偏好)、entities(人物/项目)、events(决策/里程碑)

agent 侧:cases(学到的案例)、patterns(发现的模式)

最有意思的是 agent/patterns。在我的代码审查 Agent 上,经过两周运行后,它自动提取出了这些模式:

代码语言:javascript
复制
# viking://agent/memories/
# patterns/review_strategy.md
# (自动提取,非人工编写)模式1: PR 超过 300 行时,
先给架构层面的整体意见,
再逐文件详评。
用户满意度显著高于直接逐行评。模式2: 涉及并发代码修改时,
优先检查是否有竞态条件,
其次检查锁的粒度。
历史上该类 review 漏掉竞态的
概率最高(3/7)。模式3: 建议 refactor 时带代码示例
的采纳率(72%)远高于纯文字建议
(31%)。

这些模式是 Agent 从自身执行历史中学到的"经验"。下次遇到类似场景,它会主动应用这些模式。用 Chroma 做这件事?你得自己写一整套"反思-提取-去重-更新"的管线代码。

实操:5 分钟从 Chroma 迁移到 OpenViking

如果你现在有一个基于 Chroma 的 Agent Memory,迁移路径比想象中简单:

代码语言:javascript
复制
# 1. 安装
pip install openviking --upgrade# 2. 初始化(交互式配置)
openviking-server init
# 选择 VLM provider 和
# Embedding model# 3. 健康检查
openviking-server doctor

然后把 Chroma 里的数据按类型导入:

代码语言:javascript
复制
from openviking import Client
import chromadb# 连接两端
ov = Client()
chroma = chromadb.Client()
coll = chroma.get_collection(
"agent_memories"
)# 批量导出 Chroma 数据
results = coll.get(
include=[
"documents",
"metadatas"
]
)# 按 metadata.type 分类写入
for doc, meta in zip(
results["documents"],
results["metadatas"]
):
mem_type = meta.get(
"type", "general"
)
# 映射到 OpenViking 路径
if mem_type == "preference":
path = (
"viking://user/"
"memories/preferences/"
)
elif mem_type == "knowledge":
path = (
"viking://resources/"
)
else:
path = (
"viking://agent/"
"memories/cases/"
)ov.write(
path + meta["id"] + ".md",
content=doc
)
# OpenViking 自动生成
# L0/L1/L2 三层索引

写入后,OpenViking 会自动对每个文件生成 L0 摘要和 L1 概览——不用你手动处理。

接入 Agent 的检索调用

代码语言:javascript
复制
# 之前(Chroma):
results = coll.query(
query_texts=[user_msg],
n_results=10
)
context = "\n".join(
results["documents"][0]
)
# 问题: 10条全塞,token爆炸# 现在(OpenViking):
context = ov.find(
user_msg,
# 只返回最终需要的内容
# 内部自动完成:
# L0粗筛→目录定位→
# L1精排→L2按需加载
)
# context 已经是精简后的
# 高相关上下文

我的选型判断:何时该切

说实话,我不觉得每个项目都需要上 OpenViking。我的判断标准:

🟢 适合 OpenViking 的场景:

• Agent 记忆条目 > 100 条,且持续增长

• 需要管理 3 种以上不同类型的上下文

• 你已经在自己写记忆去重/更新逻辑了

• token 预算紧张(比如用 Claude 3.5 的 200k 窗口但上下文太多)

• 多 Agent 协同,需要共享上下文空间

🔴 没必要迁移的场景:

• 简单 RAG:文档进、答案出,不需要长期记忆

• 记忆条目 < 50 条,Chroma top-5 就够用

• 已经用 LangChain/LlamaIndex 搭好了且效果达标

• 团队没有 Rust 编译环境(第一次安装会比较折腾)

💡 折中方案:OpenViking 底层支持外接 Milvus 作为向量引擎。如果你的团队已经有 Milvus 集群,可以让 OpenViking 作为上层抽象,Milvus 继续做向量存储和检索——两者不冲突。

一些坑和注意事项

用了一个月,踩过的坑也分享一下:

1. VLM 费用。OpenViking 的 L0/L1 生成依赖 VLM 模型。如果你用 GPT-4o 做 VLM,每写入 100 条记忆大约花费 $0.3-0.5。推荐用 Doubao 或自部署的开源模型控制成本。

2. 冷启动时间。第一次导入大量数据时,生成 L0/L1 需要时间(100 条约 2-3 分钟,取决于 VLM 速度)。建议后台异步处理。

3. Rust 编译。核心引擎是 Rust 写的,在某些系统上 pip install 会触发本地编译。提前装好 Cargo + GCC 9+,或者等官方的预编译 wheel。

4. 协议是 AGPL v3。如果你的项目是闭源商业产品且不想开源,需要跟火山引擎聊商业授权。纯内部使用和开源项目没有限制。

总的来说,OpenViking 让我从"自己拼装 Agent Memory"的手工模式,切换到了"用一个专门设计的基础设施"的模式。代码量少了 40%,效果好了一倍。如果你也在被 Agent 的记忆管理折磨,建议花半天时间试试。

下一篇我会接着聊"代码 RAG 的切片之痛"——为什么按 token 切片在代码上效果那么差,以及 Qoder repoWiki 的 Wiki 化预处理方案值不值得学习。下一篇将继续系列。

📎 参考资料 • GitHub: github.com/volcengine/OpenViking • 官方文档: docs.openviking.ai • 技术栈: Rust 核心引擎 + Python SDK

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-07-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 陆业聪 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档