LangChain-08-VectorStores模块

模块概览

职责与定位

VectorStores模块是LangChain生态中知识检索的核心基础设施,提供向量数据库的统一抽象接口。向量存储是RAG(检索增强生成)应用的核心组件,负责存储文档嵌入向量并支持相似度搜索,使LLM能够检索相关知识。

核心职责:

  • 定义向量存储统一接口 (VectorStore 抽象基类)
  • 支持文档添加和删除 (CRUD操作)
  • 提供多种相似度搜索能力 (余弦、欧氏、内积)
  • 支持MMR(最大边际相关性)检索算法
  • 集成多种向量数据库实现(Chroma、Qdrant、Pinecone、FAISS等)
  • 提供Retriever接口转换,无缝对接LCEL链式调用
  • 支持同步和异步API

设计模式:

  • 抽象工厂模式: VectorStore 定义统一接口,各数据库实现具体工厂方法
  • 适配器模式: VectorStoreRetriever 将向量存储适配为 BaseRetriever
  • 策略模式: 支持 similaritymmrsimilarity_score_threshold 等多种检索策略

输入输出

输入:

  • 文档列表: 需要索引的 Document 对象或文本列表
  • 嵌入模型: Embeddings 接口实现,用于向量化
  • 查询: 文本查询或向量
  • 检索参数: k(返回数量)、filter(元数据过滤)、fetch_k(MMR候选数)等

输出:

  • 文档列表: list[Document],按相似度降序排列
  • 文档+分数: list[tuple[Document, float]],分数范围[0,1]
  • 文档ID: 添加/删除操作返回的ID列表

上下游依赖

上游依赖:

  • langchain_core.embeddings.Embeddings: 文本向量化接口
    • embed_documents(): 批量嵌入文档
    • embed_query(): 嵌入查询文本
  • langchain_core.documents.Document: 文档数据结构
  • langchain_core.runnables: 异步执行支持
  • 具体向量数据库SDK (chromadb、qdrant-client、pinecone-client等)

下游被依赖:

  • langchain_core.retrievers.BaseRetriever: 检索器抽象,通过 as_retriever() 转换
  • RAG应用链: 作为知识源提供上下文
  • 问答系统: 提供相关文档检索
  • 文档管理系统: 实现语义搜索
  • Agents: 作为工具访问知识库

与其他模块交互:

graph LR
    A[Embeddings模块] -->|向量化| B[VectorStores模块]
    C[Documents模块] -->|数据结构| B
    B -->|适配为| D[Retrievers模块]
    B -->|支撑| E[RAG Chain]
    B -->|集成| F[Agents工具]
    G[向量数据库SDK] -.->|底层存储| B

系统整体架构图

三层架构设计

VectorStores模块采用经典的三层架构设计:

flowchart TB
    subgraph Application["应用层 - 上层使用方"]
        RAG[RAG Chain<br/>检索增强生成]
        AGENT[Agent Tools<br/>智能体工具]
        QA[QA System<br/>问答系统]
    end

    subgraph Interface["接口层 - 适配器"]
        RETRIEVER[VectorStoreRetriever<br/>检索器适配器]
        RUNNABLE[Runnable接口<br/>LCEL链式调用]
    end

    subgraph Core["核心层 - VectorStore抽象"]
        VECTORSTORE[VectorStore ABC<br/>抽象基类]

        subgraph CoreOps["核心操作接口"]
            ADD[add_documents/add_texts<br/>文档索引]
            SEARCH[similarity_search<br/>相似度检索]
            SEARCHSCORE[similarity_search_with_score<br/>带分数检索]
            MMR[max_marginal_relevance_search<br/>MMR多样性检索]
            DELETE[delete/get_by_ids<br/>CRUD操作]
        end

        subgraph Factory["工厂方法"]
            FROM_DOCS[from_documents<br/>文档工厂]
            FROM_TEXTS[from_texts<br/>文本工厂]
            AS_RETRIEVER[as_retriever<br/>转换为Retriever]
        end
    end

    subgraph Impl["实现层 - 具体数据库"]
        INMEM[InMemoryVectorStore<br/>内存实现]
        CHROMA[Chroma<br/>ChromaDB]
        QDRANT[Qdrant<br/>Qdrant]
        PINECONE[Pinecone<br/>Pinecone]
        FAISS[FAISS<br/>Facebook AI Similarity Search]
        WEAVIATE[Weaviate<br/>混合搜索]
    end

    subgraph Infra["基础设施层"]
        EMB[Embeddings<br/>向量化接口]
        DOC[Document<br/>文档结构]
        UTILS[utils<br/>相似度计算/MMR算法]
        DB[(向量数据库<br/>Chroma/Qdrant/Pinecone)]
    end

    RAG --> RETRIEVER
    AGENT --> RETRIEVER
    QA --> RETRIEVER

    RETRIEVER --> VECTORSTORE
    RUNNABLE -.-> RETRIEVER

    VECTORSTORE --> CoreOps
    VECTORSTORE --> Factory

    CoreOps --> Impl
    Factory --> Impl

    VECTORSTORE <|.. INMEM
    VECTORSTORE <|.. CHROMA
    VECTORSTORE <|.. QDRANT
    VECTORSTORE <|.. PINECONE
    VECTORSTORE <|.. FAISS
    VECTORSTORE <|.. WEAVIATE

    Impl --> EMB
    Impl --> DOC
    Impl --> UTILS
    Impl --> DB

    style VECTORSTORE fill:#e1f5ff,stroke:#0066cc,stroke-width:3px
    style RETRIEVER fill:#e8f5e9,stroke:#00cc66,stroke-width:2px
    style CoreOps fill:#fff4e1,stroke:#ff9900,stroke-width:2px
    style Impl fill:#f3e5f5,stroke:#9c27b0,stroke-width:2px

架构层次说明

1. 应用层 (Application Layer)

职责: 业务逻辑层,消费向量存储服务

  • RAG Chain: 检索增强生成,将检索结果注入提示词
  • Agent Tools: 智能体工具,通过检索获取决策依据
  • QA System: 问答系统,基于检索文档生成答案

交互方式: 通过 VectorStoreRetriever 统一接口访问

2. 接口层 (Interface Layer)

职责: 适配器模式,统一上层调用方式

  • VectorStoreRetriever:
    • 继承 BaseRetriever,实现 _get_relevant_documents()
    • 支持三种检索策略: similaritymmrsimilarity_score_threshold
    • 实现 Runnable 协议,支持 invoke()/ainvoke() 链式调用
    • 集成 CallbackManager,支持LangSmith追踪

关键代码:

class VectorStoreRetriever(BaseRetriever):
    vectorstore: VectorStore  # 持有向量存储实例
    search_type: str = "similarity"  # 检索策略
    search_kwargs: dict = {}  # 检索参数

    def _get_relevant_documents(self, query: str) -> list[Document]:
        if self.search_type == "similarity":
            return self.vectorstore.similarity_search(query, **self.search_kwargs)
        elif self.search_type == "mmr":
            return self.vectorstore.max_marginal_relevance_search(query, **self.search_kwargs)
        # ...

3. 核心层 (Core Layer)

职责: 定义向量存储抽象接口

VectorStore抽象基类:

  • 定义所有子类必须实现的接口 (抽象方法)
  • 提供默认实现 (模板方法模式)
  • 定义工厂方法创建实例

核心操作接口:

操作类别 方法 说明
索引 add_texts() 添加文本列表,自动生成ID
add_documents() 添加Document对象
检索 similarity_search() 相似度搜索,返回文档
similarity_search_with_score() 返回文档+距离分数
similarity_search_with_relevance_scores() 返回文档+相关性分数[0,1]
similarity_search_by_vector() 直接使用向量搜索
max_marginal_relevance_search() MMR搜索,平衡相关性与多样性
管理 delete() 删除文档
get_by_ids() 根据ID获取文档
异步 aadd_texts()/asimilarity_search() 所有操作的异步版本

工厂方法:

  • from_texts(): 类方法,从文本列表创建向量存储
  • from_documents(): 类方法,从Document列表创建
  • as_retriever(): 实例方法,转换为Retriever

4. 实现层 (Implementation Layer)

职责: 具体向量数据库集成

各实现必须提供:

  1. add_texts()add_documents() 实现
  2. similarity_search() 实现 (抽象方法)
  3. from_texts() 类方法实现 (抽象方法)
  4. _select_relevance_score_fn() 相关性评分函数

实现对比:

实现 存储方式 特点 适用场景
InMemoryVectorStore 内存字典 零配置,使用numpy计算余弦相似度 测试/Demo/小数据集
Chroma SQLite(本地)或客户端-服务器 易用,支持持久化 原型开发,小中规模应用
FAISS 本地文件 极高性能,Facebook出品 大规模本地应用
Qdrant Qdrant服务器 功能丰富,可扩展 生产环境,大规模应用
Pinecone 云托管SaaS 全托管,免运维 无运维需求的云应用
Weaviate Weaviate服务器 支持混合搜索(向量+关键词) 需要结合BM25的场景

5. 基础设施层 (Infrastructure Layer)

职责: 提供底层能力

  • Embeddings: 文本向量化,见 LangChain-03-LanguageModels模块.md
  • Document: 文档数据结构,包含 page_contentmetadataid
  • utils:
    • _cosine_similarity(): 余弦相似度计算
    • maximal_marginal_relevance(): MMR算法实现
  • 向量数据库: 第三方数据库服务

边界条件与约束

并发安全:

  • InMemoryVectorStore: 非线程安全,使用内存字典
  • Chroma/Qdrant等: 依赖底层数据库的并发控制

数据一致性:

  • 添加操作: 原子性取决于底层数据库
  • 删除操作: 部分实现支持批量删除,部分逐个删除
  • ID冲突: 大多数实现采用upsert语义,ID重复时覆盖

性能约束:

  • k 参数上限: 通常建议 ≤ 100
  • fetch_k 参数: MMR搜索时建议 fetch_k = 2-5倍 k
  • 批量添加: Chroma等实现自动分批,单批次通常≤1000

异常处理:

  • 嵌入模型失败: 传播异常给调用方
  • 数据库连接失败: 抛出运行时异常
  • 无结果: 返回空列表,不抛异常

演进与兼容性

向后兼容:

  • add_texts()add_documents() 互相委托,实现其一即可
  • 老版本实现可能不支持 get_by_ids()
  • 异步方法默认通过 run_in_executor() 包装同步方法

版本要求:

  • langchain-core >= 0.2.11: 支持 get_by_ids()
  • langchain-core >= 0.1.0: VectorStore接口稳定

架构说明

核心操作

添加文档:

vectorstore.add_documents([doc1, doc2, doc3])
  • 自动计算文档嵌入
  • 存储到向量数据库
  • 返回文档ID列表

相似度搜索:

docs = vectorstore.similarity_search("查询文本", k=4)
  • 将查询文本转换为向量
  • 在向量空间中查找最近邻
  • 返回最相似的k个文档

MMR搜索:

docs = vectorstore.max_marginal_relevance_search("查询", k=4, fetch_k=20)
  • 先获取fetch_k个候选文档
  • 使用MMR算法平衡相关性和多样性
  • 返回k个文档

向量数据库选择

数据库 特点 适用场景
Chroma 本地存储,易用 原型开发,小规模应用
FAISS 极高性能,本地 大规模本地应用
Qdrant 功能丰富,可扩展 生产环境,大规模应用
Pinecone 全托管云服务 无运维需求
Weaviate 混合搜索 需要结合关键词搜索

核心数据结构

classDiagram
    class VectorStore {
        <<abstract>>
        +embeddings: Embeddings
        +add_documents(documents) list[str]
        +add_texts(texts, metadatas) list[str]
        +similarity_search(query, k) list[Document]
        +similarity_search_with_score(query, k) list[tuple]
        +max_marginal_relevance_search(query, k, fetch_k) list[Document]
        +delete(ids) bool
        +as_retriever() VectorStoreRetriever
    }

    class Document {
        +page_content: str
        +metadata: dict
        +id: str|None
    }

    class VectorStoreRetriever {
        +vectorstore: VectorStore
        +search_type: str
        +search_kwargs: dict
        +invoke(input) list[Document]
    }

    VectorStore --> Document : returns
    VectorStore --> VectorStoreRetriever : creates

数据结构说明

VectorStore关键方法

方法 说明
add_documents 添加Document对象列表
add_texts 添加文本列表(自动创建Document)
similarity_search 相似度搜索,返回文档
similarity_search_with_score 返回文档和相似度分数
max_marginal_relevance_search MMR搜索,平衡相关性和多样性
delete 删除指定ID的文档
as_retriever 转换为Retriever对象

VectorStoreRetriever配置

参数 类型 说明
vectorstore VectorStore 底层向量存储
search_type str “similarity”|“mmr”|“similarity_score_threshold”
search_kwargs dict 搜索参数,如k、fetch_k、score_threshold

核心API详解

API-1: from_documents创建

基本信息

  • 名称: from_documents
  • 类方法签名: @classmethod def from_documents(cls, documents: list[Document], embedding: Embeddings, **kwargs) -> VectorStore
  • 幂等性: 非幂等(多次调用创建多个实例)

功能说明

从文档列表创建向量存储,自动计算嵌入并索引。

请求结构体

documents: list[Document]  # 文档列表
embedding: Embeddings  # 嵌入模型
**kwargs  # 特定数据库的配置

入口函数与关键代码

@classmethod
def from_documents(
    cls,
    documents: list[Document],
    embedding: Embeddings,
    **kwargs,
) -> VectorStore:
    """从文档创建向量存储

    Args:
        documents: 文档列表
        embedding: 嵌入模型
        **kwargs: 数据库特定配置

    Returns:
        VectorStore实例
    """
    # 1) 提取文本和元数据
    texts = [doc.page_content for doc in documents]
    metadatas = [doc.metadata for doc in documents]

    # 2) 调用from_texts
    return cls.from_texts(texts, embedding, metadatas=metadatas, **kwargs)

使用示例:

from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain_core.documents import Document

# 准备文档
documents = [
    Document(page_content="LangChain是一个LLM应用框架", metadata={"source": "doc1"}),
    Document(page_content="向量数据库用于存储嵌入向量", metadata={"source": "doc2"}),
    Document(page_content="RAG结合检索和生成", metadata={"source": "doc3"}),
]

# 创建向量存储
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(
    documents=documents,
    embedding=embeddings,
    persist_directory="./chroma_db"
)

基本信息

  • 名称: similarity_search
  • 方法签名: def similarity_search(self, query: str, k: int = 4, **kwargs) -> list[Document]
  • 幂等性: 幂等

功能说明

根据查询文本进行相似度搜索,返回最相关的k个文档。

请求结构体

query: str  # 查询文本
k: int  # 返回结果数量,默认4
**kwargs  # 额外搜索参数(如filter)

响应结构体

list[Document]  # 文档列表,按相似度降序排列

入口函数与关键代码

def similarity_search(
    self,
    query: str,
    k: int = 4,
    **kwargs,
) -> list[Document]:
    """相似度搜索

    Args:
        query: 查询文本
        k: 返回文档数量
        **kwargs: 额外参数

    Returns:
        最相似的k个文档
    """
    # 1) 将查询文本转换为嵌入向量
    query_embedding = self.embeddings.embed_query(query)

    # 2) 在向量空间中搜索
    docs_and_scores = self._similarity_search_with_relevance_scores(
        query_embedding,
        k=k,
        **kwargs
    )

    # 3) 提取文档(不带分数)
    return [doc for doc, score in docs_and_scores]

def _similarity_search_with_relevance_scores(
    self,
    query_embedding: list[float],
    k: int,
    **kwargs,
) -> list[tuple[Document, float]]:
    """底层向量搜索(子类实现)

    Returns:
        (Document, similarity_score)列表
    """
    # 子类实现,调用具体数据库API
    pass

使用示例:

# 基本搜索
docs = vectorstore.similarity_search("什么是RAG?", k=3)
for doc in docs:
    print(doc.page_content)
# "RAG结合检索和生成"
# "向量数据库用于存储嵌入向量"
# ...

# 带过滤器搜索
docs = vectorstore.similarity_search(
    "LangChain",
    k=2,
    filter={"source": "doc1"}  # 仅搜索source=doc1的文档
)

# 带分数搜索
docs_with_scores = vectorstore.similarity_search_with_score("RAG", k=3)
for doc, score in docs_with_scores:
    print(f"[{score:.2f}] {doc.page_content}")
# [0.95] RAG结合检索和生成
# [0.72] 向量数据库...

基本信息

  • 名称: max_marginal_relevance_search
  • 方法签名: def max_marginal_relevance_search(self, query: str, k: int = 4, fetch_k: int = 20, lambda_mult: float = 0.5, **kwargs) -> list[Document]
  • 幂等性: 幂等

功能说明

MMR(最大边际相关性)搜索,平衡相关性和多样性。

请求结构体

query: str  # 查询文本
k: int  # 最终返回文档数量
fetch_k: int  # 候选文档数量
lambda_mult: float  # 相关性权重(0-1),1表示纯相关性,0表示纯多样性

入口函数与关键代码

def max_marginal_relevance_search(
    self,
    query: str,
    k: int = 4,
    fetch_k: int = 20,
    lambda_mult: float = 0.5,
    **kwargs,
) -> list[Document]:
    """MMR搜索

    Args:
        query: 查询文本
        k: 返回文档数量
        fetch_k: 候选文档数量(>= k)
        lambda_mult: 相关性权重,0.5表示相关性和多样性各占50%

    Returns:
        k个文档,平衡相关性和多样性
    """
    # 1) 计算查询嵌入
    query_embedding = self.embeddings.embed_query(query)

    # 2) 获取fetch_k个候选文档
    candidate_docs = self._similarity_search_with_relevance_scores(
        query_embedding,
        k=fetch_k,
        **kwargs
    )

    # 3) 计算候选文档的嵌入
    candidate_embeddings = [
        self.embeddings.embed_query(doc.page_content)
        for doc, _ in candidate_docs
    ]

    # 4) MMR算法选择k个文档
    selected_indices = maximal_marginal_relevance(
        query_embedding,
        candidate_embeddings,
        lambda_mult=lambda_mult,
        k=k
    )

    # 5) 返回选中的文档
    return [candidate_docs[i][0] for i in selected_indices]

def maximal_marginal_relevance(
    query_embedding: list[float],
    embedding_list: list[list[float]],
    lambda_mult: float,
    k: int
) -> list[int]:
    """MMR算法实现

    选择文档时平衡:
    - 与查询的相关性
    - 与已选文档的差异性
    """
    selected = []
    remaining = list(range(len(embedding_list)))

    # 计算所有文档与查询的相似度
    similarities_to_query = cosine_similarity([query_embedding], embedding_list)[0]

    for _ in range(k):
        if not remaining:
            break

        mmr_scores = []
        for idx in remaining:
            # 相关性分数
            relevance = similarities_to_query[idx]

            # 多样性分数(与已选文档的最大相似度)
            if selected:
                max_sim_to_selected = max(
                    cosine_similarity([embedding_list[idx]], [embedding_list[s]])[0][0]
                    for s in selected
                )
            else:
                max_sim_to_selected = 0

            # MMR分数
            mmr = lambda_mult * relevance - (1 - lambda_mult) * max_sim_to_selected
            mmr_scores.append(mmr)

        # 选择MMR分数最高的文档
        best_idx = remaining[mmr_scores.index(max(mmr_scores))]
        selected.append(best_idx)
        remaining.remove(best_idx)

    return selected

使用示例:

# MMR搜索
docs = vectorstore.max_marginal_relevance_search(
    query="LangChain框架",
    k=4,
    fetch_k=20,
    lambda_mult=0.7  # 70%相关性,30%多样性
)

# 对比:
# similarity_search会返回4个非常相似的文档
# MMR会返回4个相关但内容多样的文档

# 极端情况:
# lambda_mult=1.0: 等同于similarity_search
docs_pure_similarity = vectorstore.max_marginal_relevance_search(
    "query", k=4, lambda_mult=1.0
)

# lambda_mult=0.0: 纯多样性(不推荐)
docs_pure_diversity = vectorstore.max_marginal_relevance_search(
    "query", k=4, lambda_mult=0.0
)

API-4: as_retriever

基本信息

  • 名称: as_retriever
  • 方法签名: def as_retriever(self, **kwargs) -> VectorStoreRetriever
  • 幂等性: 幂等

功能说明

将向量存储转换为Retriever对象,用于LCEL链式调用。

请求结构体

search_type: str  # "similarity"|"mmr"|"similarity_score_threshold"
search_kwargs: dict  # 搜索参数

入口函数与关键代码

def as_retriever(self, **kwargs) -> VectorStoreRetriever:
    """转换为Retriever

    Args:
        search_type: 搜索类型
        search_kwargs: 搜索参数

    Returns:
        VectorStoreRetriever实例
    """
    return VectorStoreRetriever(vectorstore=self, **kwargs)

class VectorStoreRetriever(BaseRetriever):
    """向量存储检索器"""

    vectorstore: VectorStore
    search_type: str = "similarity"
    search_kwargs: dict = Field(default_factory=dict)

    def _get_relevant_documents(self, query: str) -> list[Document]:
        """检索相关文档"""
        if self.search_type == "similarity":
            return self.vectorstore.similarity_search(query, **self.search_kwargs)
        elif self.search_type == "mmr":
            return self.vectorstore.max_marginal_relevance_search(query, **self.search_kwargs)
        elif self.search_type == "similarity_score_threshold":
            docs_and_scores = self.vectorstore.similarity_search_with_relevance_scores(
                query, **self.search_kwargs
            )
            # 过滤低于阈值的文档
            score_threshold = self.search_kwargs.get("score_threshold", 0.0)
            return [doc for doc, score in docs_and_scores if score >= score_threshold]

使用示例:

# 创建Retriever
retriever = vectorstore.as_retriever(
    search_type="mmr",
    search_kwargs={"k": 4, "fetch_k": 20}
)

# 在链中使用
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser

chain = (
    {"context": retriever, "question": RunnablePassthrough()}
    | prompt
    | model
    | StrOutputParser()
)

answer = chain.invoke("什么是RAG?")

# 相似度阈值检索
retriever = vectorstore.as_retriever(
    search_type="similarity_score_threshold",
    search_kwargs={"score_threshold": 0.8, "k": 5}
)
# 仅返回相似度>=0.8的文档

典型使用场景

场景1: RAG问答系统

from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser

# 1) 准备文档
documents = [
    Document(page_content="LangChain是一个用于构建LLM应用的框架..."),
    Document(page_content="RAG将检索和生成结合..."),
    # ... 更多文档
]

# 2) 创建向量存储
embeddings = OpenAIEmbeddings()
vectorstore = Chroma.from_documents(documents, embeddings)

# 3) 创建检索器
retriever = vectorstore.as_retriever(search_kwargs={"k": 3})

# 4) 构建RAG链
template = """基于以下上下文回答问题:

上下文: {context}

问题: {question}

答案:"""

prompt = ChatPromptTemplate.from_template(template)
model = ChatOpenAI()

def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)

chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()}
    | prompt
    | model
    | StrOutputParser()
)

# 5) 使用
answer = chain.invoke("什么是RAG?")
print(answer)

场景2: 文档更新管理

# 添加新文档
new_docs = [
    Document(page_content="新功能介绍...", metadata={"version": "2.0", "doc_id": "doc_123"})
]
doc_ids = vectorstore.add_documents(new_docs)

# 删除旧文档
vectorstore.delete(doc_ids)

# 批量更新
# 1) 删除旧版本
old_ids = vectorstore.get_ids(filter={"version": "1.0"})
vectorstore.delete(old_ids)

# 2) 添加新版本
new_docs = load_updated_documents()
vectorstore.add_documents(new_docs)

场景3: 多向量存储组合

# 场景: 不同类型文档使用不同的向量存储
technical_docs = Chroma.from_documents(technical_documents, embeddings, collection_name="technical")
marketing_docs = Chroma.from_documents(marketing_documents, embeddings, collection_name="marketing")

# 创建多检索器
tech_retriever = technical_docs.as_retriever(search_kwargs={"k": 2})
marketing_retriever = marketing_docs.as_retriever(search_kwargs={"k": 2})

# 组合检索
from langchain.retrievers import MergerRetriever

combined_retriever = MergerRetriever(retrievers=[tech_retriever, marketing_retriever])

# 使用
docs = combined_retriever.invoke("产品特性")
# 返回技术文档2篇 + 营销文档2篇

最佳实践

1. 选择合适的向量数据库

# 原型开发: Chroma(本地,零配置)
from langchain_chroma import Chroma
vectorstore = Chroma.from_documents(docs, embeddings)

# 生产环境(中小规模): Qdrant
from langchain_qdrant import Qdrant
vectorstore = Qdrant.from_documents(
    docs,
    embeddings,
    url="http://localhost:6333",
    collection_name="my_collection"
)

# 生产环境(大规模): Pinecone
from langchain_pinecone import Pinecone
vectorstore = Pinecone.from_documents(
    docs,
    embeddings,
    index_name="my-index"
)

2. 优化搜索性能

# 推荐: 使用适当的k值
# k太小: 可能遗漏相关信息
# k太大: 增加成本和噪音
retriever = vectorstore.as_retriever(search_kwargs={"k": 4})  # 平衡点

# 推荐: MMR用于需要多样性的场景
retriever = vectorstore.as_retriever(
    search_type="mmr",
    search_kwargs={"k": 4, "fetch_k": 20, "lambda_mult": 0.7}
)

# 推荐: 使用相似度阈值过滤低质量结果
retriever = vectorstore.as_retriever(
    search_type="similarity_score_threshold",
    search_kwargs={"score_threshold": 0.75}
)

3. 元数据过滤

# 推荐: 使用元数据缩小搜索范围
docs = vectorstore.similarity_search(
    "查询",
    k=4,
    filter={"source": "official_docs", "version": "v2"}
)

# 在retriever中使用
retriever = vectorstore.as_retriever(
    search_kwargs={
        "k": 4,
        "filter": {"department": "engineering"}
    }
)