向量数据库学习总结
一、FAISS 向量库
1. FAISS 向量库创建与保存
这是什么
- FAISS(Facebook AI Similarity Search)是Facebook开源的向量相似度搜索库
- 用于本地存储和检索高维向量数据,无需外部服务依赖
有什么用
- 本地开发环境快速搭建向量检索能力
- 小规模应用(<10万条数据)的最佳选择
- RAG系统的基础组件,为LLM提供知识库检索
示例代码
from langchain_community.vectorstores import FAISS
from langchain_community.embeddings import QianfanEmbeddingsEndpoint
from langchain_core.documents import Document
# 初始化嵌入模型
embedding = QianfanEmbeddingsEndpoint()
# 准备文档数据
documents = [
Document(page_content="我养了一只猫,叫笨笨", metadata={"id": 1}),
Document(page_content="我养了一只狗,叫旺财", metadata={"id": 2}),
]
# 创建 FAISS 向量数据库
db = FAISS.from_documents(documents, embedding)
# 保存到本地
db.save_local("./vector-store/")
2. FAISS 向量库加载与检索
这是什么
- 从本地加载已保存的FAISS索引文件
- 执行相似度搜索并返回匹配结果
有什么用
- 持久化向量数据,避免每次重新计算Embedding
- 生产环境中快速启动检索服务
示例代码
from langchain_community.vectorstores import FAISS
from langchain_community.embeddings import QianfanEmbeddingsEndpoint
embedding = QianfanEmbeddingsEndpoint()
# 从本地加载向量库
db = FAISS.load_local(
"./vector-store/",
embedding,
allow_dangerous_deserialization=True
)
# 执行相似度搜索(返回距离分数)
results = db.similarity_search_with_score("我养了一只猫,叫笨笨")
# 输出:[(Document(...), 0.123), (Document(...), 0.456)]
二、腾讯云 VectorDB
3. 腾讯云VectorDB内置Embedding
这是什么
- 腾讯云托管的向量数据库服务
- 使用腾讯云自带的Embedding模型,无需额外配置
有什么用
- 快速接入云端向量检索能力
- 避免自行维护Embedding服务
- 适合生产环境大规模应用
示例代码
from langchain_community.vectorstores import TencentVectorDB
from langchain_community.vectorstores.tencentvectordb import ConnectionParams
db = TencentVectorDB(
embedding=None, # 使用内置Embedding
connection_params=ConnectionParams(
url=os.environ.get("TC_VECTOR_DB_URL"),
username=os.environ.get("TC_VECTOR_DB_USERNAME"),
key=os.environ.get("TC_VECTOR_DB_KEY"),
timeout=int(os.environ.get("TC_VECTOR_DB_TIMEOUT")),
),
database_name="llmops-test",
collection_name="dataset-builtin",
)
# 添加文本
texts = ["笨笨是一只很喜欢睡觉的猫咪", "我喜欢在夜晚听音乐"]
ids = db.add_texts(texts)
# 相似度搜索(带相关性分数)
results = db.similarity_search_with_relevance_scores("我养了一只猫")
4. - 腾讯云VectorDB外部Embedding
这是什么
- 使用第三方Embedding模型(如OpenAI)与腾讯云VectorDB集成
- 灵活选择最适合业务的Embedding服务
有什么用
- 使用高质量Embedding模型提升检索精度
- 统一管理多种Embedding服务
- 支持自定义Embedding模型
示例代码
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import TencentVectorDB
# 使用OpenAI Embedding
embedding = OpenAIEmbeddings(model="text-embedding-3-small")
db = TencentVectorDB(
embedding=embedding,
connection_params=ConnectionParams(...),
database_name="llmops-test",
collection_name="dataset-external",
)
# 添加文档并检索
ids = db.add_texts(texts)
results = db.similarity_search_with_score("我养了一只猫,叫笨笨")
5. - 腾讯云VectorDB元数据过滤
这是什么
- 在向量相似度检索基础上增加结构化过滤条件
- 支持元数据字段定义(MetaField)和过滤表达式(expr)
有什么用
- 实现精准检索:如只搜索特定用户、特定时间范围的数据
- 多租户数据隔离
- 结合语义和结构化条件的混合检索
示例代码
from langchain_community.vectorstores.tencentvectordb import (
MetaField, META_FIELD_TYPE_UINT64
)
db = TencentVectorDB(
embedding=None,
connection_params=ConnectionParams(...),
meta_fields=[
MetaField(name="page", data_type=META_FIELD_TYPE_UINT64),
]
)
# 添加带元数据的文档
texts = ["笨笨是猫", "旺财是狗", "小飞是鸟"]
metadatas = [{"page": 1}, {"page": 5}, {"page": 10}]
db.add_texts(texts, metadatas)
# 带过滤条件的搜索:只检索 page >= 9 的文档
results = db.similarity_search_with_score(
"宠物",
expr="page>=9" # 过滤表达式
)
三、自定义向量存储
6. 自定义 MemoryVectorStore 实现
这是什么
- 继承LangChain的VectorStore基类实现自定义向量存储
- 完整展示向量数据库的底层工作原理
有什么用
- 理解向量数据库核心机制:Embedding计算、距离度量、相似度排序
- 学习如何实现符合LangChain规范的向量存储
- 为特殊需求定制向量存储方案
示例代码
from langchain_core.vectorstores import VectorStore
from typing import List, Optional, Any
import numpy as np
class MemoryVectorStore(VectorStore):
store: dict = {}
def __init__(self, embedding: Embeddings):
self._embedding = embedding
def add_texts(self, texts: Iterable[str], metadatas: Optional[List[dict]] = None):
# 1. 将文本转换为向量
embeddings = self._embedding.embed_documents(texts)
ids = [str(uuid.uuid4()) for _ in texts]
# 2. 存储向量与元数据
for idx, text in enumerate(texts):
self.store[ids[idx]] = {
"id": ids[idx],
"text": text,
"embedding": embeddings[idx],
"metadata": metadatas[idx] if metadatas else {},
}
return ids
def similarity_search(self, query: str, k: int = 4):
# 1. 计算查询向量
query_embedding = self._embedding.embed_query(query)
# 2. 计算与所有向量的欧几里得距离
result = []
for key, record in self.store.items():
distance = self._euclidean_distance(query_embedding, record["embedding"])
result.append({"distance": distance, **record})
# 3. 排序并返回前k个结果
result = sorted(result, key=lambda x: x["distance"])[:k]
return [Document(page_content=item["text"], metadata=item["metadata"]) for item in result]
@classmethod
def _euclidean_distance(cls, vec1: list, vec2: list) -> float:
"""计算两个向量的欧几里得距离"""
return np.linalg.norm(np.array(vec1) - np.array(vec2))
# 使用示例
db = MemoryVectorStore(embedding=QianfanEmbeddingsEndpoint())
db.add_texts(["笨笨是猫", "旺财是狗"], metadatas=[{"page": 1}, {"page": 2}])
results = db.similarity_search("宠物", k=2)
四、Weaviate 向量数据库
- Weaviate 向量搜索引擎
这是什么
- 开源向量搜索引擎,支持云服务(WCS)和本地部署
- 提供强大的过滤查询能力和GraphQL接口
有什么用
- 构建企业级向量搜索引擎
- 支持复杂的多条件过滤查询
- 与LangChain深度集成,快速搭建RAG系统
示例代码
import weaviate
from langchain_weaviate import WeaviateVectorStore
from weaviate.auth import AuthApiKey
from weaviate.classes.query import Filter
# 创建连接客户端(云服务)
client = weaviate.connect_to_wcs(
cluster_url="xxx.c0.asia-southeast1.gcp.weaviate.cloud",
auth_credentials=AuthApiKey("your-api-key"),
)
# 创建向量库实例
db = WeaviateVectorStore(
client=client,
index_name="MyTest",
text_key="text",
embedding=QianfanEmbeddingsEndpoint(model="embedding-v1"),
)
# 添加数据
ids = db.add_texts(texts, metadatas)
# 带过滤条件的相似度搜索
filters = Filter.by_property("page").greater_or_equal(5)
results = db.similarity_search_with_score("笨笨", filters=filters)
# 转换为Retriever(用于RAG)
retriever = db.as_retriever()
results = retriever.invoke("笨笨")
五、Pinecone 向量数据库
8. Pinecone 托管向量数据库
这是什么
- 完全托管的向量数据库服务,无需运维
- 提供高性能的向量检索API和自动扩缩容能力
有什么用
- 生产环境首选:零运维、高可用、自动扩展
- 支持Namespace实现多租户数据隔离
- 丰富的过滤语法实现精准检索
示例代码
from langchain_pinecone import PineconeVectorStore
from langchain_community.embeddings import HuggingFaceEmbeddings
# 使用HuggingFace中文Embedding模型
embedding = HuggingFaceEmbeddings(
model_name="BAAI/bge-small-zh-v1.5"
)
# 创建向量库实例(指定namespace实现数据隔离)
db = PineconeVectorStore(
index_name="llmops",
embedding=embedding,
namespace="dataset" # 命名空间
)
# 添加文档
db.add_texts(texts, metadatas, namespace="dataset")
# 带过滤条件的检索
results = db.similarity_search_with_relevance_scores(
"我养了一只猫",
filter={"$or": [{"page": 5}, {"account_id": 1}]} # 复杂过滤条件
)
# 删除指定文档
db.delete(["document-id"], namespace="dataset")
六、核心知识点总结
1. 向量数据库选型指南
| 方案 | 适用场景 | 优势 | 劣势 |
|---|---|---|---|
| FAISS | 本地开发、小规模应用 | 免费、快速、无依赖 | 单机、需手动持久化 |
| 腾讯云VectorDB | 国内生产环境 | 低延迟、内置Embedding | 仅国内可用 |
| Pinecone | 国际生产环境 | 零运维、自动扩展 | 需海外访问 |
| Weaviate | 自建搜索引擎 | 开源、功能丰富 | 需运维 |
2. Embedding 模型选择
# 千帆(国内推荐)
QianfanEmbeddingsEndpoint(model="Embedding-V1")
# OpenAI(国际推荐)
OpenAIEmbeddings(model="text-embedding-3-small")
# HuggingFace(免费离线)
HuggingFaceEmbeddings(model_name="BAAI/bge-small-zh-v1.5") # 中文
HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2") # 英文
3. 相似度计算方法
| 方法 | 公式 | 特点 | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| 欧几里得距离 | ` | v1 - v2 | ` | 距离越小越相似 | ||||||
| 余弦相似度 | `cos(θ) = (v1·v2) / ( | v1 | · | v2 | )` | 值越大越相似 | ||||
| 内积 | v1·v2 | 计算最快 |
4. 典型应用流程
# 1. 准备数据
documents = ["文本1", "文本2", "文本3"]
metadatas = [{"source": "A"}, {"source": "B"}, {"source": "C"}]
# 2. 创建向量库
db = VectorStore.from_texts(documents, embedding, metadatas)
# 3. 保存(可选)
db.save_local("./vector-store/")
# 4. 检索
results = db.similarity_search("查询文本", k=3) # 返回前3个最相似的
# 5. 带过滤检索
results = db.similarity_search(
"查询文本",
filter={"source": "A"} # 只检索source=A的文档
)
# 6. 转换为Retriever(用于RAG)
retriever = db.as_retriever(search_kwargs={"k": 2})
results = retriever.invoke("查询文本")
5. RAG系统集成示例
from langchain.chains import RetrievalQA
from langchain_openai import ChatOpenAI
# 创建向量库的Retriever
retriever = db.as_retriever(search_kwargs={"k": 3})
# 创建RAG问答链
qa_chain = RetrievalQA.from_chain_type(
llm=ChatOpenAI(model="gpt-4"),
chain_type="stuff",
retriever=retriever,
return_source_documents=True # 返回参考文档
)
# 执行问答
answer = qa_chain.invoke({"query": "笨笨是什么?"})
print(answer["result"]) # LLM生成的答案
print(answer["source_documents"]) # 参考的文档片段
七、最佳实践
- 中文场景:优先选择千帆或
bge-small-zh-v1.5模型 - 数据规模:<10万用FAISS,>100万用托管服务
- 元数据设计:提前规划过滤字段,避免频繁重建索引
- 性能优化:使用批量添加(
add_texts)而非单条插入 - 成本控制:开发阶段用FAISS,生产环境切换到托管服务
- 安全隔离:多租户场景使用Pinecone的Namespace或元数据过滤