1. 引言
在对话系统中,记忆(Memory)是一个核心功能。默认情况下,大型语言模型(LLM)是无状态的,即每次调用是独立的,不会记住之前的对话。而记忆机制允许我们保存对话上下文,使模型能够“记住”过去的互动,这在构建聊天机器人时尤为重要。
本文总结了LangChain中几种主要的记忆机制及其代码实现,包括:
- ConversationBufferMemory(缓冲记忆)
- ConversationBufferWindowMemory(缓冲窗口记忆)
- ConversationSummaryMemory(对话总结记忆)
- ConversationSummaryBufferMemory(混合记忆)
2. 对话链与提示模板
示例:ConversationChain
ConversationChain 是LangChain提供的一种简单对话链,其提示模板如下:
from langchain import OpenAI
from langchain.chains import ConversationChain
llm = OpenAI(temperature=0.5, model_name="gpt-3.5-turbo-instruct")
conv_chain = ConversationChain(llm=llm)
print(conv_chain.prompt.template)
输出模板:
The following is a friendly conversation between a human and an AI. The AI is talkative and provides lots of specific details from its context. If the AI does not know the answer to a question, it truthfully says it does not know.
Current conversation:
{history}
Human: {input}
AI:
- {history}:存储会话的对话历史。
- {input}:新输入。
通过将历史信息存储在 {history} 中,新的提示能够带有上下文进行回答。
3. 记忆机制实现
3.1 ConversationBufferMemory
特点
- 保存整个对话历史,适合短对话。
- Token消耗较高,容易达到模型的上下文限制。
示例代码
from langchain import OpenAI
from langchain.chains import ConversationChain
from langchain.chains.conversation.memory import ConversationBufferMemory
llm = OpenAI(temperature=0.5, model_name="gpt-3.5-turbo-instruct")
conversation = ConversationChain(llm=llm, memory=ConversationBufferMemory())
# 第一天对话
conversation("我姐姐明天要过生日,我需要一束生日花束。")
print("第一次对话后的记忆:", conversation.memory.buffer)
# 第二天对话
conversation("我又来了,还记得我昨天为什么要来买花吗?")
print("第二次对话后的记忆:", conversation.memory.buffer)
输出:
第一次对话后的记忆:
Human: 我姐姐明天要过生日,我需要一束生日花束。
AI: 哦,你姐姐明天要过生日,那太棒了!
第二次对话后的记忆:
Human: 我姐姐明天要过生日,我需要一束生日花束。
AI: 哦,你姐姐明天要过生日,那太棒了!
Human: 我又来了,还记得我昨天为什么要来买花吗?
AI: 是的,我记得你昨天说你姐姐要过生日。
3.2 ConversationBufferWindowMemory
特点
- 只保存最近
k轮对话。 - 适合短时间内的对话,但会忘记较远的历史。
示例代码
from langchain import OpenAI
from langchain.chains import ConversationChain
from langchain.chains.conversation.memory import ConversationBufferWindowMemory
llm = OpenAI(temperature=0.5, model_name="gpt-3.5-turbo-instruct")
conversation = ConversationChain(llm=llm, memory=ConversationBufferWindowMemory(k=1))
conversation("我姐姐明天要过生日,我需要一束生日花束。")
conversation("她喜欢粉色玫瑰,颜色是粉色的。")
response = conversation("我又来了,还记得我昨天为什么要来买花吗?")
print(response)
输出:
AI: 不好意思,我只记得你说喜欢粉色玫瑰。
说明:设置
k=1,模型只能记住最近一轮对话。
3.3 ConversationSummaryMemory
特点
- 对对话内容进行汇总,适合长对话。
- 使用LLM进行总结,每次更新时会增加计算成本。
示例代码
from langchain.chains.conversation.memory import ConversationSummaryMemory
conversation = ConversationChain(llm=llm, memory=ConversationSummaryMemory(llm=llm))
conversation("我姐姐明天要过生日,我需要一束生日花束。")
conversation("她喜欢粉色玫瑰,颜色是粉色的。")
response = conversation("我又来了,还记得我昨天为什么要来买花吗?")
print(response)
输出:
AI: 是的,我记得你昨天说你姐姐要过生日,想买一束粉色玫瑰。
汇总机制示例
ConversationSummaryMemory 将对话内容汇总成结构化信息:
历史总结:
The human asked the AI for advice on buying a bouquet for their sister's birthday. The AI suggested buying a vibrant bouquet...
3.4 ConversationSummaryBufferMemory
特点
- 即对话总结缓冲记忆,它是一种混合记忆模型。
- 结合
ConversationSummaryMemory和ConversationBufferWindowMemory。 - 在设定的
max_token_limit内保留最近对话,超出部分进行汇总。
示例代码
from langchain.chains.conversation.memory import ConversationSummaryBufferMemory
conversation = ConversationChain(
llm=llm,
memory=ConversationSummaryBufferMemory(llm=llm, max_token_limit=300)
)
conversation("我姐姐明天要过生日,我需要一束生日花束。")
conversation("她喜欢粉色玫瑰,颜色是粉色的。")
response = conversation("我又来了,还记得我昨天为什么要来买花吗?")
print(response)
输出:
AI: 是的,我记得你昨天说你姐姐要过生日,想买粉色玫瑰。
4. 记忆机制比较
| 机制 | 保存内容 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|---|
| ConversationBufferMemory | 全部历史 | 简单直接,完整上下文 | Token消耗高,易超限制 | 短对话 |
| ConversationBufferWindowMemory | 最近 k 轮对话 | 高效,Token利用率高 | 忘记较远历史 | 短期对话 |
| ConversationSummaryMemory | 对话总结 | 节约Token,适合长对话 | 总结质量依赖LLM,成本高 | 长对话 |
| ConversationSummaryBufferMemory | 最近对话+历史总结 | 灵活,高效 | 总结可能丢失细节 | 长对话或混合对话 |
5. 总结与展望
LangChain 提供了多种记忆机制,帮助我们根据需求灵活选择。在实际应用中,选择合适的记忆机制需要权衡对上下文长度、Token消耗和记忆准确性的要求。
对于复杂的对话应用,例如客服机器人、个人助手等,ConversationSummaryBufferMemory 是较好的选择,因为它在节约资源和保留信息间达到了良好的平衡。