LangChain的记忆机制改进 | 豆包MarsCode AI刷题

249 阅读4分钟

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

特点

  • 对话总结缓冲记忆,它是一种混合记忆模型。
  • 结合 ConversationSummaryMemoryConversationBufferWindowMemory
  • 在设定的 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 是较好的选择,因为它在节约资源和保留信息间达到了良好的平衡。