langchain-向量数据库学习总结

24 阅读7分钟

向量数据库学习总结


一、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"])  # 参考的文档片段

七、最佳实践

  1. 中文场景:优先选择千帆或bge-small-zh-v1.5模型
  2. 数据规模:<10万用FAISS,>100万用托管服务
  3. 元数据设计:提前规划过滤字段,避免频繁重建索引
  4. 性能优化:使用批量添加(add_texts)而非单条插入
  5. 成本控制:开发阶段用FAISS,生产环境切换到托管服务
  6. 安全隔离:多租户场景使用Pinecone的Namespace或元数据过滤