作者实现了 Qdrant 向 Memanto OKF 开放格式的无损迁移 pipeline,包含四阶段exporter→mapper→OKF bundle→round-trip验证。
AI 智能体正在获得记忆能力,这很棒——直到你想切换记忆后端。这就是我花了一周时间解决的问题:将基于向量存储的智能体记忆迁移到开放、可移植的格式,且不丢失任何一条记录。
大多数智能体记忆系统(Mem0、LangChain、LlamaIndex)将嵌入向量和载荷持久化到向量数据库中,如 Qdrant、Pinecone、Weaviate 或 Redis。数据以专有的集合 schema 形式存储,以无损、可移植的方式导出数据是一个没有人真正解决的痛点。
后来我发现了 Memanto——一个为智能体记忆定义开放知识格式(OKF)的项目。他们的赏金任务要求实现迁移适配器:从一个流行的向量数据库中取出记忆存储,导出为 OKF 包,并证明往返迁移是无损的。
我选择了 Qdrant 路径——这是目前最常见的生产级向量存储,支撑着大量智能体记忆(Mem0 的默认选项,加上 LangChain 和 LlamaIndex 的集成)。
适配器是一个四阶段的管道:
Qdrant collection
│ (1) exporter — pull all points + payloads
▼
records.jsonl
│ (2) mapper — Qdrant schema → OKF schema
▼
OKF bundle (manifest + records)
│ (3) round-trip validator — re-ingest and diff
▼
parity report (61/61 records)
阶段 1 — 导出器(Exporter)
连接到 Qdrant 集合,通过所有 points 分页滚动(使用 limit=100 和 offset 游标进行 scroll),将每个 point 的 id、vector 和 payload 导出到 JSONL 文件。游标分页很关键——Qdrant 的 scroll API 返回一个 next_page_offset,必须持续跟随直到它为 null。如果这一步处理错误,会静默地截断集合。
阶段 2 — 映射器(Mapper)
这是真正工作所在。Qdrant points 有 id(UUID 或无符号整数)、vector 和 payload(任意 JSON)。OKF 需要规范化的记录结构。映射器处理以下内容:
{ "metadata": {...}, "content": "...", "embedding": {...} } 这样的结构)阶段 3 — 往返验证(Round-trip validation)
这是将真正的适配器与 demo 区分开来的部分:将 OKF 包重新导入到一个全新的 Qdrant 集合中,并与源数据进行 diff 对比。我的验证器检查以下内容:
对真实源集合的端到端运行产生了:
Records exported: 61
Records restored: 61
ID matches: 61/61
Payload matches: 61/61
Vector matches: 61/61
Parity: 61/61 ✓
零丢失迁移——每条记录都完整地经历了导出 → 映射 → 恢复的完整周期。
浮点漂移是真实存在的。Vector 相等性检查需要一个 epsilon。我使用了 np.allclose 并设置 atol=1e-6;如果你需要位精确的 vector,可以在包中存储原始字节。
Payload 的可移植性取决于你的映射器。如果你的源 payload 有非字符串键的嵌套对象(罕见,但可能出现于 JSON 中),映射器需要显式处理。
这验证的是结构,而不是语义。往返迁移证明了字节存活下来了,但不能保证下游智能体会给出相同的答案。这是一个我想添加的后续测试(嵌入一个探测问题,比较迁移前后的答案)。
该 PR 正在等待维护者审查——迁移展示仓库模式意味着多个独立提交都是受欢迎的,所以这个适配器无论怎样都可以作为参考实现而独立存在。
锁定是智能体开发中的一笔隐性税。每个记忆系统都有自己的一套集合 schema,而切换的成本随着你存储的每条记录增长。一个带有可工作迁移适配器的开放格式意味着:
适配器模式(导出器 → 映射器 → 验证器)可以移植到任何存储。只要骨架相同,换个连接器就行。
这是作为对 Memanto 开放记忆格式项目的贡献而构建的。完整的适配器实现和测试套件都在这个迁移 PR 中。