纲要
- 向量数据库基础
- 在 RAG 系统中的核心位置
- 与传统关系型数据库的本质区别
- LangChain 向量数据库接口
- 统一方法:
add_documents、delete、similarity_search、similarity_search_by_vector - 常用向量数据库概览:
Chroma、FAISS、Pinecone、Milvus等
- 统一方法:
- 基本操作实战
- 文档添加(支持自定义 ID)
- 文档删除(按 ID)
- 文本相似性搜索与向量搜索
- 高级检索技巧
- 最大边际相关性(MMR)搜索
- 混合搜索(关键词 + 向量)概述
- 完整可运行代码:使用
FakeEmbeddings与内存Chroma向量库模拟增删查与 MMR
引言
在 RAG(检索增强生成)系统中,原始文档经过加载、切片和向量化后,需要一个高效的存储和检索容器,这便是向量数据库。向量数据库不仅承载了所有外部知识的向量表示,更承担着语义搜索的核心任务:根据查询向量快速定位最相似的文档片段。LangChain 通过统一的向量存储接口(VectorStore)封装了多种数据库实现,使得开发者可以像操作普通数据集合一样执行增、删、查,同时提供了最大边际相关性(MMR)搜索、混合搜索等高级检索能力。本文将通过可运行的代码示例,系统性地介绍向量数据库的核心操作与进阶用法。
向量数据库基础
向量数据库与传统关系型数据库(如 MySQL)在设计哲学和数据模型上存在根本性差异,具体对比维度如下:
| 维度 | 关系型数据库 | 向量数据库 |
|---|---|---|
| 存储内容 | 结构化数据(表格、字段) | 高维向量数组(浮点数序列) |
| 查询方式 | 精确匹配(SQL where、join) | 相似度搜索(余弦距离、欧氏距离、内积) |
| 典型场景 | 事务处理、用户管理、报表统计 | 语义检索、图像搜索、推荐系统 |
| 数据模式 | 固定 Schema,需预先定义表结构 | 灵活,无固定 Schema 要求 |
在 RAG 工作流中,向量数据库处于索引阶段与查询阶段的交汇点:它存储所有知识片段的向量嵌入,并在接收到用户查询时,将查询向量与库内向量进行相似度计算,返回 Top‑K 个最相关的文档片段。
LangChain 向量数据库接口
LangChain 在 langchain_core.vectorstores 中定义了 VectorStore 基类,所有向量数据库实现均需遵循该接口规范。核心方法包括:
add_documents(documents, ids=None, **kwargs):批量添加Document对象,可选自定义 ID。delete(ids, **kwargs):按 ID 列表删除文档。similarity_search(query, k=4, **kwargs):给定文本查询,返回最相似的k个文档。similarity_search_by_vector(embedding, k=4, **kwargs):直接传入向量进行相似度检索。max_marginal_relevance_search(query, k=4, fetch_k=20, lambda_mult=0.5, **kwargs):执行 MMR 搜索,平衡相关性与多样性。
主流向量数据库实现及适用场景如下:
| 数据库 | 部署方式 | 适用场景 |
|---|---|---|
Chroma | 内存/本地持久化 | 开发测试、轻量级原型 |
FAISS | 本地内存 | 高性能本地检索,适合小规模数据 |
Pinecone | 云端托管 | 生产环境,需要自动扩展和高可用 |
Milvus | 本地/云端分布式 | 大规模向量数据,企业级应用 |
Weaviate | 本地/云端 | 内置混合搜索,支持 GraphQL |
基本操作实战
本章节使用 FakeEmbeddings 模拟向量嵌入模型(输出维度固定为 128),配合 Chroma 内存向量库,演示完整的增、删、查操作流程,无需任何外部 API Key 或网络连接。
环境依赖安装:
pip install langchain langchain-core langchain-community chromadb
版本说明:本文示例基于
langchain>=0.3.0,langchain-community>=0.3.0。
文档添加
创建 Document 对象集合,并通过 add_documents 方法写入向量库,同时指定自定义 ID。
from langchain_community.embeddings.fake import FakeEmbeddings
from langchain_community.vectorstores import Chroma
from langchain_core.documents import Document
# 初始化模拟嵌入模型(维度 128)
embeddings = FakeEmbeddings(size=128)
# 准备文档数据
docs = [
Document(page_content="智能温控水杯支持手机 App 远程控温。", metadata={"source": "product"}),
Document(page_content="产品续航 48 小时,采用 316 不锈钢内胆。", metadata={"source": "product"}),
Document(page_content="充电时请使用 5V/2A 适配器。", metadata={"source": "product"}),
]
# 创建内存向量库并添加文档
vectorstore = Chroma(embedding_function=embeddings, collection_name="demo")
ids = ["doc_1", "doc_2", "doc_3"]
vectorstore.add_documents(docs, ids=ids)
print("已添加文档数:", vectorstore._collection.count())
删除文档
通过 delete 方法按 ID 移除指定文档。
vectorstore.delete(ids=["doc_2"])
print("删除后文档数:", vectorstore._collection.count()) # 输出 2
相似性搜索
支持两种搜索方式:直接传入文本(内部自动调用嵌入模型)或预先计算查询向量。
方式一:文本相似性搜索
results = vectorstore.similarity_search("怎么充电?", k=1)
for doc in results:
print(doc.page_content) # 应返回充电相关文档
方式二:向量相似性搜索
query_vector = embeddings.embed_query("怎么充电?")
results = vectorstore.similarity_search_by_vector(query_vector, k=1)
print(results[0].page_content)
两种方式在语义上等价,区别在于方式二允许复用已计算好的向量,适合批量查询或性能敏感场景。
高级检索:MMR 搜索
最大边际相关性(Maximal Marginal Relevance,MMR)是一种在信息检索中广泛使用的重排序算法,其核心思想是在保证检索结果与查询条件相关的前提下,引入多样性约束,避免返回结果集中于某一子主题。
MMR 的评分公式为:
MMR = arg max D i ∈ R ∖ S [ λ ⋅ sim ( D i , Q ) − ( 1 − λ ) ⋅ max D j ∈ S sim ( D i , D j ) ] \text{MMR} = \arg\max_{D_i \in R \setminus S} \left[ \lambda \cdot \text{sim}(D_i, Q) - (1 - \lambda) \cdot \max_{D_j \in S} \text{sim}(D_i, D_j) \right] MMR=argDi∈R∖Smax[λ⋅sim(Di,Q)−(1−λ)⋅Dj∈Smaxsim(Di,Dj)]
其中
λ
\lambda
λ 为多样性系数(lambda_mult),值越小结果多样性越高。
Chroma 通过 max_marginal_relevance_search 方法原生支持 MMR。
# 添加更多内容相近的文档以观测 MMR 效果
additional_docs = [
Document(page_content="水杯过热保护功能详解", metadata={"source": "manual"}),
Document(page_content="如何正确清洗保温杯内胆", metadata={"source": "manual"}),
Document(page_content="电池续航测试及充电注意事项", metadata={"source": "manual"}),
]
vectorstore.add_documents(additional_docs)
# MMR 搜索:取 3 条结果,lambda_mult=0.5(值越小越注重多样性)
mmr_results = vectorstore.max_marginal_relevance_search(
"充电", k=3, lambda_mult=0.5
)
for doc in mmr_results:
print(doc.page_content)
在输出中可以看到,MMR 不会仅返回三篇全部围绕“充电”的文档,而是可能混合“过热保护”或“清洗内胆”等内容,从而提供更全面的上下文。
混合搜索简介
混合搜索(Hybrid Search)结合了关键词检索(如 BM25 算法)和向量语义检索两种策略,在特定场景下能同时发挥关键词的精确匹配能力和向量的语义泛化能力。典型的混合搜索流程为:
- 关键词检索:在文档的元数据或原始文本上执行 BM25/TF‑IDF 匹配,召回候选集。
- 向量检索:在候选集上执行相似度搜索,得到最终排序。
Pinecone、Weaviate 等数据库提供了开箱即用的混合搜索支持,LangChain 通过 HybridSearchRetriever 等封装类提供统一接入。由于混合搜索通常依赖外部服务(如 Pinecone 的索引配置),本文不作展开运行,但需明确其核心价值:在精确实体匹配和语义泛化之间取得最佳平衡。
完整可运行代码整合
以下脚本集成了文档增删、相似性搜索和 MMR 搜索的全部核心操作,使用内存向量库,无需任何外部依赖或 API Key。
from langchain_community.embeddings.fake import FakeEmbeddings
from langchain_community.vectorstores import Chroma
from langchain_core.documents import Document
embeddings = FakeEmbeddings(size=128)
# 初始文档集合
docs = [
Document(page_content="智能温控水杯支持手机 App 远程控温。", metadata={"type": "feature"}),
Document(page_content="产品续航 48 小时,采用 316 不锈钢内胆。", metadata={"type": "feature"}),
Document(page_content="充电时请使用 5V/2A 适配器。", metadata={"type": "caution"}),
Document(page_content="请勿将杯体浸入水中清洗。", metadata={"type": "caution"}),
Document(page_content="可通过 App 调节温度范围 40~100°C。", metadata={"type": "feature"}),
]
vectorstore = Chroma(embedding_function=embeddings, collection_name="cup")
ids = ["d1", "d2", "d3", "d4", "d5"]
vectorstore.add_documents(docs, ids=ids)
# 删除一条记录
vectorstore.delete(ids=["d4"])
print("剩余文档数:", vectorstore._collection.count())
# 文本相似性搜索
print("\n--- 相似性搜索:充电 ---")
for doc in vectorstore.similarity_search("如何充电?", k=2):
print(doc.page_content)
# MMR 搜索(多样性优先)
print("\n--- MMR 搜索:充电(多样性优先) ---")
for doc in vectorstore.max_marginal_relevance_search("充电", k=2, lambda_mult=0.3):
print(doc.page_content)
API 速览
| 方法 | 所属库 | 签名 | 说明 |
|---|---|---|---|
add_documents | langchain_core.vectorstores.VectorStore | add_documents(documents: List[Document], ids: Optional[List[str]] = None, **kwargs) -> List[str] | 批量添加文档,返回添加的 ID 列表 |
delete | langchain_core.vectorstores.VectorStore | delete(ids: Optional[List[str]] = None, **kwargs) -> Optional[bool] | 按 ID 删除文档 |
similarity_search | langchain_core.vectorstores.VectorStore | similarity_search(query: str, k: int = 4, **kwargs) -> List[Document] | 文本查询,返回相似文档 |
similarity_search_by_vector | langchain_core.vectorstores.VectorStore | similarity_search_by_vector(embedding: List[float], k: int = 4, **kwargs) -> List[Document] | 向量查询,返回相似文档 |
max_marginal_relevance_search | langchain_community.vectorstores.Chroma | max_marginal_relevance_search(query: str, k: int = 4, fetch_k: int = 20, lambda_mult: float = 0.5, **kwargs) -> List[Document] | MMR 检索,平衡相关性与多样性 |
参考文档
官方文档:
参考链接:
总结
向量数据库是 RAG 应用中连接知识存储与语义检索的核心基础设施。LangChain 通过统一的 VectorStore 抽象接口,抹平了不同向量数据库之间的底层差异,使开发者可以快速切换本地开发环境(Chroma、FAISS)与生产级服务(Pinecone、Milvus)。
掌握 add_documents、delete、similarity_search 等基本操作后,进一步选用 MMR 或混合搜索策略,能够有效提升检索结果的多样性与准确性,从而为下游生成模型提供更高质量的上文信息。
206



被折叠的 条评论
为什么被折叠?



