如何在LangChain QA Retrieval中处理上下文与通用问题?
问题分析与解决方案
你的核心问题在于**RetrievalQA的memory参数并非用于将聊天历史作为问答上下文**,它仅用于存储链内部的中间运行状态,导致你存入的聊天历史没有被模型有效利用;同时RetrievalQA会强制优先从向量库检索内容,即使问题和知识库无关,检索到的空/不相关上下文会干扰模型调用聊天历史的逻辑。
以下是两种可行的解决方法:
方案1:改用ConversationalRetrievalChain(推荐)
这个链是LangChain专为对话式检索场景设计的,天然支持将聊天历史与检索上下文结合,无需手动处理历史传递。
修改后的代码:
from langchain.chains import ConversationalRetrievalChain from langchain.memory import ConversationBufferMemory # 初始化记忆模块(确保正确配置记忆键) memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True) # 存入初始问答 memory.save_context({"input": "Who is the founder of India?"}, {"output": "Gandhi"}) # 创建对话检索链 qa = ConversationalRetrievalChain.from_llm( llm=llm, retriever=vectorstore.as_retriever(), memory=memory, # 自定义提示词,明确优先级:聊天历史 > 检索上下文 > 自身知识 combine_docs_chain_kwargs={ "prompt": PromptTemplate( template="""请用自己的话回答问题,优先级如下: 1. 优先从聊天历史中查找相关信息 2. 聊天历史无相关内容时,使用提供的上下文 3. 以上都没有时,使用你的知识库回答 聊天历史:{chat_history} 上下文:{context} 用户:{question} 助手:""", input_variables=["context", "chat_history", "question"] ) } ) # 提问测试 question = "What did I ask about India?" result = qa({"question": question}) print(result["answer"])
方案2:调整RetrievalQA配置与提示词
如果坚持使用RetrievalQA,需要手动处理聊天历史的传递,并优化提示词逻辑:
- 优化提示词:明确告诉模型优先参考聊天历史
- 手动传递聊天历史:从记忆模块中提取历史内容,作为参数传入问答链
- 调整检索策略:减少无关检索结果的干扰
修改后的代码:
# 优化提示词,明确优先级 template = """请用自己的话回答问题,遵循以下优先级: 1. 先从聊天历史中查找相关信息 2. 聊天历史无相关内容时,使用提供的上下文 3. 以上都没有时,使用你的知识库回答 聊天历史:{chat_history} 上下文:{context} 用户:{question} 助手:""" prompt = PromptTemplate( input_variables=["context", "chat_history", "question"], template=template ) # 创建RetrievalQA,限制检索数量减少干扰 qa = RetrievalQA.from_chain_type( llm=llm, retriever=vectorstore.as_retriever(search_kwargs={"k": 1}), chain_type_kwargs={'prompt': prompt} ) # 提问时手动提取聊天历史并传入 chat_history = memory.load_memory_variables({})["chat_history"] question = "What did I ask about India?" result = qa({ "query": question, "chat_history": chat_history, "context": "" # 若检索无结果,手动设为空上下文 }) print(result["result"])
关键注意事项
RetrievalQA的memory参数不能用来传递聊天历史到提示词,必须手动提取或改用专门的对话链- 提示词的优先级逻辑是核心,必须明确告诉模型何时使用聊天历史
- 对于和知识库无关的问题,可设置检索阈值(如
search_kwargs={"score_threshold": 0.7}),当检索结果相似度低于阈值时返回空上下文,避免干扰模型判断
内容的提问来源于stack exchange,提问作者Usman Afridi
相关产品推荐
相关产品推荐

