本文将通过索引进行问答。
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()
# 构建embeddings,构建文档相关性
docsearch = Chroma.from_documents(texts, embeddings)
# 创建问答chain
qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=docsearch.as_retriever())
query = "总统对科坦吉·布朗·杰克逊说了些什么"
qa.run(query)
结果:
总统说,她是全国顶尖的法律专家之一、前私人执业顶级诉讼律师、前联邦公设辩护律师,出身于公立学校教育工作者和警察家庭。他还表示,她是共识的缔造者,得到了广泛的支持,从警察兄弟会到民主党和共和党任命的前法官。
我们轻松指定要在 RetrievalQA chain
中加载和使用的不同chain type
。有关这些类型的更详细示例,请参考。
有两种方法可以加载不同的Chain type
。
首先,您可以在 from_chain_type
方法中指定chain type
参数。这允许您传入要使用的chain type
的名称。例如,下面我们将链类型更改为map_reduce
。
qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="map_reduce", retriever=docsearch.as_retriever())
query = "总统对科坦吉·布朗·杰克逊说了些什么"
qa.run(query)
结果:
总统表示,科坦吉·布朗·杰克逊法官是我国最顶尖的法律专家之一、前私人执业顶级诉讼律师和前联邦公设辩护人,出身于公立学校教育工作者和警察家庭,是共识的缔造者,受到了广泛的支持。从警察兄弟会到民主党和共和党任命的前法官,都提供了一系列支持。
上述方法允许您简单地更改 chain_type
,但它并没有为该链类型的参数提供大量的灵活性。
如果您想控制这些参数,您可以直接加载链(就像您在本笔记本中所做的那样),然后使用 combine_documents_chain
参数将其直接传递到 RetrievalQA 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 = "总统对科坦吉·布朗·杰克逊说了些什么"
qa.run(query)
也就是说,可以在加载
chain
的时候,就指定chain type
,而不是在创建RetrievalQA时。
结果:
总统表示,科坦吉·布朗·杰克逊是美国顶尖的法律专家之一、前私人执业顶级诉讼律师、前联邦公设辩护律师,出身于公立学校教育工作者和警察家庭。他还表示,她是共识的缔造者,得到了从警察兄弟会到民主党和共和党任命的前法官的广泛支持。
您可以传入自定义prompt
来进行问答。这些提示与您可以传递到基本问答链的提示相同。
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 prompt
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 = 总统对科坦吉·布朗·杰克逊说了些什么"
qa.run(query)
结果:
总统表示,科坦吉·布朗·杰克逊是美国最重要的法律人才之一,他将继承布雷耶大法官的卓越表现,并获得了广泛的支持,从警察兄弟会到民主党和共和党提名的前法官。
此外,我们可以通过在构建链时指定可选参数来返回用于回答问题的源文档。
# 构建chain时,指定return_source_documents参数:返回document的source
qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=docsearch.as_retriever(), return_source_documents=True)
query = "What did the president say about Ketanji Brown Jackson"
result = qa({"query": query})
result["result"]
结果:
" The president said that Ketanji Brown Jackson is one of the nation's top legal minds, a former top litigator in private practice and a former federal public defender from a family of public school educators and police officers, and that she has received a broad range of support from the Fraternal Order of Police to former judges appointed by Democrats and Republicans."
# 打印源文档
result["source_documents"]
[Document(page_content='Tonight. I call on the Senate to: Pass the Freedom to Vote Act. Pass the John Lewis Voting Rights Act. And while you’re at it, pass the Disclose Act so Americans can know who is funding our elections. \n\nTonight, I’d like to honor someone who has dedicated his life to serve this country: Justice Stephen Breyer—an Army veteran, Constitutional scholar, and retiring Justice of the United States Supreme Court. Justice Breyer, thank you for your service. \n\nOne of the most serious constitutional responsibilities a President has is nominating someone to serve on the United States Supreme Court. \n\nAnd I did that 4 days ago, when I nominated Circuit Court of Appeals Judge Ketanji Brown Jackson. One of our nation’s top legal minds, who will continue Justice Breyer’s legacy of excellence.', lookup_str='', metadata={'source': '../../state_of_the_union.txt'}, lookup_index=0),
Document(page_content='A former top litigator in private practice. A former federal public defender. And from a family of public school educators and police officers. A consensus builder. Since she’s been nominated, she’s received a broad range of support—from the Fraternal Order of Police to former judges appointed by Democrats and Republicans. \n\nAnd if we are to advance liberty and justice, we need to secure the Border and fix the immigration system. \n\nWe can do both. At our border, we’ve installed new technology like cutting-edge scanners to better detect drug smuggling. \n\nWe’ve set up joint patrols with Mexico and Guatemala to catch more human traffickers. \n\nWe’re putting in place dedicated immigration judges so families fleeing persecution and violence can have their cases heard faster. \n\nWe’re securing commitments and supporting partners in South and Central America to host more refugees and secure their own borders.', lookup_str='', metadata={'source': '../../state_of_the_union.txt'}, lookup_index=0),
Document(page_content='And for our LGBTQ+ Americans, let’s finally get the bipartisan Equality Act to my desk. The onslaught of state laws targeting transgender Americans and their families is wrong. \n\nAs I said last year, especially to our younger transgender Americans, I will always have your back as your President, so you can be yourself and reach your God-given potential. \n\nWhile it often appears that we never agree, that isn’t true. I signed 80 bipartisan bills into law last year. From preventing government shutdowns to protecting Asian-Americans from still-too-common hate crimes to reforming military justice. \n\nAnd soon, we’ll strengthen the Violence Against Women Act that I first wrote three decades ago. It is important for us to show the nation that we can come together and do big things. \n\nSo tonight I’m offering a Unity Agenda for the Nation. Four big things we can do together. \n\nFirst, beat the opioid epidemic.', lookup_str='', metadata={'source': '../../state_of_the_union.txt'}, lookup_index=0),
Document(page_content='Tonight, I’m announcing a crackdown on these companies overcharging American businesses and consumers. \n\nAnd as Wall Street firms take over more nursing homes, quality in those homes has gone down and costs have gone up. \n\nThat ends on my watch. \n\nMedicare is going to set higher standards for nursing homes and make sure your loved ones get the care they deserve and expect. \n\nWe’ll also cut costs and keep the economy going strong by giving workers a fair shot, provide more training and apprenticeships, hire them based on their skills not degrees. \n\nLet’s pass the Paycheck Fairness Act and paid leave. \n\nRaise the minimum wage to $15 an hour and extend the Child Tax Credit, so no one has to raise a family in poverty. \n\nLet’s increase Pell Grants and increase our historic support of HBCUs, and invest in what Jill—our First Lady who teaches full-time—calls America’s best-kept secret: community colleges.', lookup_str='', metadata={'source': '../../state_of_the_union.txt'}, lookup_index=0)]
或者,如果我们的文档有“source”元数据 key,我们可以使用 RetrievalQAWithSourceChain
来引用我们的source
:
# 构建文档时,指定元数据
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
# 构建可以从元数据中引用source的chain
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)
""" {'answer': ' The president honored Justice Breyer for his service and mentioned his legacy of excellence.\n',
'sources': '31-pl'} """
本文讲述4个要点:如何构建问答,构建时如何指定chain type,自定义prompt、返回源文档。
构建问答的方法:RetrievalQA.from_chain_type(xxx)
指定chain type: RetrievalQA.from_chain_type(chain_type="map_reduce")
,也可以利用load_qa_chain()
方法指定chain type。
自定义prompt:通过在RetrievalQA.from_chain_type()
方法中,指定chain_type_kwargs
参数,而该参数:chain_type_kwargs = {"prompt": PROMPT}
。
返回源文档:通过RetrievalQA.from_chain_type()
方法中指定:return_source_documents=True
参数;也可以使用RetrievalQAWithSourceChain()
方法,返回源文档的引用(坐标或者叫主键、索引)
参考地址:
Retrieval QA