学习笔记:LangChain中的对话记忆机制

96 阅读3分钟

一、引言

在默认情况下,无论是LLM(大语言模型)还是代理都是无状态的,每次模型的调用都是独立于其他交互的。然而,ChatGPT等聊天机器人能够记得之前的对话内容,这得益于其使用的记忆(Memory)机制。本文将介绍LangChain中几种不同的记忆机制,并探讨它们在实际应用中的效果。

二、ConversationChain

ConversationChain是LangChain中用于管理对话记忆的重要工具。它提供了包含AI前缀和人类前缀的对话摘要格式,与记忆机制结合紧密。

示例代码

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}参数用于存储和传递对话历史和新输入内容。

三、使用ConversationBufferMemory

ConversationBufferMemory是LangChain中最简单的记忆机制,通过缓冲对话历史来实现记忆功能。

示例代码

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)
# 第三次对话(第二天的对话)
conversation("我又来了,还记得我昨天为什么要来买花吗?")
print("\n第三次对话后时提示:\n", conversation.prompt.template)
print("\n第三次对话后的记忆:\n", conversation.memory.buffer)

输出

第一次对话后的记忆: 
Human: 我姐姐明天要过生日,我需要一束生日花束。
AI:  哦,你姐姐明天要过生日,那太棒了!我可以帮你推荐一些生日花束,你想要什么样的?我知道有很多种,比如玫瑰、康乃馨、郁金香等等。
...(后续对话内容)

这种机制简单直观,但可能会因为较长的对话历史而增加Token的使用。

四、使用ConversationSummaryMemory和ConversationSummaryBufferMemory

ConversationSummaryMemory和ConversationSummaryBufferMemory是更高级的记忆机制,旨在优化Token的使用并保留重要的对话内容。

  • ConversationSummaryMemory:总结早期的互动,适用于多轮、长时间的对话场景。但无法区分近期和长期的对话。
  • ConversationSummaryBufferMemory:结合了上述两种机制的特点,通过max_token_limit参数控制总结的详细程度。当对话内容超过预设长度时,会进行总结以节省Token。

示例代码

from langchain.chains.conversation.memory import ConversationSummaryBufferMemory
llm = OpenAI(temperature=0.5, model_name="gpt-3.5-turbo-instruct")
conversation = ConversationChain(llm=llm, memory=ConversationSummaryBufferMemory(llm=llm, max_token_limit=300))
# 初始化对话并观察输出内容的变化(略)...

这种机制在节省Token的同时,能够较好地保留重要的对话信息。但需要注意的是,对于较短的对话,也可能会增加Token的使用。

五、总结与比较

通过表格总结了四种记忆机制的优缺点:

记忆机制优点缺点适用场景
ConversationBufferMemory简单直观,易于实现对话历史较长时增加Token使用简短、单次对话
ConversationSummaryMemory节省Token,适用于多轮对话无法区分近期和长期对话多轮、长时间对话
ConversationBufferWindowMemory直接节省Token,不依赖LLM的汇总能力完全遗忘K轮之前的对话内容需要频繁更新的场景
ConversationSummaryBufferMemory结合了上述机制的特点,灵活性强对于较短的对话也可能增加Token使用多轮、需要节省Token的场景