基于Langchain的ConversationalRetrievalChain聊天机器人记忆集成问题
问题分析
你的机器人无法记住之前的问题,核心原因有两个:
- 调用
run_chain时传入的chat_history是空字符串,没有传递实际对话历史给ConversationalRetrievalChain - 当前session存储的消息格式和
ConversationalRetrievalChain要求的聊天历史格式不匹配(链条需要列表元组格式,比如[(用户提问, AI回答), ...],而你存的是字典列表)
修复方案
以下是修改后的完整代码,核心调整点已标注:
class MyBot(ActivityHandler): def __init__(self, conversation_state: ConversationState): self.conversation_state = conversation_state self.session_accessor = self.conversation_state.create_property("Session") # Data loader loader = CSVLoader(file_path="data.csv", encoding="utf-8", csv_args={'delimiter': ','}) data = loader.load() # OpenAI API key openai_api_key = os.environ.get('OPENAI_API_KEY') # Initialize OpenAIEmbeddings embeddings = OpenAIEmbeddings(openai_api_key=openai_api_key) # Initialize FAISS for the vector database vectors = FAISS.from_documents(data, embeddings) # 系统提示词整合到QA_PROMPT中,不需要存到会话历史里 # Initialize the ConversationalRetrievalChain self.chain = ConversationalRetrievalChain.from_llm( llm=ChatOpenAI(temperature=0.5, request_timeout=100, model_name='gpt-4o', max_tokens=2048, openai_api_key=openai_api_key), retriever=vectors.as_retriever(), combine_docs_chain_kwargs={"prompt": QA_PROMPT} ) def run_chain(self, chat_history, question): return self.chain.run({'chat_history': chat_history, 'question': question}) async def get_response(self, user_message, turn_context: TurnContext): # 初始化会话时只存储用户和AI的交互历史,不需要系统提示词 session = await self.session_accessor.get(turn_context, lambda: {"chat_history": []}) # 1. 把当前会话历史转换成ConversationalRetrievalChain需要的格式:列表元组 formatted_history = [(item["user"], item["assistant"]) for item in session["chat_history"]] # 2. 调用链条时传入格式化后的聊天历史 response = self.run_chain(formatted_history, user_message) ai_response = response # 3. 将当前对话存储到会话历史中(用字典格式方便后续转换) session["chat_history"].append({ "user": user_message, "assistant": ai_response }) # 保存更新后的会话 await self.conversation_state.save_changes(turn_context) return ai_response
关键修改说明
- 会话存储结构调整:把原来的
messages列表改成chat_history列表,每个元素是包含user和assistant字段的字典,方便后续转换成链条需要的格式。 - 历史格式转换:在调用链条前,将会话中的历史转换成
[(用户提问, AI回答)]的元组列表,这是ConversationalRetrievalChain要求的标准格式。 - 正确传递历史:调用
run_chain时传入转换后的formatted_history,而不是空字符串,让链条能基于之前的对话生成上下文相关的回答。 - 系统提示词处理:系统提示词直接整合到
QA_PROMPT中,不需要存到会话历史里,避免干扰历史上下文的传递。
内容的提问来源于stack exchange,提问作者Ahmed Ewis
相关产品推荐
相关产品推荐

