LangChain检索器:高效灵活地访问文档
LangChain框架中的检索器扮演着至关重要的角色,它提供了一个灵活的接口,用于根据非结构化查询返回文档。与向量数据库不同,检索器无需存储文档;其主要功能是从大量数据中检索相关信息。虽然向量数据库可以作为检索器的基础,但存在各种类型的检索器,每种都针对特定用例进行了定制。
学习目标
目录
LangChain中的检索器
检索器接收字符串查询作为输入,并输出一个Document对象的列表。此机制允许应用程序高效地获取相关信息,从而实现与大型数据集或知识库的高级交互。
向量数据库检索器通过利用向量表示来高效地检索文档。它充当向量存储类的轻量级包装器,符合检索器接口并使用诸如相似性搜索和最大边际相关性 (MMR) 等方法。
要从向量数据库创建检索器,请使用.as_retriever
方法。例如,对于基于客户评论的Pinecone向量数据库,我们可以按如下方式进行设置:
from langchain_community.document_loaders import CSVLoader from langchain_community.vectorstores import Pinecone from langchain_openai import OpenAIEmbeddings from langchain_text_splitters import CharacterTextSplitter loader = CSVLoader("customer_reviews.csv") documents = loader.load() text_splitter = CharacterTextSplitter(chunk_size=500, chunk_overlap=50) texts = text_splitter.split_documents(documents) embeddings = OpenAIEmbeddings() vectorstore = Pinecone.from_documents(texts, embeddings) retriever = vectorstore.as_retriever()
我们现在可以使用此检索器查询相关的评论:
docs = retriever.invoke("What do customers think about the battery life?")
默认情况下,检索器使用相似性搜索,但我们可以将MMR指定为搜索类型:
retriever = vectorstore.as_retriever(search_type="mmr")
此外,我们可以传递诸如相似度分数阈值之类的参数,或使用top-k限制结果数量:
retriever = vectorstore.as_retriever(search_kwargs={"k": 2, "score_threshold": 0.6})
输出:
使用向量数据库作为检索器可以通过确保高效访问相关信息来增强文档检索。
MultiQueryRetriever通过解决常见限制(例如查询措辞的变化和次优嵌入)来增强基于距离的向量数据库检索。使用大型语言模型 (LLM) 自动化提示调整,可以从不同角度为给定的用户输入生成多个查询。此过程允许为每个查询检索相关文档,并将结果组合起来以产生更丰富的潜在文档集。
为了演示MultiQueryRetriever,让我们使用来自CSV文件的商品描述创建一个向量存储:
from langchain_community.document_loaders import CSVLoader from langchain_community.vectorstores import FAISS from langchain_openai import OpenAIEmbeddings from langchain_text_splitters import CharacterTextSplitter # 加载产品描述 loader = CSVLoader("product_descriptions.csv") data = loader.load() # 将文本分割成块 text_splitter = CharacterTextSplitter(chunk_size=300, chunk_overlap=50) documents = text_splitter.split_documents(data) # 创建向量存储 embeddings = OpenAIEmbeddings() vectordb = FAISS.from_documents(documents, embeddings)
要使用MultiQueryRetriever,请指定用于查询生成的LLM:
from langchain.retrievers.multi_query import MultiQueryRetriever from langchain_openai import ChatOpenAI question = "What features do customers value in smartphones?" llm = ChatOpenAI(temperature=0) retriever_from_llm = MultiQueryRetriever.from_llm( retriever=vectordb.as_retriever(), llm=llm ) unique_docs = retriever_from_llm.invoke(question) len(unique_docs) # 检索到的唯一文档数量
输出:
MultiQueryRetriever生成多个查询,增强了检索到的文档的多样性和相关性。
要调整生成的查询,您可以创建一个自定义PromptTemplate和一个输出解析器:
from langchain_core.output_parsers import BaseOutputParser from langchain_core.prompts import PromptTemplate from typing import List # 自定义输出解析器 class LineListOutputParser(BaseOutputParser[List[str]]): def parse(self, text: str) -> List[str]: return list(filter(None, text.strip().split("\n"))) output_parser = LineListOutputParser() # 用于查询生成的自定义提示 QUERY_PROMPT = PromptTemplate( input_variables=["question"], template="""Generate five different versions of the question: {question}""" ) llm_chain = QUERY_PROMPT | llm | output_parser # 初始化检索器 retriever = MultiQueryRetriever( retriever=vectordb.as_retriever(), llm_chain=llm_chain, parser_key="lines" ) unique_docs = retriever.invoke("What features do customers value in smartphones?") len(unique_docs) # 检索到的唯一文档数量
输出
使用MultiQueryRetriever可以实现更有效的检索过程,确保基于用户查询获得多样化和全面的结果。
从大型文档集合中检索相关信息可能具有挑战性,尤其是在数据摄取时不知道用户将提出的特定查询时。通常,有价值的见解隐藏在冗长的文档中,导致对语言模型 (LLM) 的调用效率低下且成本高昂,同时提供的响应不如理想。上下文压缩通过改进检索过程来解决此问题,确保仅根据用户的查询返回相关信息。此压缩包括减少单个文档的内容和过滤掉不相关的文档。
上下文压缩检索器通过将基本检索器与文档压缩器集成来运行。此方法不会完整返回文档,而是根据查询提供的上下文压缩文档。此压缩包括减少单个文档的内容和过滤掉不相关的文档。
from langchain_community.document_loaders import TextLoader from langchain_community.vectorstores import FAISS from langchain_openai import OpenAIEmbeddings from langchain_text_splitters import CharacterTextSplitter # 加载并分割文章 documents = TextLoader("climate_change_policy.txt").load() text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) texts = text_splitter.split_documents(documents) # 初始化向量存储检索器 retriever = FAISS.from_documents(texts, OpenAIEmbeddings()).as_retriever()
docs = retriever.invoke("What actions are being proposed to combat climate change?")
from langchain.retrievers import ContextualCompressionRetriever from langchain.retrievers.document_compressors import LLMChainExtractor from langchain_openai import OpenAI llm = OpenAI(temperature=0) compressor = LLMChainExtractor.from_llm(llm) compression_retriever = ContextualCompressionRetriever( base_compressor=compressor, base_retriever=retriever ) # 执行压缩检索 compressed_docs = compression_retriever.invoke("What actions are being proposed to combat climate change?")
查看压缩结果:ContextualCompressionRetriever处理初始文档并仅提取与查询相关的相关信息,从而优化响应。
检索器在许多LLM应用程序中都是必不可少的。它的任务是根据用户查询获取相关文档。这些文档被格式化为LLM的提示,使其能够生成适当的响应。
要创建自定义检索器,请扩展BaseRetriever类并实现以下方法:
方法 | 描述 | 必需/可选 |
---|---|---|
_get_relevant_documents |
检索与查询相关的文档。 | 必需 |
_aget_relevant_documents |
异步实现,用于原生支持。 | 可选 |
继承自BaseRetriever会为您的检索器提供标准的Runnable功能。
这是一个简单检索器的示例:
from typing import List from langchain_core.documents import Document from langchain_core.retrievers import BaseRetriever class ToyRetriever(BaseRetriever): """一个简单的检索器,它返回包含用户查询的前k个文档。""" documents: List[Document] k: int def _get_relevant_documents(self, query: str) -> List[Document]: matching_documents = [doc for doc in self.documents if query.lower() in doc.page_content.lower()] return matching_documents[:self.k] # 示例用法 documents = [ Document("Dogs are great companions.", {"type": "dog"}), Document("Cats are independent pets.", {"type": "cat"}), ] retriever = ToyRetriever(documents=documents, k=1) result = retriever.invoke("dog") print(result[0].page_content)
输出
此实现提供了一种基于用户输入检索文档的简单方法,说明了LangChain中自定义检索器的核心功能。
在LangChain框架中,检索器是强大的工具,可以有效地访问各种文档类型和用例中的相关信息。通过理解和实现不同的检索器类型(例如向量存储检索器、MultiQueryRetriever和上下文压缩检索器),开发人员可以根据其应用程序的特定需求定制文档检索。
每种检索器类型都具有独特的优势,从使用MultiQueryRetriever处理复杂查询到使用上下文压缩优化响应。此外,创建自定义检索器可以提供更大的灵活性,以适应内置选项可能无法满足的特殊要求。掌握这些检索技术使开发人员能够构建更有效且更具响应性的应用程序,从而充分利用语言模型和大型数据集的潜力。
Q1. LangChain中检索器的主要作用是什么? A1. 检索器的主要作用是根据查询获取相关文档。这有助于应用程序有效地访问大型数据集中的必要信息,而无需自行存储文档。
Q2. 检索器与向量数据库有何不同? A2. 向量数据库用于以允许基于相似性的检索的方式存储文档,而检索器是用于根据查询检索文档的接口。尽管向量数据库可以是检索器的一部分,但检索器的任务侧重于获取相关信息。
Q3. 什么是MultiQueryRetriever,它是如何工作的? A3. MultiQueryRetriever通过使用语言模型创建查询的多个变体来改进搜索结果。此方法捕获可能与不同措辞的问题相关的更广泛的文档范围,从而增强检索信息的丰富性。
Q4. 为什么上下文压缩很重要? A4. 上下文压缩通过将文档内容减少到仅相关部分并过滤掉不相关信息来优化检索结果。这在大型集合中尤其有用,因为完整文档可能包含无关的细节,从而节省资源并提供更集中的响应。
Q5. 设置MultiQueryRetriever的要求是什么? A5. 要设置MultiQueryRetriever,您需要一个用于文档存储的向量数据库、一个用于生成多个查询视角的语言模型 (LLM),以及可选的自定义提示模板以进一步优化查询生成。
以上是3种朗链猎犬的先进策略的详细内容。更多信息请关注PHP中文网其他相关文章!