ConversationBufferWindowMemory与SQLDatabaseChain集成失效问题排查
问题分析与修复方案
核心问题
你的代码有俩关键问题导致上下文记忆失效:
- 自定义查询模板没加聊天历史变量:你写的
QUERY字符串里根本没放{chat_history}占位符,内存里存的之前对话根本传不到LLM那里,它自然没法用上上下文。 - 查看内存内容的方式错误:你打印的
memory.buffer是完整的消息存储列表,ConversationBufferWindowMemory的k=1是通过load_memory_variables方法返回最近1条对话,直接看buffer当然会显示所有历史,这不是实际传给LLM的内容。
修复步骤
1. 修改QUERY模板,加入聊天历史变量
更新你的QUERY模板,让LLM能获取之前的对话上下文:
QUERY = """ 参考以下聊天历史: {chat_history} 给定问题,先生成语法正确的PostgreSQL查询并执行,再根据查询结果返回答案。 格式必须遵循以下要求: Question: "问题内容" SQLQuery: "要执行的SQL查询" SQLResult: "查询结果" Answer: "最终答案" {question} """
2. 正确初始化链并验证传入的记忆
你可以在调用链之前,打印实际传给LLM的记忆内容,确认是不是最近1条:
# 初始化记忆和链 memory = ConversationBufferWindowMemory(memory_key="chat_history", return_messages=True, k=1) # 推荐用from_llm方法初始化,更符合LangChain规范 db_chain = SQLDatabaseChain.from_llm(llm=llm, database=db, verbose=True, memory=memory, top_k=3) # 在get_prompt函数的run调用前添加,查看实际传入的上下文 print("实际传给LLM的上下文:", memory.load_memory_variables({}))
3. 调整链的调用方式(可选)
如果使用run方法仍有问题,可以改用predict方法明确传入参数:
response = db_chain.predict(question=prompt, chat_history=memory.load_memory_variables({})["chat_history"])
4. 正确查看内存使用情况
别再打印memory.buffer了,打印load_memory_variables的结果,这才是链真正使用的上下文:
print("当前使用的上下文:", memory.load_memory_variables({}))
修复后的完整代码片段
# 省略其他导入和数据库、LLM初始化代码... # 更新后的查询模板 QUERY = """ 参考以下聊天历史: {chat_history} 给定输入问题,先创建语法正确的PostgreSQL查询并执行,再根据查询结果返回答案。 请遵循以下格式: Question: "问题内容" SQLQuery: "要执行的SQL查询" SQLResult: "查询结果" Answer: "最终答案" {question} """ memory = ConversationBufferWindowMemory(memory_key="chat_history", return_messages=True, k=1) db_chain = SQLDatabaseChain.from_llm(llm=llm, database=db, verbose=True, memory=memory, top_k=3) def get_prompt(): print("输入'exit'退出") while True: prompt = input("请输入问题:") logger.info(f"PROMPT: {prompt}") if prompt.lower() == 'exit': print('正在退出...') break else: try: # 打印实际传入的上下文 print("当前上下文:", memory.load_memory_variables({})) # 格式化问题,把聊天历史加入 question = QUERY.format(chat_history=memory.load_memory_variables({})["chat_history"], question=prompt) response = db_chain.run(question) logger.info(f"RESPONSE: {response}") print(response) # 打印更新后的上下文 print("更新后的上下文:", memory.load_memory_variables({})) except Exception as e: print(e) get_prompt()
额外说明
- 0.2.17版本的LangChain完全支持给
SQLDatabaseChain传入memory参数,无需更换版本。 - 如果仍有异常,可以尝试用
SQLChatMessageHistory结合ConversationBufferWindowMemory实现更精细的会话管理,但上述修复已能解决核心的上下文失效问题。
内容的提问来源于stack exchange,提问作者user1805280
相关产品推荐
相关产品推荐

