前言
LLM默认是没有记忆功能的,现象如下:
那……如何让他能有“记性”呢,下面给大家介绍个新模块“Memory”
简介
记忆组件解决的两大问题
-
历史如何存储
-
历史如何查询 LangChain提供了好几种记忆组件类型,这里先给大家介绍三种(其他的都很类似)
ConversationBufferMemory
程序
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory()
memory.save_context({"HumanMessage": "你好啊, AI小助手。"}, {"AIMessage": "嗨,有什么我可以帮助你?"})
res_save = memory.chat_memory.messages
print("Save:", res_save)
# 保存记忆
memory.save_context({"HumanMessage": "今天你过得怎么样?"}, {"AIMessage": "我过得很好,你今天有什么开心的事吗?"})
# 加载记忆
res_load = memory.load_memory_variables({})
print("Load:", res_load)
#清除记忆
memory.clear()
print("History:", memory.load_memory_variables({}))
输出结果
Save: [HumanMessage(content='你好啊, AI小助手。'), AIMessage(content='嗨,有什么我可以帮助你?')]
Load: {'history': 'Human: 你好啊, AI小助手。\nAI: 嗨,有什么我可以帮助你?\nHuman: 今天你过得怎么样?\nAI: 我过得很好,你今天有什么开心的事吗?'}
{'history': ''}
ConversationBufferWindowMemory
持续记录对话历史,但只使用最近的K个交互(类似滑动窗口机制),确保缓存大小不会变得过大。
程序
from langchain.memory import ConversationBufferWindowMemory
# k=1,意思是只记忆最近的一条内容
memory = ConversationBufferWindowMemory(k=1)
# 保存记忆
memory.save_context({"HumanMessage": "你好啊, AI小助手。"}, {"AIMessage": "嗨,有什么我可以帮助你?"})
memory.save_context({"HumanMessage": "今天你过得怎么样?"}, {"AIMessage": "我过得很好,你今天有什么开心的事吗?"})
print("Save:", memory.chat_memory.messages)
# 加载记忆
res = memory.load_memory_variables({})
print("Load:", res)
# 清除记忆
memory.clear()
print("History:", memory.load_memory_variables({}))
输出结果
Save: [HumanMessage(content='你好啊, AI小助手。'), AIMessage(content='嗨,有什么我可以帮助你?'), HumanMessage(content='今天你过得怎么样?'), AIMessage(content='我过得很好,你今天有什么开心的事吗?')]
Load: {'history': 'Human: 今天你过得怎么样?\nAI: 我过得很好,你今天有什么开心的事吗?'}
{'history': ''}
ConversationSummaryMemory
程序
from langchain.memory import ConversationSummaryMemory
from langchain_openai import ChatOpenAI
memory = ConversationSummaryMemory(llm=ChatOpenAI())
# 保存记忆
memory.save_context({"HumanMessage": "你好啊, AI小助手。"}, {"AIMessage": "嗨,有什么我可以帮助你?"})
memory.save_context({"HumanMessage": "今天你过得怎么样?"}, {"AIMessage": "我过得很好,你今天有什么开心的事吗?"})
# 加载记忆
res_load = memory.load_memory_variables({})
print(res_load)
# 清除记忆
memory.clear()
print("History:", memory.load_memory_variables({}))
输出结果
{'history': 'The human greets the AI in Chinese and the AI responds asking how it can help. The human asks the AI how its day is going in Chinese, to which the AI responds that it is doing well and asks if the human has anything happy to share today.'}
{'history': ''}
横向对比
组件类型 | 优点 | 不足 |
---|---|---|
ConversationBufferMemory | 实现简单、交互次数少 字符量不大时非常有效 | 交互增加,字符增多,可能导致Prompt tokens数超过上下文限制,导致调用模型失败 |
ConversationBufferWindowMemory | 持续记录对话历史,但只使用最近的K个交互 | K个以外的对话历史不会被保存 |
ConversationSummaryMemory | 可以调用LLM汇总之前的聊天记录 | 对话内容少,汇总的内容不会精炼太多 |
结语
再回到开篇的问题,看看如何解决“无记性”的事儿,代码如下:
现在看不懂Chain没关系,这系列以后再给大家介绍,一点点来~
from langchain_openai import OpenAI
from langchain.memory import ConversationBufferMemory
from langchain.chains import ConversationChain
memory = ConversationBufferMemory()
chain = ConversationChain(memory=memory, llm=OpenAI())
response = chain.invoke("你好啊, AI小助手")
response = chain.invoke("我刚才说什么了?")
print(response)
扩展一点
给大家介绍一种类似”记忆功能“,达到省流(省Token)的目的