RetrievalQA链中检索文档传递至LLM的技术问题咨询
你提到的代码里没有显式传递检索文档的步骤,是因为RetrievalQA.from_chain_type()方法已经封装了检索文档→拼接上下文→传递给LLM的完整流程。当你传入retriever=vectordb.as_retriever()时,RetrievalQA链会自动在每次调用时执行以下操作:
- 用传入的问题调用retriever获取相关文档
- 将这些文档内容拼接成上下文,和原始问题一起填入预设的prompt模板
- 把填充好的prompt传给LLM生成回答
下面是几种验证、自定义或显式控制这一流程的方法:
一、查看默认流程的内部细节(验证文档已被传递)
在创建RetrievalQA链时开启verbose=True,运行后会打印出传给LLM的完整prompt,你就能直观看到检索到的文档已经被包含在上下文里:
qa_chain = RetrievalQA.from_chain_type( llm, retriever=vectordb.as_retriever(), verbose=True # 开启verbose模式 ) result = qa_chain({"query": question})
运行后会输出类似这样的内容(包含检索到的文档片段):
Prompt after formatting:
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.[检索到的文档内容1]
[检索到的文档内容2]Question: What are major topics for this class?
Helpful Answer:
二、自定义Prompt模板(显式控制文档的使用方式)
如果你想自定义上下文和问题的拼接逻辑,可以自己定义Prompt模板,然后通过chain_type_kwargs传入RetrievalQA:
from langchain.prompts import PromptTemplate # 自定义prompt模板,明确包含{context}和{question}变量 custom_prompt = PromptTemplate( template="""基于以下上下文信息回答问题: {context} 问题:{question} 请给出准确的回答:""", input_variables=["context", "question"] ) qa_chain = RetrievalQA.from_chain_type( llm, retriever=vectordb.as_retriever(), chain_type_kwargs={"prompt": custom_prompt}, # 传入自定义prompt verbose=True ) result = qa_chain({"query": question})
这种方式下,你能完全控制检索到的文档如何被组织成LLM的输入。
三、手动构建RetrievalQA流程(完全显式控制每一步)
如果想要彻底拆解流程,手动完成每一步,可以不用from_chain_type(),而是自己组合组件:
from langchain.chains import LLMChain from langchain.chains.combine_documents.stuff import StuffDocumentsChain # 1. 定义LLM链(处理问题+上下文) llm_chain = LLMChain(llm=llm, prompt=custom_prompt) # 2. 定义文档组合链(把检索到的文档拼接成context) stuff_chain = StuffDocumentsChain( llm_chain=llm_chain, document_variable_name="context" # 指定文档对应的变量名 ) # 3. 构建RetrievalQA链 qa_chain = RetrievalQA( retriever=vectordb.as_retriever(), combine_documents_chain=stuff_chain ) # 调用链 result = qa_chain({"query": question})
这种方式下,你能清晰看到检索到的文档通过StuffDocumentsChain被拼接成context变量,再传给LLM链。
补充说明
你代码里的docs = vectordb.similarity_search(question,k=3)只是单独测试检索功能,和后面的RetrievalQA链没有关联——RetrievalQA链会自己调用retriever获取文档,不需要你手动传递这个docs变量。如果想让链使用你手动检索的文档,可以用RetrievalQA.from_documents()方法:
qa_chain = RetrievalQA.from_documents( docs, # 传入你手动检索的文档 llm ) result = qa_chain({"query": question})
内容的提问来源于stack exchange,提问作者Rishil Boddula

