在 LangChain 中,检索器(Retrievers) 是用于从外部数据源(如文档、数据库或网页)中获取与用户查询相关内容的组件。它们是构建基于外部知识的问答系统、语义搜索或上下文增强应用的核心模块。检索器通过将用户查询与存储的数据进行匹配,返回相关文档或片段,供语言模型(LLM)进一步处理。
以下是对 LangChain 检索器的详细介绍,涵盖其定义、类型、工作原理、实现方式、应用场景、代码示例、优化建议以及与生态系统的结合。
1. 什么是 LangChain 的检索器?
检索器是 LangChain 中负责信息检索的模块,通常与 索引(Indexes) 模块(如向量存储、文档加载器)结合使用。它的核心功能是:
- 输入:接收用户查询(通常是文本)。
- 处理:根据查询从数据源中检索相关内容。
- 输出:返回一组相关文档或文本片段(通常是
Document对象列表)。
检索器在以下场景中扮演关键角色:
- 问答系统:从文档或知识库中检索答案的上下文。
- 语义搜索:根据查询的语义返回相关结果。
- 上下文增强:为语言模型提供外部知识,解决其知识局限。
检索器通常与 向量存储(Vector Stores) 配合,通过嵌入模型(Embedding Models)将查询和文档转为向量,基于相似性进行检索。
2. 检索器的工作原理
检索器的工作流程可以分为以下步骤:
- 查询嵌入:将用户查询通过嵌入模型(如
OpenAIEmbeddings)转为向量表示。 - 相似性搜索:在向量存储中查找与查询向量最相似的文档向量。
- 文档返回:返回匹配的文档(包含内容、元数据等)。
- 后处理(可选):对检索结果进行排序、过滤或重新排名。
检索器的核心依赖:
- 嵌入模型:将文本转为向量(如
OpenAIEmbeddings,HuggingFaceEmbeddings)。 - 向量存储:存储文档向量(如 Chroma、FAISS、Pinecone)。
- 相似性度量:如余弦相似度、欧几里得距离。
3. LangChain 检索器的类型
LangChain 提供了多种检索器,适用于不同场景。以下是主要类型的详细介绍:
(1) VectorStoreRetriever
- 功能:基于向量存储的检索器,通过嵌入向量进行语义搜索。
- 特点:
- 使用嵌入模型将查询和文档转为向量。
- 支持多种向量存储(如 Chroma、FAISS、Pinecone)。
- 默认使用余弦相似度排序结果。
- 适用场景:
- 语义搜索。
- 基于文档的问答系统。
- 支持的向量存储(需单独安装):
langchain-chromalangchain-faisslangchain-pineconelangchain-weaviatelangchain-qdrant
- 示例:
from langchain_community.vectorstores import Chroma from langchain_openai import OpenAIEmbeddings from langchain_core.documents import Document # 创建文档 docs = [ Document(page_content="量子计算是一种基于量子力学的计算范式。", metadata={"source": "doc1"}), Document(page_content="人工智能是模拟人类智能的技术。", metadata={"source": "doc2"}) ] # 初始化向量存储 embeddings = OpenAIEmbeddings(api_key="your-openai-key") vectorstore = Chroma.from_documents(docs, embeddings) # 创建检索器 retriever = vectorstore.as_retriever(search_kwargs={"k": 1}) # 返回 1 个结果 # 检索 results = retriever.invoke("量子计算是什么?") print(results) - 输出:
[Document(page_content='量子计算是一种基于量子力学的计算范式。', metadata={'source': 'doc1'})]
(2) BM25Retriever
- 功能:基于 BM25 算法的关键词检索器,适合基于词频的搜索。
- 特点:
- 不依赖嵌入模型,使用词频和逆文档频率(TF-IDF)计算相关性。
- 适合关键词匹配场景,计算成本低。
- 不支持语义搜索,效果依赖文本的字面匹配。
- 适用场景:
- 传统搜索场景。
- 关键词驱动的问答。
- 安装:
pip install rank_bm25 - 示例:
from langchain_community.retrievers import BM25Retriever from langchain_core.documents import Document docs = [ Document(page_content="量子计算是一种基于量子力学的计算范式。"), Document(page_content="人工智能是模拟人类智能的技术。") ] retriever = BM25Retriever.from_documents(docs) retriever.k = 1 # 返回 1 个结果 results = retriever.invoke("量子计算") print(results) - 输出:
[Document(page_content='量子计算是一种基于量子力学的计算范式。')]
(3) TFIDFRetriever
- 功能:基于 TF-IDF(词频-逆文档频率)的检索器,类似 BM25。
- 特点:
- 使用 TF-IDF 向量表示文档和查询。
- 适合关键词匹配,性能优于 BM25 在某些场景。
- 不支持语义搜索。
- 适用场景:
- 文本搜索。
- 关键词提取。
- 安装:
pip install scikit-learn - 示例:
from langchain_community.retrievers import TFIDFRetriever from langchain_core.documents import Document docs = [ Document(page_content="量子计算是一种基于量子力学的计算范式。"), Document(page_content="人工智能是模拟人类智能的技术。") ] retriever = TFIDFRetriever.from_documents(docs) results = retriever.invoke("量子计算") print(results)
(4) MultiQueryRetriever
- 功能:通过生成多个查询变体增强检索效果,结合向量存储。
- 特点:
- 使用语言模型生成查询的多种表达方式。
- 从向量存储中检索所有变体的结果并合并。
- 提高召回率,适合复杂查询。
- 适用场景:
- 查询表达不明确或需要覆盖多种语义。
- 提高检索的全面性。
- 示例:
from langchain.retrievers.multi_query import MultiQueryRetriever from langchain_openai import ChatOpenAI, OpenAIEmbeddings from langchain_community.vectorstores import Chroma from langchain_core.documents import Document docs = [ Document(page_content="量子计算基于量子力学。"), Document(page_content="人工智能模拟人类智能。") ] embeddings = OpenAIEmbeddings(api_key="your-openai-key") vectorstore = Chroma.from_documents(docs, embeddings) llm = ChatOpenAI(api_key="your-openai-key") retriever = MultiQueryRetriever.from_llm( retriever=vectorstore.as_retriever(), llm=llm ) results = retriever.invoke("量子计算是什么?") print(results) - 输出:可能返回多个相关文档。
(5) ContextualCompressionRetriever
- 功能:对检索结果进行压缩,提取最相关的内容。
- 特点:
- 使用语言模型对检索到的文档进行重新排序或精炼。
- 减少无关内容,提高结果质量。
- 增加计算开销,但提升精准度。
- 适用场景:
- 文档内容冗长,需要提取关键信息。
- 提高问答系统的答案质量。
- 示例:
from langchain.retrievers import ContextualCompressionRetriever from langchain.retrievers.document_compressors import LLMChainExtractor from langchain_openai import ChatOpenAI, OpenAIEmbeddings from langchain_community.vectorstores import Chroma from langchain_core.documents import Document docs = [ Document(page_content="量子计算是一种基于量子力学的计算范式,涉及量子比特和量子纠缠。"), Document(page_content="人工智能是模拟人类智能的技术,包括机器学习和深度学习。") ] embeddings = OpenAIEmbeddings(api_key="your-openai-key") vectorstore = Chroma.from_documents(docs, embeddings) llm = ChatOpenAI(api_key="your-openai-key") compressor = LLMChainExtractor.from_llm(llm) retriever = ContextualCompressionRetriever( base_compressor=compressor, base_retriever=vectorstore.as_retriever() ) results = retriever.invoke("量子计算的核心是什么?") print(results) - 输出:
[Document(page_content='量子计算是一种基于量子力学的计算范式,涉及量子比特和量子纠缠。')]
(6) EnsembleRetriever
- 功能:结合多种检索器(如 BM25 和向量存储),融合结果。
- 特点:
- 结合关键词搜索和语义搜索的优点。
- 支持加权融合,调整不同检索器的权重。
- 提高召回率和精准度。
- 适用场景:
- 需要综合关键词和语义的搜索。
- 复杂查询场景。
- 示例:
from langchain.retrievers import EnsembleRetriever from langchain_community.retrievers import BM25Retriever from langchain_community.vectorstores import Chroma from langchain_openai import OpenAIEmbeddings from langchain_core.documents import Document docs = [ Document(page_content="量子计算基于量子力学。"), Document(page_content="人工智能模拟人类智能。") ] bm25_retriever = BM25Retriever.from_documents(docs) bm25_retriever.k = 1 embeddings = OpenAIEmbeddings(api_key="your-openai-key") vectorstore = Chroma.from_documents(docs, embeddings) vector_retriever = vectorstore.as_retriever(search_kwargs={"k": 1}) ensemble_retriever = EnsembleRetriever( retrievers=[bm25_retriever, vector_retriever], weights=[0.5, 0.5] ) results = ensemble_retriever.invoke("量子计算") print(results)
(7) SelfQueryRetriever
- 功能:使用语言模型解析查询,提取结构化条件(如元数据过滤)并执行检索。
- 特点:
- 支持复杂查询(如“2023年发布的量子计算文档”)。
- 自动解析查询中的过滤条件。
- 需要向量存储支持元数据查询。
- 适用场景:
- 带元数据过滤的检索。
- 结构化知识库查询。
- 示例:
from langchain.retrievers.self_query import SelfQueryRetriever from langchain_openai import ChatOpenAI, OpenAIEmbeddings from langchain_community.vectorstores import Chroma from langchain_core.documents import Document docs = [ Document(page_content="量子计算简介", metadata={"year": 2023, "category": "tech"}), Document(page_content="人工智能简介", metadata={"year": 2022, "category": "tech"}) ] embeddings = OpenAIEmbeddings(api_key="your-openai-key") vectorstore = Chroma.from_documents(docs, embeddings) llm = ChatOpenAI(api_key="your-openai-key") retriever = SelfQueryRetriever.from_llm( llm=llm, vectorstore=vectorstore, document_contents="技术文档", metadata_field_info=[ {"name": "year", "type": "int", "description": "发布年份"}, {"name": "category", "type": "str", "description": "类别"} ] ) results = retriever.invoke("2023年的技术文档") print(results)
(8) WebResearchRetriever
- 功能:从网页中检索相关内容,结合搜索引擎和向量存储。
- 特点:
.ConcurrentHashMap - 使用外部搜索引擎(如 Google)获取网页。- 将网页内容存储到向量存储并检索。
- 适合动态、实时信息检索。
- 适用场景:
- 需要从互联网获取最新信息的问答。
- 研究或知识收集。
- 安装:
pip install google-api-python-client - 示例:
from langchain.retrievers.web_research import WebResearchRetriever from langchain_openai import ChatOpenAI, OpenAIEmbeddings from langchain_community.vectorstores import Chroma from langchain_community.utilities import GoogleSearchAPIWrapper llm = ChatOpenAI(api_key="your-openai-key") embeddings = OpenAIEmbeddings(api_key="your-openai-key") vectorstore = Chroma(embedding_function=embeddings) search = GoogleSearchAPIWrapper(google_api_key="your-google-key", google_cse_id="your-cse-id") retriever = WebResearchRetriever.from_llm( vectorstore=vectorstore, llm=llm, search=search ) results = retriever.invoke("量子计算的最新进展") print(results)
(9) Custom Retriever
- 功能:开发者可以自定义检索逻辑,适配特定数据源或算法。
- 特点:
- 继承
BaseRetriever类,实现get_relevant_documents方法。 - 支持任意数据源(如数据库、API)。
- 继承
- 适用场景:
- 特定领域的数据源(如内部数据库)。
- 自定义检索算法。
- 示例:
from langchain_core.retrievers import BaseRetriever from langchain_core.documents import Document class CustomRetriever(BaseRetriever): def _get_relevant_documents(self, query: str, **kwargs): # 自定义逻辑(如查询数据库) return [Document(page_content=f"自定义结果 for {query}")] retriever = CustomRetriever() results = retriever.invoke("量子计算") print(results)
4. 检索器的应用场景
检索器在以下场景中广泛应用:
- 基于文档的问答:
- 从公司文档、PDF 或知识库中检索答案。
- 示例:
RetrievalQA链结合VectorStoreRetriever。
- 语义搜索:
- 根据查询的语义返回相关内容。
- 示例:使用
VectorStoreRetriever实现产品搜索。
- 上下文增强:
- 为语言模型提供外部知识,解决知识截止问题。
- 示例:结合
WebResearchRetriever获取最新信息。
- 结构化查询:
- 从带元数据的文档中检索特定内容。
- 示例:
SelfQueryRetriever按年份过滤文档。
- 混合搜索:
- 结合关键词和语义搜索。
- 示例:
EnsembleRetriever融合 BM25 和向量存储。
- 实时信息检索:
- 从网页或 API 获取动态数据。
- 示例:
WebResearchRetriever检索新闻。
5. 检索器的实现与代码示例
综合示例:RetrievalQA 链
以下是一个基于 VectorStoreRetriever 的问答系统:
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_community.vectorstores import Chroma
from langchain_core.documents import Document
from langchain.chains import RetrievalQA
from langchain_core.prompts import PromptTemplate
# 创建文档
docs = [
Document(page_content="量子计算是一种基于量子力学的计算范式。", metadata={"source": "doc1"}),
Document(page_content="人工智能是模拟人类智能的技术。", metadata={"source": "doc2"})
]
# 初始化向量存储和检索器
embeddings = OpenAIEmbeddings(api_key="your-openai-key")
vectorstore = Chroma.from_documents(docs, embeddings)
retriever = vectorstore.as_retriever(search_kwargs={"k": 1})
# 初始化语言模型
llm = ChatOpenAI(api_key="your-openai-key")
# 创建 RetrievalQA 链
prompt = PromptTemplate.from_template("根据以下上下文回答问题:{context}\n问题:{question}")
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=retriever,
return_source_documents=True,
chain_type_kwargs={"prompt": prompt}
)
# 查询
result = qa_chain.invoke({"query": "量子计算是什么?"})
print(result["result"])
print("来源:", result["source_documents"])
输出:
量子计算是一种基于量子力学的计算范式。
来源:[Document(page_content='量子计算是一种基于量子力学的计算范式。', metadata={'source': 'doc1'})]
6. 检索器的优化建议
(1) 提高检索质量
- 嵌入模型选择:
- 使用高质量嵌入模型(如
text-embedding-ada-002或SentenceTransformers)。 - 针对特定领域微调嵌入模型。
- 使用高质量嵌入模型(如
- 文档分割:
- 使用
RecursiveCharacterTextSplitter分割长文档,保留语义。
from langchain.text_splitter import RecursiveCharacterTextSplitter splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200) chunks = splitter.split_documents(docs) - 使用
- 查询优化:
- 使用
MultiQueryRetriever生成查询变体。 - 规范化查询(如小写化、去噪)。
- 使用
(2) 提高性能
- 向量存储优化:
- 使用高效的向量存储(如 FAISS 适合本地,Pinecone 适合云)。
- 索引优化(如 FAISS 的 HNSW 索引)。
- 缓存检索结果:
- 结合 LangChain 的缓存机制。
from langchain.globals import set_llm_cache from langchain.cache import SQLiteCache set_llm_cache(SQLiteCache(database_path="cache.db")) - 批量检索:
- 使用
batch方法处理多个查询。
results = retriever.batch(["query1", "query2"]) - 使用
(3) 后处理
- 重新排名:
- 使用
ContextualCompressionRetriever精炼结果。
- 使用
- 过滤:
- 根据元数据(如日期、类别)过滤结果。
retriever = vectorstore.as_retriever(search_kwargs={"filter": {"year": 2023}})
(4) 监控与调试
- 回调:
- 使用回调记录检索器的输入输出。
from langchain_core.callbacks import BaseCallbackHandler class RetrieverCallback(BaseCallbackHandler): def on_retriever_start(self, serialized, query, **kwargs): print(f"检索查询:{query}") def on_retriever_end(self, documents, **kwargs): print(f"检索结果:{documents}") - LangSmith:
- 分析检索器的召回率和精准度。
from langsmith import Client retriever.invoke(query, config={"callbacks": [Client(api_key="your-langsmith-key")]})
7. 注意事项
- 检索质量:
- 嵌入模型的质量直接影响检索效果。
- 关键词检索(BM25/TFIDF)和语义检索(向量存储)各有优劣,需根据场景选择。
- 数据规模:
- 大规模文档需要高效的向量存储(如 Pinecone、Weaviate)。
- 定期更新索引以反映数据变化。
- 隐私与安全:
- 文档可能包含敏感信息,需加密存储或限制访问。
- 避免将用户查询存储在公共向量存储中。
- 成本管理:
- 云向量存储(如 Pinecone)可能产生费用,需优化查询频率。
- 嵌入模型的 API 调用也需监控。
- 调试:
- 检查检索结果是否相关,必要时调整嵌入模型或分割策略。
- 使用
LangSmith分析检索器的性能。
8. 与其他模块的结合
- 链(Chains):
- 结合
RetrievalQA或ConversationalRetrievalChain实现问答。
from langchain.chains import ConversationalRetrievalChain from langchain.memory import ConversationBufferMemory memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True) qa_chain = ConversationalRetrievalChain.from_llm(llm, retriever, memory=memory) - 结合
- 回调(Callbacks):
- 监控检索过程。
- 缓存(Cache):
- 缓存检索结果,减少重复查询。
- 代理(Agents):
- 结合
WebResearchRetriever为代理提供动态知识。
- 结合
- LangSmith:
- 分析检索器的性能和命中率。
9. 学习资源
- 官方文档:https://python.langchain.com/docs/modules/retrievers
- GitHub 示例:https://github.com/langchain-ai/langchain
- LangSmith:用于调试检索器(https://smith.langchain.com)。
- 社区教程:LangChain 官方博客、YouTube 视频。
10. 总结
- 定义:检索器用于从外部数据源获取与查询相关的内容,是问答和搜索系统的核心。
- 类型:
VectorStoreRetriever:语义搜索。BM25Retriever/TFIDFRetriever:关键词搜索。MultiQueryRetriever:多查询增强。ContextualCompressionRetriever:结果压缩。EnsembleRetriever:混合搜索。SelfQueryRetriever:结构化查询。WebResearchRetriever:网页检索。- 自定义检索器:特定需求。
- 工作原理:查询嵌入 → 相似性搜索 → 文档返回。
- 应用场景:问答、语义搜索、上下文增强、结构化查询。
- 优化点:嵌入模型、文档分割、缓存、后处理、监控。
- 注意事项:质量、规模、隐私、成本、调试。
1214

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



