【LanceDB】Harness 原生存储:AI Agent 的 Lakehouse 级记忆
【LanceDB】核心架构与 Harness 设计原理:让 AI Agent 拥有 Lakehouse 级记忆的嵌入式向量库
一句话概括:LanceDB 不是又一个”在 PostgreSQL 上加 pgvector”,而是为 AI Agent 时代重新设计的列存 Lakehouse。它的核心赌注是:当 Agent 需要同时检索文本、图片、点云、视频帧并按版本回滚时,传统行存数据库会全部崩塌。
引子:当 Agent 记忆撞上 PostgreSQL 的天花板
假设你正在给一个多模态 Agent 搭记忆层。需求如下:
- 工程师上传一份 PDF + 3 张示意图 + 一段会议录音,Agent 需要在回答时同时引用三者的内容
- 每次问答后要把新的对话嵌入写入记忆库,要求支持版本回溯(30 天前那次错误的 chunking 不能悄悄改掉)
- 在线 5 万 QPS,向量召回 P99 延迟 < 30ms
- 团队有人在用 OpenAI 嵌入,有人在用本地 BGE-M3,还有人想试试 ColPali(专门为多页 PDF 设计的视觉嵌入)
- 必须能跑在单机笔记本上做 POC,又要能平移到云上处理 PB 级数据
把这套需求塞进传统数据库会出现什么情况?
| 需求 | PostgreSQL + pgvector | Milvus / Qdrant(独立向量库) | LanceDB |
|---|---|---|---|
| 多模态 Blob + 向量共存 | 弱(只能存 URL + 外键) | 弱(向量库外置对象存储) | 原生支持(Lance 列存 + Blob 扩展类型) |
| 数据版本回滚 | 需要业务自己写逻辑 | 一般不支持 | 零拷贝版本树(Lance 文件级别) |
| 切换嵌入模型 | 要重灌全量数据 | 要重灌全量数据 | Schema 内嵌 EmbeddingFunction 注册表 |
| Hybrid Search(向量 + 全文 + 过滤) | 三套系统拼凑 | 通常需要 ES + 向量库双写 | 单一 Lance 列存 + 统一查询计划 |
| 单机 POC → 云端扩展 | 业务改写 | 业务改写 | 同一套 API,路径从 ./data 切到 s3:// 即可 |
| Pydantic / ORM 集成 | 需要手写映射层 | 需要手写映射层 | LanceModel 一行声明向量字段 |
LanceDB 的核心定位就一句话:“为 AI 工作负载重写的列存 Lakehouse,向量检索只是其中一个索引维度”。它把 Harness Engineering 里的”记忆层”从外挂组件提升成一等公民。
下面我从 6 个维度把这套架构拆给你看。
一、项目定位:在 Harness 6 件套中处于哪一格?
LanceDB 主要支撑的是 Memory 子层 + Script 子层(数据平面)。先看全景:
graph LR
subgraph Harness["🤖 AI Agent Harness"]
Rule["📜 Rule<br/>团队政策"]
Skill["📚 Skill<br/>SOP"]
Sub["🧩 Sub-Agent<br/>角色分工"]
WF["🔁 Workflow<br/>状态机"]
Script["⚙️ Script<br/>硬关卡"]
MCP["🔌 MCP<br/>外部桥接"]
end
subgraph Memory["🧠 Memory 子系统"]
Lance["💎 LanceDB<br/>列存 Lakehouse"]
Buf["📨 写入路径<br/>EmbeddingFunction Registry"]
Read["🔍 读取路径<br/>Hybrid Query + Reranker"]
end
Agent["🚀 Agent Loop"] -->|search / add| Lance
Lance --> Buf
Lance --> Read
Agent -.->|调用工具| Script
Script -.->|持久化| Lance
style Harness fill:#F5F5F5,stroke:#999,color:#333
style Memory fill:#E8D5F5,stroke:#999,color:#333
style Lance fill:#C7CEEA,stroke:#5A6FA0,color:#333
style Buf fill:#FFDAB9,stroke:#999,color:#333
style Read fill:#B5EAD7,stroke:#5A8A6A,color:#333
style Agent fill:#FFB3C6,stroke:#999,color:#333
style Script fill:#FFF9C4,stroke:#999,color:#333为什么它落在 Memory 子系统?
在 Harness Engineering 框架里,Memory 子层需要满足三个硬指标:
- 多模态原生——文本、图像、点云、视频帧必须能用同一套 schema 存同一张表
- 写入即版本——任何 chunking / 嵌入策略变更都不能”无痕改写”历史
- 检索即组合——向量近似 + 全文精确 + 元数据过滤 + 后排序必须是同一个查询计划
LanceDB 是为数不多同时把这三条都做对的开源实现(其他往往是 Milvus 做向量 + ES 做全文 + MinIO 做对象存储拼出来的”伪 Lakehouse”)。
二、整体架构:4 层抽象 + 1 个核心数据结构
LanceDB 的代码组织非常清晰,核心数据结构只有一个:LanceTable——一切上层 API 都是它的视图。来看分层:
graph TB
subgraph L4["第 4 层:用户 API"]
Py["🐍 Python SDK<br/>db.py / table.py"]
Js["📜 JS/TS SDK"]
Rust["🦀 Rust SDK"]
REST["🌐 REST API"]
end
subgraph L3["第 3 层:查询语义层"]
Query["🔍 Query Builder<br/>vector + FTS + hybrid"]
Re["🎯 Reranker<br/>RRF / Cohere / CrossEncoder"]
Expr["🧮 Expr<br/>类型安全过滤"]
end
subgraph L2["第 2 层:核心数据模型"]
Em["📐 EmbeddingFunction<br/>Registry + Base"]
Blob["📦 BlobType<br/>PyArrow 扩展类型"]
Schema["📋 Pydantic LanceModel"]
end
subgraph L1["第 1 层:Rust 引擎(_lancedb)"]
Lance["💎 Lance 列存格式<br/>零拷贝 + 版本树"]
Index["⚡ 多索引<br/>IVF-PQ / HNSW / FTS"]
IO["📁 Storage Backend<br/>local / S3 / Azure"]
end
L4 --> L3 --> L2 --> L1
Py --> Em
Py --> Query
Query --> Re
Em -.托管.-> Schema
style L4 fill:#C7CEEA,stroke:#5A6FA0,color:#333
style L3 fill:#E8D5F5,stroke:#999,color:#333
style L2 fill:#FFDAB9,stroke:#999,color:#333
style L1 fill:#B5EAD7,stroke:#5A8A6A,color:#333
style Lance fill:#FFB3C6,stroke:#999,color:#333
style Em fill:#FFF9C4,stroke:#999,color:#3332.1 第 1 层:Lance 列存格式(数据真正的”家”)
Lance 文件格式是 LanceDB 的秘密武器,它由兄弟项目 lance-format/lance 维护,核心特性:
- 列存 + 行组(Row Group):每列独立压缩,文本列用 zstd,向量列用 IVF-PQ 量化
- 零拷贝版本树:每次
table.add()/table.delete()不改写老文件,而是追加新版本,类似 Git commit。table.checkout(version=42)立刻回到任意历史快照 - 数据集级谓词下推:filter
WHERE user_id = 42会被推到 IO 层,只读相关 row group
关键设计哲学:Lance 把”数据即代码”的理念落地——你的向量库不是数据库,而是一个可被 checkout 的版本化数据集。
2.2 第 2 层:EmbeddingFunction 注册表(机制与策略分离)
这是 LanceDB 在 Harness Engineering 上最值得借鉴的设计。看 python/python/lancedb/embeddings/registry.py 的核心结构:
1 | # python/python/lancedb/embeddings/registry.py |
注意它暴露的 register() 是个装饰器工厂——任何 EmbeddingFunction 都能在 import 时自动注册,Schema 里就能直接按名字引用。来看一个真实的注册实例(embeddings/openai.py):
1 | # python/python/lancedb/embeddings/openai.py |
设计要点:
- 机制层:
EmbeddingFunction抽象基类,定义compute_source_embeddings()/compute_query_embeddings()/ndims()三个必实现方法 - 策略层:每个具体嵌入模型(OpenAI / Sentence-Transformers / Cohere / Jina / VoyageAI / ColPali / SigLIP)都是独立的 @register 注册项
- 运行时绑定:Schema 序列化时只存
name="openai"+ 配置,反序列化时按名字从 Registry 拉回具体类——切换模型无需迁移数据
这是 Harness Engineering 的精髓:机制和策略分离 = 写一次 EmbeddingFunction 基类,永远支持新模型。对比 pgvector 那种”换嵌入模型必须重灌数据”,这是质变。
2.3 第 3 层:查询语义层(统一 Hybrid)
看 query.py 顶部导入就懂了:
1 | # python/python/lancedb/query.py |
LanceDB 的查询对象不是”向量查询”或”全文查询”二选一,而是 Query 抽象 → VectorQuery / FullTextQuery / HybridQuery 三个特化。Hybrid 同时拿向量召回结果和 FTS 召回结果,再丢给 Reranker:
1 | # python/python/lancedb/rerankers/rrf.py |
这套设计让 Agent 可以写:table.search(vector=..., text=...).rerank(RRFReranker())——一句话完成”先向量召回 + 再全文精排 + 最后 RRF 融合”。
2.4 第 4 层:用户 API(多语言客户端)
LanceDB 提供 Python / JS / Rust / REST 四套接口,底层都是同一个 Rust 引擎。这一点很像 SQLite 的策略——一个引擎,多种绑定。
三、核心机制原理(带可运行代码)
3.1 机制 1:EmbeddingFunction Registry —— 模型热插拔
完整可运行示例,展示”注册一个 EmbeddingFunction → 在 Pydantic Schema 里引用 → 自动绑定到表的写入路径”:
1 | """ |
完整数据流用 Mermaid 看更清晰:
sequenceDiagram
autonumber
actor U as 🧑 用户
participant Sch as 📋 Pydantic Schema
participant Reg as 📚 EmbeddingFunctionRegistry
participant Em as 🔢 EmbeddingFunction
participant T as 💎 LanceTable
participant V as 📦 Vector Index (HNSW/IVF-PQ)
U->>Sch: 1. 声明 Document(vector=Vector(dim=128) = HashEF.create())
Sch->>Reg: 2. 按 alias="hash-128" 查注册表
Reg-->>Sch: 返回 HashEmbeddingFunction 类
U->>T: 3. table.add([Document(...)])
T->>Em: 4. 自动调用 generate_embeddings([text,...])
Em-->>T: 返回 128 维向量数组
T->>V: 5. 写入时构建/更新向量索引
V-->>T: 索引就绪
U->>T: 6. table.search("Harness")
T->>Em: 7. compute_query_embeddings("Harness")
Em-->>T: 返回 query 向量
T->>V: 8. ANN 近邻搜索
V-->>T: top-K 候选 row_id
T-->>U: 9. 返回 [{text, _distance}, ...]
style U fill:#FFB3C6,stroke:#999,color:#333
style Sch fill:#FFF9C4,stroke:#999,color:#333
style Reg fill:#FFDAB9,stroke:#999,color:#333
style Em fill:#E8D5F5,stroke:#999,color:#333
style T fill:#C7CEEA,stroke:#5A6FA0,color:#333
style V fill:#B5EAD7,stroke:#5A8A6A,color:#333运行结果预期:
1 | ✅ 注册成功,可用函数:['hash-128'] |
这个机制解决了 Harness 工程里的一个老问题——当 Agent 的嵌入策略需要从 ada-002 升级到 text-embedding-3-large 时,传统方案要写 ETL 脚本重灌;LanceDB 只改 Schema 的 Vector(...) 字段即可,下次写入自动用新模型。
3.2 机制 2:Hybrid Query + Reranker 组合
LanceDB 的 Hybrid Search 把向量召回、全文召回、过滤、rerank 全部串成一个 Builder 链:
1 | """ |
完整查询流图(一次性看清多路召回如何被 Reranker 融合):
graph LR
Q["🔍 Query<br/>'Hybrid Search'"] --> Branch{Query Type?}
Branch -->|vector| VQ["📐 Vector Query<br/>compute_query_embeddings()"]
Branch -->|fts| FQ["📝 FTS Query<br/>BM25 Tokenize"]
Branch -->|hybrid| Both["⚡ 双路召回"]
VQ --> VR["📊 Vector Results<br/>top-100 _rowid"]
FQ --> FR["📋 FTS Results<br/>top-100 _rowid"]
Both --> VQ
Both --> FQ
VR --> Re{"Reranker?"}
FR --> Re
Re -->|None| Out["📤 Raw Merge<br/>按 distance 排序"]
Re -->|RRF| RRF["🔀 RRFReranker<br/>score = Σ 1/(K+rank)"]
Re -->|Cohere| Coh["🎯 CohereReranker<br/>Cross-Encoder 重打分"]
RRF --> Filter{"where<br/>过滤?"}
Coh --> Filter
Out --> Filter
Filter -->|是| W["🔧 apply where<br/>category = 'advanced'"]
Filter -->|否| L["📏 .limit(N)"]
W --> L
L --> Final["📦 最终结果<br/>[{title, body, score}, ...]"]
style Q fill:#C7CEEA,stroke:#5A6FA0,color:#333
style Branch fill:#FFF9C4,stroke:#999,color:#333
style VQ fill:#E8D5F5,stroke:#999,color:#333
style FQ fill:#E8D5F5,stroke:#999,color:#333
style Both fill:#FFDAB9,stroke:#999,color:#333
style VR fill:#FFDAB9,stroke:#999,color:#333
style FR fill:#FFDAB9,stroke:#999,color:#333
style Re fill:#FFB3C6,stroke:#999,color:#333
style RRF fill:#B5EAD7,stroke:#5A8A6A,color:#333
style Coh fill:#B5EAD7,stroke:#5A8A6A,color:#333
style Out fill:#F5F5F5,stroke:#999,color:#333
style Filter fill:#FFF9C4,stroke:#999,color:#333
style W fill:#FFDAB9,stroke:#999,color:#333
style L fill:#FFDAB9,stroke:#999,color:#333
style Final fill:#B5EAD7,stroke:#5A8A6A,color:#333这段代码展示了 4 种检索模式的优雅切换:
| 模式 | API 入口 | 用途 |
|---|---|---|
| 纯向量 | search(query_type="vector") | 语义召回 |
| 纯全文 | search(query_type="fts") | 关键词精准 |
| Hybrid | search(query_type="hybrid") | 默认融合 |
| Hybrid+过滤 | hybrid + where(...) | 多维召回 |
Harness 价值:当 Agent 需要做”先按向量相似召回 1000 条 → 按 category 过滤到 50 条 → 按 BM25 精排前 10 条 → 用 RRF 融合排序”这种典型 RAG 流水线时,LanceDB 一条 Builder 链搞定,不用写胶水代码。
3.3 机制 3:Merge Insert —— 增量同步的状态机
LanceDB 的 merge_insert() 是 Agent 记忆层最常用的增量同步接口。它用 Builder 模式把”upsert + delete + when_matched”语义写成一个状态机:
1 | # python/python/lancedb/merge.py(简化版) |
实战场景:Agent 每天要同步一次”任务完成情况”到记忆表,规则是:
- 如果任务 ID 已存在 → 更新状态
- 如果任务 ID 不存在 → 插入新行
- 如果任务在源表里消失了 → 从记忆表里删掉
- 只同步 owner == “agent-A” 的任务
1 | """ |
这个 Builder 模式的精妙之处:
- 零分支:调用方用链式 API 表达”什么情况做什么”,没有
if-else地狱 - 编译时校验:每个方法返回
self,编译器可以静态检查链路完整性 - 策略可扩展:未来加
when_matched_ignore()/when_not_matched_log_only()不破坏现有调用
这正是 Harness Engineering 里”机制 vs 策略分离”的实操范本:merge_insert 引擎是机制,when_matched_ 是策略*。
3.4 机制 4:Blob 类型 —— 多模态数据一等公民
传统向量库的痛点:图片 / PDF / 音频只能存 URL + 外键,跨存储查询要写胶水。LanceDB 用 PyArrow 的 ExtensionType 把 Blob 提升为一等公民字段类型:
1 | # python/python/lancedb/schema.py |
两阶段读取:查询默认只返回轻量级 descriptor(URI + size),需要实际字节时再 fetch_blob_files() 或 fetch_blobs() 拉取。这避免了”问一句’有没有相关图片’就把 5GB 图片全部下到内存”的灾难。
四、设计哲学分析:LanceDB 是否符合 Bitter Lesson?
Richard Sutton 的 Bitter Lesson 说:通用方法 + 大算力最终会胜过人类先验的”聪明但小”的方法。LanceDB 做了哪些选择?
4.1 四个 Bitter Lesson 友好的设计
| 设计 | 是否符合 | 理由 |
|---|---|---|
| 底层用 Rust + Arrow 通用列存 | ✅ | 不为某类数据特化存储,最大化通用性 |
| EmbeddingFunction 作为可插拔基类 | ✅ | 不锁死任何嵌入模型,模型变强立刻能切换 |
| Hybrid Query 统一抽象 | ✅ | 不为”向量更好”或”全文更好”站队,让检索融合策略决定 |
| Pydantic Schema 声明式 | ✅ | 用户声明”我要 1024 维向量”,系统决定用 HNSW 还是 IVF-PQ |
4.2 三个”聪明但终将被淘汰”的代码
| 代码 | 为什么是聪明税 | 演化方向 |
|---|---|---|
| 手工配置的多种索引类型(IVF-PQ / HNSW / BTree / Bitmap) | 每种都要调参 | 应该让系统根据数据分布自动选择 |
| rerankers 目录下的 12 个第三方客户端(Cohere / Jina / VoyageAI / Watsonx…) | 每接一个就要写新文件 | 应该让用户通过 register_reranker() 自己注册 |
lang_mapping 字典(手工映射 ISO 语言码到 analyzer 名字) | 写死的语言列表 | 应该读自 CJK 词典等标准源 |
LanceDB 团队正在做后者的工作,比如 EmbeddingFunction 的 @register 装饰器就是为了淘汰硬编码 import。
4.3 Hook 与机制/策略分离
LanceDB 没有像 LangChain 那种 30+ Hook 的总线,但它在更基础的层面做到了机制和策略分离:
- 机制层(Rust 引擎):Lance 列存格式 + 向量索引 + IO 后端
- 策略层(Python 抽象):EmbeddingFunction / Reranker / MergeInsert 三大可插拔接口
- 边界层(Schema):Pydantic LanceModel 把策略声明下沉到数据本身
判断标准:当一个项目把”哪些模型能接”做成开环(用户自己注册)而不是闭环(内置 12 个客户端),它就是 Bitter Lesson 友好。
五、优缺点对比
按 Harness Engineering 标准的左/右视图:
| 维度 | LanceDB | 代价 |
|---|---|---|
| 架构简洁性 | ✅ 列存 + 单一文件格式 + Rust 内核,没有”模块拼凑感” | ❌ 编译产物大(macOS arm64 wheel ~180MB) |
| 扩展性 | ✅ EmbeddingFunction / Reranker / Index 三套注册表 | ⚠️ 自定义索引需要写 Rust 扩展 |
| 易用性 | ✅ Pydantic LanceModel 一行声明向量字段 | ❌ HNSW / IVF-PQ 参数语义对新手不透明 |
| 性能 | ✅ 列存 + 零拷贝 + 谓词下推,单机亿级向量 OK | ❌ 分布式版本依赖 Lance Cloud(开源版单机) |
| 复杂度 | ⚠️ 概念较多(Chunking / Embedding / FTS / Rerank / MergeInsert) | ❌ Pydantic v1/v2 双版本兼容代码历史包袱重 |
| 维护性 | ✅ Rust 核心 + Python 包装,分层清晰 | ⚠️ 文档主要在 docs.lancedb.com,主仓 docs/ 偏 API 参考 |
关键观察:LanceDB 用”列存内核 + 嵌入式 Python 客户端”的策略,把 PostgreSQL 时代数据库工程师的设计直觉移植到了 AI 时代——这是优点也是缺点。优点是数据量大时性能强;缺点是概念门槛比”装个 SQLite 文件”高。
六、横向对比:与同类向量存储的设计哲学差异
6.1 vs Qdrant(34k⭐ Rust 向量库)
Qdrant 是**”向量优先的专用数据库”,LanceDB 是“列存优先的 Lakehouse 附带向量索引”**。
| 维度 | Qdrant | LanceDB |
|---|---|---|
| 存储底座 | 自定义 HNSW + Payload 索引 | Lance 列存文件 |
| 多模态 Blob | 不原生支持(payload 只存元数据) | 原生 Blob v2 扩展类型 |
| 版本回滚 | 需手动实现 | 零拷贝版本树 |
| 部署模式 | 服务端(gRPC/HTTP) | 嵌入式(import 即可用) |
| 扩展嵌入模型 | 客户端编码 | Schema 内嵌 + Registry 序列化 |
关键设计差异:Qdrant 是”数据库服务”模型,LanceDB 是”嵌入式库”模型。Agent 选哪个取决于场景——需要多 Agent 共享一个服务时选 Qdrant;Agent 需要把记忆层塞进自己的进程时选 LanceDB。
6.2 vs Milvus(46k⭐ 分布式向量库)
Milvus 是”集群版大杀器”,LanceDB 是”单机也能跑 POC”的轻量版。
| 维度 | Milvus | LanceDB |
|---|---|---|
| 部署复杂度 | 需要 etcd + MinIO + Pulsar + 多个 Milvus Pod | pip install 即用 |
| 数据规模 | PB 级(已验证) | TB 级(单机)/ PB 级(云) |
| 索引类型 | IVF / HNSW / DiskANN / GPU | IVF / HNSW / FTS / Bitmap |
| Hybrid Search | 需配 Milvus + ES 双栈 | 单一引擎统一抽象 |
| 版本控制 | 有限支持 | 零拷贝版本树是核心特性 |
关键设计差异:Milvus 是”用一套复杂基础设施换横向扩展”,LanceDB 是”用单一进程换简单性 + 用 Lance Cloud 平移到云”。两者并不冲突,很多团队在 POC 阶段用 LanceDB,验证通过后无缝切到 Lance Cloud。
6.3 vs pgvector(22k⭐ PostgreSQL 扩展)
pgvector 是”在现有 PostgreSQL 上补一个向量列”,LanceDB 是”为 AI 重新设计的列存”。
| 维度 | pgvector | LanceDB |
|---|---|---|
| 数据规模 | 受限于 PostgreSQL 单机 | Lance 列存 + S3 后端 |
| 多模态 | 弱 | 原生 Blob |
| 版本控制 | 不支持 | 零拷贝版本树 |
| 迁移成本 | 低(已经在用 PG) | 高(新系统) |
| Hybrid 检索 | 弱(需 tsvector + 自写 RRF) | 原生 + 12 种 Reranker 策略 |
关键设计差异:pgvector 的”在数据库里加一列向量”哲学,适合存量系统渐进式升级;LanceDB 的”AI Lakehouse”哲学,适合从零搭建的 AI 原生应用。混合部署的常见做法:核心交易数据放 PostgreSQL + 向量检索放 LanceDB,两边按业务 ID 关联。
七、从零搭建启示:复刻 MVP 的最小代码
如果你想自己实现一个”AI 原生向量存储”的 MVP,应该抄什么、省什么?
7.1 必做(机制层)
1 | """ |
7.2 可省(暂时不做)
| LanceDB 特性 | MVP 是否需要 | 理由 |
|---|---|---|
| Rust 内核 | ❌ 用 pyarrow + parquet 替代 | POC 阶段 Python 够用 |
| 分布式存储 | ❌ 单机文件 | 等业务上量再考虑 |
| 12 个 Reranker 客户端 | ❌ 先实现 RRF + CrossEncoder | 覆盖 80% 场景 |
| OAuth 远程客户端 | ❌ 暂时不支持 | 等企业级需求 |
| Pydantic Schema 集成 | ⚠️ 可选 | 直接用 pyarrow Schema 更轻 |
7.3 踩坑预警
- Pydantic 版本兼容性:LanceDB 同时支持 v1 和 v2,但
arbitrary_types_allowed配置在不同版本下行为不一致 - EmbeddingFunction 序列化:把 EmbeddingFunction 持久化到表 schema 后,切换模型需要新建表——这是显式的”打破向后兼容”设计,提醒用户注意数据迁移
- FTS 索引的 tokenizer 选择:中文必须显式配
tokenizer="jieba"或tokenizer="luceneplus",否则会按字符切分,效果很差 - 大文件 Blob 读取:默认 lazy 模式下,
to_pandas()不返回图片字节,必须显式fetch_blobs()
八、结论:什么时候选 LanceDB?
选 LanceDB 的信号:
- ✅ Agent 需要持久化多模态记忆(文本 + 图片 + 音频)
- ✅ 需要版本回溯(”30 天前那次错误的 chunking”能被 checkout)
- ✅ 团队不想运维一套向量库服务
- ✅ 嵌入模型可能在未来切换
- ✅ 数据规模从 POC 到 TB 级(不需要 PB 级横向扩展)
不要选 LanceDB 的信号:
- ❌ 已有 PostgreSQL 且需要 ACID 事务(选 pgvector)
- ❌ 数据规模确定要 PB 级(选 Milvus + 集群)
- ❌ 团队完全没有 Rust / Python 工具链维护能力(选 Qdrant 容器化部署)
一句话总结:LanceDB 是把”AI Agent 的记忆层应该长什么样”这个问题,用列存 Lakehouse 的答案讲清楚的开源项目——它不是最快的向量库,也不是最大的向量库,但是为 AI 工作负载设计得最彻底的。
附录:参考资料
- 项目仓库:https://github.com/lancedb/lancedb (11k⭐,2026-08-22 主分支最新提交)
- 官方文档:https://docs.lancedb.com
- 底层列存格式:https://github.com/lance-format/lance
- 同系列对比文章:
- 【Qdrant】核心架构(2026-06-08)
- 【Milvus】分布式架构(2026-06-14)
- 【Weaviate】LSM + 模块化(2026-06-20)
- 【PageIndex】Vectorless RAG(2026-07-24)
- 集成生态:LangChain / LlamaIndex / Apache Arrow / Pandas / Polars / DuckDB
调研感悟:写完这篇发现 LanceDB 真正的护城河不是它的向量索引(HNSW 谁都能实现),而是Lance 列存格式 + EmbeddingFunction Registry 这对组合。前者给了它”AI 时代文件系统”的底座,后者给了它”模型热插拔”的灵活度。当一个 Agent 框架需要把”记忆层”做成 Harness 的一等公民时,这种”嵌入式 + 持久化 + 可演化的库”形态比”服务化数据库”更有未来。