Skip to main content

使用检索器进行问答 (QA using a Retriever)

这个示例展示了如何在索引上进行问答。

from langchain.chains import RetrievalQA  
from langchain.document_loaders import TextLoader
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.llms import OpenAI
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import Chroma

loader = TextLoader("../../state_of_the_union.txt")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)

embeddings = OpenAIEmbeddings()
docsearch = Chroma.from_documents(texts, embeddings)

qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=docsearch.as_retriever())

query = "What did the president say about Ketanji Brown Jackson"
qa.run(query)

链类型

您可以轻松地指定不同的链类型来加载和使用检索器链。有两种加载不同链类型的方法。首先,您可以在from_chain_type方法中指定链类型参数。这样可以传入您想要使用的链类型的名称。例如,在下面的示例中,我们将链类型更改为map_reduce

qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="map_reduce", retriever=docsearch.as_retriever())  

query = "What did the president say about Ketanji Brown Jackson"
qa.run(query)

上述方法允许您非常简单地更改链类型,但对该链类型的参数没有太多的灵活性。如果您想要控制这些参数,您可以直接加载链(就像在这个笔记本中所做的那样),然后将其直接传递给RetrievalQA链的combine_documents_chain参数。例如:

from langchain.chains.question_answering import load_qa_chain  
qa_chain = load_qa_chain(OpenAI(temperature=0), chain_type="stuff")
qa = RetrievalQA(combine_documents_chain=qa_chain, retriever=docsearch.as_retriever())

query = "What did the president say about Ketanji Brown Jackson"
qa.run(query)

自定义提示

您可以传入自定义提示来进行问答。这些提示与您可以传递给基本问答链的提示相同。

from langchain.prompts import PromptTemplate  
prompt_template = """Use the following pieces of context to answer the question at the end. If you don't know the answer, just say that you don't know, don't try to make up an answer.

{context}

Question: {question}
Answer in Italian:"""
PROMPT = PromptTemplate(
template=prompt_template, input_variables=["context", "question"]
)

chain_type_kwargs = {"prompt": PROMPT}
qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=docsearch.as_retriever(), chain_type_kwargs=chain_type_kwargs)

query = "What did the president say about Ketanji Brown Jackson"
qa.run(query)

Vectorstore检索器选项

您可以根据特定任务调整从向量存储中检索文档的方式。

有两种主要的检索文档相关查询的方法-相似性搜索和最大边际相关搜索(MMR搜索)。相似性搜索是默认的,但您可以通过添加search_type参数来使用MMR搜索:

docsearch.as_retriever(search_type="mmr")  

您还可以通过将特定的搜索参数通过检索器传递给搜索函数来修改搜索,使用search_kwargs关键字参数。

  • k定义返回的文档数量;默认为4。
  • score_threshold允许您为由检索器返回的文档设置最低相关性阈值,如果您使用的是“similarity_score_threshold”搜索类型。
  • fetch_k确定要传递给MMR算法的文档数量;默认为20。
  • lambda_mult控制MMR算法返回结果的多样性,1表示最小多样性,0表示最大多样性。默认为0.5。
  • filter允许您根据文档的元数据定义筛选器,以确定应检索哪些文档。如果向量存储不存储任何元数据,则此选项无效。

以下是如何使用这些参数的一些示例:

# 检索更多具有更高多样性的文档-如果您的数据集有许多相似的文档,则这很有用
docsearch.as_retriever(search_type="mmr", search_kwargs={'k': 6, 'lambda_mult': 0.25})

# 获取更多供MMR算法考虑的文档,但只返回前5个
docsearch.as_retriever(search_type="mmr", search_kwargs={'k': 5, 'fetch_k': 50})

# 仅检索具有超过某个阈值的相关性分数的文档
docsearch.as_retriever(search_type="similarity_score_threshold", search_kwargs={'score_threshold': 0.8})

# 仅从数据集中获取最相似的单个文档
docsearch.as_retriever(search_kwargs={'k': 1})

# 使用过滤器仅检索特定论文的文档
docsearch.as_retriever(search_kwargs={'filter': {'paper_title':'GPT-4 Technical Report'}})

返回源文档

此外,我们可以通过在构建链时指定一个可选参数来返回用于回答问题的源文档。

qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=docsearch.as_retriever(search_type="mmr", search_kwargs={'fetch_k': 30}), return_source_documents=True)  

query = "What did the president say about Ketanji Brown Jackson"
result = qa({"query": query})

result["result"]
result["source_documents"]

或者,如果我们的文档具有“source”元数据键,我们可以使用RetrievalQAWithSourceChain来引用我们的来源:

docsearch = Chroma.from_texts(texts, embeddings, metadatas=[{"source": f"{i}-pl"} for i in range(len(texts))])  

from langchain.chains import RetrievalQAWithSourcesChain
from langchain import OpenAI

chain = RetrievalQAWithSourcesChain.from_chain_type(OpenAI(temperature=0), chain_type="stuff", retriever=docsearch.as_retriever())

chain({"question": "What did the president say about Justice Breyer"}, return_only_outputs=True)