学习笔记10《记忆:通过Memory记住客户上次买花时的对话细节》

191 阅读4分钟

引言

在构建基于大型语言模型(LLM)的对话系统时,记忆机制是一个关键功能,它允许系统回顾和利用之前的交互信息。LangChain提供了多种记忆机制,以适应不同的对话场景和需求。以下是对LangChain中记忆机制的详细学习笔记。

无状态的LLM和代理

在默认情况下,LLM和代理(代理在这里指的是对话系统中的AI角色)都是无状态的,即它们不会保留任何关于之前交互的信息。这意味着每次用户与系统交互时,系统都会像第一次一样,没有任何上下文信息。为了解决这个问题,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)

这段代码创建了一个ConversationChain实例,其中包含了一个LLM实例。prompt.template定义了对话的格式,其中包括了对话历史({history})和当前的人类输入({input})。

使用ConversationBufferMemory

ConversationBufferMemory是一种简单的记忆机制,它将对话历史存储在一个缓冲区中。

示例代码分析

from langchain.chains.conversation.memory import ConversationBufferMemory

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)

这段代码展示了如何使用ConversationBufferMemory来存储对话历史。每次对话后,memory.buffer都会更新,包含最新的对话内容。

使用ConversationBufferWindowMemory

ConversationBufferWindowMemory是一种缓冲窗口记忆机制,它只保存一定数量的最新对话。

示例代码分析

from langchain.chains.conversation.memory import ConversationBufferWindowMemory

conversation = ConversationChain(
    llm=llm,
    memory=ConversationBufferWindowMemory(k=1)
)

result = conversation("我姐姐明天要过生日,我需要一束生日花束。")
print(result)

result = conversation("她喜欢粉色玫瑰,颜色是粉色的。")
print(result)

result = conversation("我又来了,还记得我昨天为什么要来买花吗?")
print(result)

这段代码展示了如何使用ConversationBufferWindowMemory来限制记忆的窗口大小。在这个例子中,k=1表示只保存最近的一次对话。

使用ConversationSummaryMemory

ConversationSummaryMemory是一种对话总结记忆机制,它将对话历史总结后传递给LLM。

示例代码分析

from langchain.chains.conversation.memory import ConversationSummaryMemory

conversation = ConversationChain(
    llm=llm,
    memory=ConversationSummaryMemory(llm=llm)
)

result = conversation("我姐姐明天要过生日,我需要一束生日花束。")
print(result)

result = conversation("她喜欢粉色玫瑰,颜色是粉色的。")
print(result)

result = conversation("我又来了,还记得我昨天为什么要来买花吗?")
print(result)

这段代码展示了如何使用ConversationSummaryMemory来总结对话历史,并将其作为上下文传递给LLM。

使用ConversationSummaryBufferMemory

ConversationSummaryBufferMemory结合了对话总结和缓冲窗口记忆的特点。

示例代码分析

from langchain.chains.conversation.memory import ConversationSummaryBufferMemory

conversation = ConversationChain(
    llm=llm,
    memory=ConversationSummaryBufferMemory(
        llm=llm,
        max_token_limit=300)
)

result = conversation("我姐姐明天要过生日,我需要一束生日花束。")
print(result)

result = conversation("她喜欢粉色玫瑰,颜色是粉色的。")
print(result)

result = conversation("我又来了,还记得我昨天为什么要来买花吗?")
print(result)

这段代码展示了如何使用ConversationSummaryBufferMemory来同时实现对话总结和限制记忆的窗口大小。

总结

LangChain提供的记忆机制可以帮助LLM在对话中保持上下文信息,从而提供更加连贯和个性化的对话体验。每种记忆机制都有其特点和适用场景,开发者可以根据具体需求选择合适的记忆机制。

思考题解答

  1. 在客服聊天机器人设计中,如果需要告知客户记忆能力有限,我会选择ConversationBufferWindowMemory作为记忆机制。这种机制可以明确地设置记忆窗口的大小,例如设置为10,这样可以直接告诉客户只能记住最近的10次对话。

  2. 改变ConversationBufferWindowMemory中的k值并增加对话轮次,可以观察到记忆机制如何影响对话的连贯性和上下文的保持。例如,增加k值可以保留更多的对话历史,但可能会导致对话历史过于冗长,影响新对话的处理。

  3. 改变ConversationSummaryBufferMemory中的max_token_limit值可以影响对话总结的详细程度。增加这个值可以允许更详细的对话总结,但可能会导致LLM处理时间过长。减少这个值可以加快处理速度,但可能会丢失一些重要的上下文信息。

通过这些实验,我们可以更好地理解不同记忆机制在实际应用中的效果和影响,从而为特定的对话场景选择最合适的记忆机制。