转载:小红书 AI产品赵哥
前言🔖
上一篇笔记我们聊了 LangChain 在生产环境的坑,其中最大的一个坑就是 RAG(检索增强生成)的效果问题。而 RAG 最重要的,不就是向量数据库(Vector Database)嘛。
很多产品经理在规划 AI 项目时,听到开发说 “我们要选型向量库”,往往一脸懵:
- 数据库不就是 MySQL、PostgreSQL 吗?
- 为什么为了 AI 要专门搞个新的?
- 市面上的 Chroma、FAISS、Milvus、Pinecone 到底有啥区别?
今天,我们来聊聊这个话题:在 LangChain 里怎么选择向量数据库。准备好了吗?出发!
一、为什么要用向量数据库?
在传统软件开发中,我们用 MySQL 存用户资料,用 Redis 存缓存,用 ElasticSearch 做关键词搜索。
但在 AI 时代,这些都不够用了。
🔹1. 计算机读不懂 “意思”
传统的搜索是关键词匹配。
- 用户搜:“苹果手机没电了怎么办?”
- 数据库找:“苹果”、“手机”、“没电”。
- 如果你有一篇文档写的是:“iPhone 电池耗尽后的处理方案”,这里没有 “苹果” 也没有 “没电”,传统数据库可能就搜不到。
🔹2. Vector(向量)是 AI 的通用语言
大模型(Embedding Model)把一段文字变成一串数字(通常是 768 个或 1536 个浮点数)。这串数字就叫 向量。
- “苹果手机” 变成了
[0.1, 0.5, -0.3, ...] - “iPhone” 变成了
[0.12, 0.48, -0.29, ...]
这两个向量在数学空间里距离非常近。向量数据库的核心能力,就是算距离。它能在毫秒级的时间内,从几百万个向量里找到跟用户问题最接近的那几个。
关系型数据库(MySQL)存的是精确数据,向量数据库存的是语义关系。 要做 RAG,向量数据库是刚需。
二、上手三剑客:FAISS、Chroma、Milvus
LangChain 支持几十种向量库,但对于大多数项目,你只需要关注这三个代表性的选手。它们分别代表了三种不同的产品形态和适用场景。
🔹1. FAISS:不是数据库的数据库
定位:这是一个由 Facebook 开源的算法库,而不是一个独立的服务器软件。
- 特点:它轻量、极快,通常直接嵌入在 Python 代码里运行。它没有独立的进程,数据通常存在内存里(RAM),或者存成本地文件。
- LangChain 中的地位:它是很多其他向量数据库的底层引擎。
- 优点:
- 零部署成本:
pip install faiss-cpu就能用,不需要安装 Docker,不需要配置服务器。 - 速度极快:在百万级数据量下,它的搜索速度是毫秒级的。
- 零部署成本:
- 缺点:
- 易失性:如果你的 Python 程序挂了,内存里的数据就没了。虽然可以保存成文件,但不支持实时的高并发写入。
- 无法水平扩展:你的服务器内存有多大,它就能存多少数据。无法像真正的数据库那样搞集群。
- 适用场景:
- 本地 Demo 或 PoC(概念验证):比如你在自己的笔记本上跑一个文档问答机器人。
- 一次性离线任务:比如每天晚上跑一次全量数据的聚类分析。
- 超小规模应用:只有几百个文档,不需要持久化更新。
🔹2. Chroma:AI 时代的 “SQLite”
定位:一个 AI 原生的开源向量数据库,主打易用性和开发者体验。
- 特点:它是目前 LangChain 生态中最受欢迎的轻量级数据库。它可以像 FAISS 一样运行在本地(In-memory),也可以作为服务端部署。它最大的卖点是简单。
- LangChain 中的地位:官方教程和大量开源项目的首选默认配置。
- 优点:
- 开箱即用:安装简单,API 设计非常人性化,完美契合 Python 开发者的习惯。
- 功能够用:支持元数据过滤,比如 “只搜索
category=finance的文档”,这点比 FAISS 强。
- 持久化:它可以把数据存在本地的 SQLite 文件里,程序重启数据还在。
- 缺点:
- 性能瓶颈:在数据量达到千万级时,性能不如 Milvus 稳定。
- 分布式能力弱:虽然 Chroma 正在做服务端版本,但目前主要还是单机为主。
- 适用场景:
- 初创公司的 MVP:快速上线,验证业务。
- 中小型应用:文档数量在 10 万 – 100 万级别。
- 内部工具:给公司内部用的知识库工具。
🔹3. Milvus:重装坦克
定位:企业级、云原生、分布式的向量数据库。
- 特点:由 Zilliz 公司维护,架构非常复杂,基于 K8s,存算分离。它的设计目标就是大规模和高可靠。
- LangChain 中的地位:生产环境、特别是大厂和金融机构的首选。
- 优点:
- 海量存储:轻松支持十亿级向量。你的数据再多也装得下。
- 高可用:支持副本、分片、故障恢复。这才是真正的 “数据库”。
- 高性能:在海量数据下依然能保持低延迟。
- 缺点:
- 运维重:部署它需要 Docker、K8s、Etcd、MinIO… 运维人员看到 docker-compose 文件通常会皱眉。
- 资源消耗大:哪怕没数据,空跑也占不少内存和 CPU。
- 学习曲线陡峭:概念多(Collection, Partition, Segment),开发上手慢。
- 适用场景:
- 企业级生产环境:用户量大,并发高,对稳定性要求极高。
- 海量知识库:比如要把全网的新闻、几千万份法律文书存进去。
- 混合检索需求:需要结合复杂的标量过滤和向量搜索。
三、LangChain 代码视角:切换数据库有多容易?
LangChain 最牛掰的地方在于它定义了一个标准接口:VectorStore。这意味着,你可以用几乎同样的代码,从 Chroma 切换到 Milvus。这对产品迭代非常友好。
看看这段 Python 伪代码,体会一下这种 “无缝切换”:
场景 1:在开发阶段,使用 Chroma
from langchain_openai import OpenAIEmbeddings
from langchain_chroma import Chroma
from langchain_text_splitters import CharacterTextSplitter
# 1. 准备数据
raw_documents = [...] # 假设这是你的文档列表
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
docs = text_splitter.split_documents(raw_documents)
# 2. 选择 Embedding 模型(负责把文字变成向量)
embedding_model = OpenAIEmbeddings()
# 3. 初始化数据库(Chroma)
# persist_directory 指定数据存在本地硬盘的哪里
db = Chroma.from_documents(
documents=docs,
embedding=embedding_model,
persist_directory="./local_chroma_db"
)
# 4. 搜索
query = "如何申请年假?"
result = db.similarity_search(query)
print(result[0].page_content)
场景 2:上线生产环境,迁移到 Milvus
当你的数据量变大,想换成 Milvus,只需要改几行代码:
from langchain_community.vectorstores import Milvus
# 前面的数据处理逻辑完全不用变...
# 3. 初始化数据库(Milvus)
# 这里指向公司部署好的 Milvus 服务器地址
db = Milvus.from_documents(
documents=docs,
embedding=embedding_model,
connection_args={"host": "192.168.1.100", "port": "19530"},
collection_name="company_wiki"
)
# 4. 搜索逻辑完全不用变
result = db.similarity_search(query)
产品经理 Insight:
因为 LangChain 的这种封装,你可以在 PRD 阶段采取 “分阶段演进” 的策略:
- 第一阶段(验证期):强制要求开发用 Chroma,因为快,一周就能出 Demo。
- 第二阶段(灰度期):如果数据量涨得快,或者性能不够了,再安排资源部署 Milvus,代码层面的改造成本极低,主要是运维部署的成本。
四、选型决策矩阵:产品经理该怎么选?
不要只听架构师说哪个技术牛,要结合业务场景。我整理了一个选型决策表,建议收藏。
| FAISS | Chroma | Milvus | |
|---|---|---|---|
| 数据规模 | < 10 万(内存限制) | 10 万 – 500 万 | > 500 万(无上限) |
| 数据持久性 | 低(主要用于临时计算) | 中(本地文件) | 高(企业级存储) |
| 部署难度 | 极低 (pip install) | 低(pip 或单容器) | 高(K8s 集群) |
| 运维成本 | 无 | 低 | 高(需要专门 DBA) |
| 查询功能 | 纯向量搜索 | 支持元数据过滤 | 复杂混合检索 |
| 适合阶段 | Demo, 个人工具,算法验证 | MVP, 内部系统,中型应用 | 核心业务系统,大数据平台 |
还有几个备选项:
除了这三家,你可能会听到:
- Pinecone:闭源的 SaaS 服务。体验极好,完全不用运维,也是 LangChain 的一级公民。但缺点是贵,而且数据在美国,国内企业慎用。
- Elasticsearch (ES):很多公司本来就在用 ES 做搜索。新版的 ES 也支持向量搜索了。如果你们公司运维不想维护一套新的数据库,直接用 ES 也是个折中方案,但向量性能不如专用的 Milvus。
- PostgreSQL (pgvector):如果你们用 PG 数据库,装个
pgvector插件就能存向量。对于不想引入新架构的中小团队,这是个极具性价比的选择。
五、避坑指南:向量数据库里的 “隐形杀手”
在实际落地中,我见过很多产品因为向量库没用好而翻车。这里有 3 个最常见的大坑。
🔹1. 维度不匹配
现象:
开发把代码写好了,一运行就报错,提示维度错误。
或者之前存的数据,换了个模型就搜不出来了。
根因:
向量库里的 “坑位” 大小是固定的。
- OpenAI
text-embedding-3-small产生的向量长度是 1536。 - 其他模型可能是 768、1024 等,一旦建库时指定了维度,就不能随便换模型。
- HuggingFace 上很多开源模型长度是 768 甚至 1024。
解决方案:
在立项之初,必须锁死 Embedding 模型。
如果你中途想从 OpenAI 换到国内的通义千问 Embedding,对不起,数据库里的所有向量必须全部重新生成(Re-indexing)。这不仅费时间,还费钱。
产品经理要在 PRD 里明确:Embedding 模型变更是一次重大重构。
🔹2. 元数据过滤的性能陷阱
现象:
你想做一个文档库,支持按 “年份” 筛选。
用户搜 “2023 年的财务报告”。
逻辑是:先搜出所有关于 “财务报告” 的向量,然后再剔除不是 2023 年的。
在数据量大时,这种 “后过滤” 会让查询变得极慢,或者召回率极低(因为前 100 个结果可能都是 2022 年的,被过滤完就没东西了)。
解决方案:
选择支持 ** 预过滤(Pre-filtering)** 的数据库(Chroma 和 Milvus 都支持,但机制不同)。
在搜索向量之前,先通过元数据索引把范围缩小到 2023 年的数据集,再在里面做向量搜索。
产品经理需要确认:你的业务场景中,过滤条件(Filter)是不是高频操作?如果是,一定要选对数据库。
🔹3. 冷启动与索引构建时间
现象:
你的应用上线了,你要把公司 100 万份 PDF 导进去。
你以为一小时搞定,结果跑了三天三夜。
根因:
向量的写入不仅仅是存进去,还要构建索引(HNSW, IVFFlat 等)。这是一个极耗 CPU 的计算过程。
而且,调用 Embedding API 也是有速率限制的。
解决方案:
- 异步处理:上传文档后,告诉用户 “系统正在学习中,请稍后”。不要让用户在前台等。
- 批量写入:要求开发使用
db.add_documents(chunks)批量上传,而不是一个一个循环传。
六、来来来,总结一下吧
关于向量数据库的选型,赵哥送你三句话:
- 千万别搞过度设计:90% 的 AI 应用,Chroma 或者 pgvector 就足够了。没达到千万级数据量之前,别碰 Milvus,那是给自己找麻烦。
- LangChain 是你的护身符:利用 LangChain 的通用接口,保持代码的灵活性。不要把业务逻辑和具体的数据库绑定太死。
- 算好那笔账:Embedding 是要钱的,存储是要钱的,计算是要钱的 —— 重要的事情重复三遍。在把数据塞进数据库之前,先想清楚哪些数据真正有价值。