如何在Langchain ConversationalRetrievalChain中先处理检索文档再作答
实现ConversationalRetrievalChain前置文档内容提取步骤
要实现对检索到的每份文档先提取与问题相关内容(无相关则返回Unknown),再执行后续问答的需求,可通过Map-Reduce模式扩展原有链结构,具体实现如下:
1. 定义单文档内容提取链
创建用于处理单份文档的链,调用目标提示词完成内容提取:
from langchain.chains import LLMChain from langchain.prompts import PromptTemplate from langchain.chat_models import ChatOpenAI llm = ChatOpenAI(temperature=0, model="gpt-3.5-turbo") # 中文提取提示词(翻译自原需求模板) intermediate_answer_template = """ 你是专业的信息提取助手。 给定问题和上下文,从上下文中提取所有与问题相关的文本内容。 如果上下文无法回答该问题,直接返回"Unknown" 上下文: {context} 问题: {question} 返回格式:markdown """ intermed_ans = PromptTemplate(template=intermediate_answer_template, input_variables=["context", "question"]) # 单文档处理链:输入单份文档+问题,输出提取后的内容 single_doc_chain = LLMChain(llm=llm, prompt=intermed_ans)
2. 构建批量文档处理链
用MapDocumentsChain批量遍历所有检索到的文档,对每份文档单独执行提取操作:
from langchain.chains import MapDocumentsChain # 批量处理链:将单文档提取逻辑应用到所有检索结果 map_chain = MapDocumentsChain( llm_chain=single_doc_chain, document_variable_name="context" # 指定文档在提示词中的变量名 )
3. 定义有效结果合并链
过滤掉返回Unknown的无效文档,将有效提取结果合并后传入原有QA链生成最终回答:
from langchain.chains import ReduceDocumentsChain, StuffDocumentsChain from langchain.chains.question_answering import load_qa_chain # 原有问答提示词(需提前定义CONDENSE_PROMPT和QA_PROMPT) # CONDENSE_PROMPT = ... # 对话历史浓缩提示词 # QA_PROMPT = ... # 最终问答生成提示词 # 合并有效提取结果:将内容拼接为上下文传入QA链 reduce_chain = StuffDocumentsChain( llm_chain=LLMChain(llm=llm, prompt=QA_PROMPT), document_variable_name="context" ) # 整合过滤与合并逻辑 combine_documents_chain = ReduceDocumentsChain( combine_documents_chain=reduce_chain, # 过滤无相关内容的文档 document_filter=lambda doc: doc.page_content != "Unknown", collapse_documents_chain=reduce_chain ) # 组合Map-Reduce链:先批量提取,再合并有效内容 final_combine_chain = MapReduceDocumentsChain( map_documents_chain=map_chain, combine_documents_chain=combine_documents_chain, return_intermediate_steps=False )
4. 替换原链的文档合并逻辑
将新构建的final_combine_chain替换原有doc_chain,完成整个对话检索链的整合:
from langchain.chains import ConversationalRetrievalChain question_generator = LLMChain(llm=llm, prompt=CONDENSE_PROMPT) chain = ConversationalRetrievalChain( retriever=vectorstore.as_retriever(), question_generator=question_generator, combine_docs_chain=final_combine_chain )
核心逻辑说明
- Map阶段:对每份检索到的文档单独执行内容提取,只保留与问题强相关的片段,剔除冗余信息。
- Reduce阶段:自动过滤无相关内容的文档,避免无效数据干扰最终回答的生成质量。
内容的提问来源于stack exchange,提问作者watermelodic
相关产品推荐
相关产品推荐

