如何在LangChain中结合对话记忆与文档上下文加载?
解决方案:结合LangChain对话记忆与文档上下文加载
你遇到的问题核心是ConversationChain仅支持单一输入参数,无法同时处理文档检索结果和对话历史。正确的做法是使用ConversationalRetrievalChain——LangChain专门为「带对话记忆的文档检索问答」场景设计的链结构,它能自动整合文档检索、对话记忆和LLM推理逻辑。
修改后的完整代码
import pickle from langchain.chat_models import OpenAI from langchain.chains import ConversationalRetrievalChain from langchain.memory import ConversationBufferWindowMemory from langchain.callbacks import get_openai_callback # 加载预存的文档检索对象 with open('/content/gdrive/My Drive/ai-data/docsearch.pkl', 'rb') as f: docsearch = pickle.load(f) # 配置LLM参数 model_kwargs = { "model": "text-davinci-003", "temperature": 0.7, "max_tokens": -1, "top_p": 1, "frequency_penalty": 0, "presence_penalty": 0.5, "n": 1, "best_of": 1 } llm = OpenAI(model_kwargs=model_kwargs) # 定义统计token的函数 def count_tokens(chain, query): with get_openai_callback() as cb: # ConversationalRetrievalChain会自动处理文档检索和对话记忆,直接传入query即可 result = chain.run(query) print(f'总共消耗 {cb.total_tokens} 个token') return result # 创建带对话记忆的检索问答链 conversation_chain = ConversationalRetrievalChain.from_llm( llm=llm, # 将docsearch转换为检索器供链使用 retriever=docsearch.as_retriever(), # 保留你原来的对话记忆配置 memory=ConversationBufferWindowMemory(k=5, memory_key="chat_history", return_messages=True) ) # 测试调用 count_tokens( conversation_chain, "Good morning AI!" )
关键修改说明
- 替换链类型:用
ConversationalRetrievalChain替代ConversationChain,这个链原生支持文档检索与对话记忆的结合。 - 传入检索器:通过
docsearch.as_retriever()将你的向量搜索对象转换为LangChain标准检索器,链会自动根据用户query检索相关文档。 - 简化调用逻辑:无需手动调用
similarity_search和传入input_documents,链内部会完成「检索文档→结合对话历史→生成回答」的全流程,直接调用chain.run(query)即可。 - 记忆参数适配:添加
memory_key="chat_history", return_messages=True是为了匹配ConversationalRetrievalChain默认的记忆键名,确保对话历史能被正确读取和使用。
额外提示
如果需要自定义回答的提示模板,可以在创建链时传入combine_docs_chain_kwargs参数,比如:
from langchain.prompts import PromptTemplate custom_prompt = PromptTemplate( template="根据以下文档内容和对话历史回答问题:\n文档:{context}\n对话历史:{chat_history}\n问题:{question}\n回答:", input_variables=["context", "chat_history", "question"] ) conversation_chain = ConversationalRetrievalChain.from_llm( llm=llm, retriever=docsearch.as_retriever(), memory=ConversationBufferWindowMemory(k=5, memory_key="chat_history", return_messages=True), combine_docs_chain_kwargs={"prompt": custom_prompt} )
内容的提问来源于stack exchange,提问作者Chris Vorster
相关产品推荐
相关产品推荐

