Langchain中ConversationalRetrievalChain无法记忆对话历史的问题排查
问题原因及解决办法
1. 聊天历史格式维护错误
ConversationalRetrievalChain要求chat_history必须是**[(用户问题, 机器人回答), ...]**这种元组列表格式。如果每次调用后你错误地把返回结果里的chat_history(本身已经是列表)直接往原列表里追加,或者用了错误的更新方式,就会出现嵌套数组的问题。
比如你可能写了这样的错误代码:
chat_history = [] response = conv_chain({"question": "你好", "chat_history": chat_history}) # 错误操作:把返回的列表直接追加,导致嵌套结构 chat_history.append(response["chat_history"])
此时chat_history会变成[[("你好", "你好呀")]],下次调用传入这个嵌套列表,自然无法正常识别对话历史。
正确的更新方式是把当前对话的(问题,回答)元组直接追加到列表:
chat_history.append((prompt, response["answer"]))
2. 每次提问都重新创建了链实例
如果你的代码每次处理用户提问时,都重新初始化conv_chain(比如把链的创建逻辑写在循环内部),那每次都是全新的链实例,日志自然会显示进入新的ConversationalRetrievalChain,而且链根本没法复用之前的对话上下文。
错误示例:
while True: prompt = input("问点啥:") # 每次循环都新建链,完全没必要且会导致记忆失效 conv_chain = ConversationalRetrievalChain.from_llm(llm=你的大模型, retriever=你的检索器) response = conv_chain({"question": prompt, "chat_history": chat_history})
正确做法是把链的初始化放在循环外面,只创建一次:
# 提前创建好链,仅初始化一次 conv_chain = ConversationalRetrievalChain.from_llm(llm=你的大模型, retriever=你的检索器) chat_history = [] while True: prompt = input("问点啥:") response = conv_chain({"question": prompt, "chat_history": chat_history}) chat_history.append((prompt, response["answer"])) print(response["answer"])
3. 别被verbose日志误导
如果你的链设置了verbose=True,每次调用都会输出执行流程日志,看起来像是进入新的链,但其实只是每次调用的过程打印。只要链是只初始化一次,这个就不是问题,重点还是要盯紧chat_history的格式是否正确。
内容的提问来源于stack exchange,提问作者RagAnt
相关产品推荐
相关产品推荐

