[toc]
聊天机器人和虚拟助手正变得越来越普遍,在对话中保持上下文和连续性的能力很重要。想象一下,你正在与聊天机器人进行有趣的对话,结果对方却在对话中完全忘记了上下文,不过不要害怕,LangChain的内存管理功能为您提供了支持。内存管理允许对话式 AI 应用程序保留和回忆过去的交互,从而实现无缝和连贯的对话。LangChain提供不同类型的内存类型,每种类型都是为满足特定需求和优化性能而量身定制的。
一、内存类型
LangChain提供了多种内存类型,每种内存类型都旨在处理不同的用例和场景。让我们来探讨一些最常用的类型:
1. ConversationBufferMemory
ConversationBufferMemory 按原样存储整个对话历史记录,无需任何更改,使其成为聊天机器人和其他需要准确上下文的应用程序的有用工具。想象一下,您正在为客户支持聊天机器人构建一个虚拟助手。借助 ConversationBufferMemory,您的聊天机器人可以回忆起以前的交互,从而根据用户的特定查询或问题提供个性化且相关的响应。
下面是一个简单的示例来说明其用法:
from langchain_openai import ChatOpenAI
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory
# Set up the LLM and memory
llm_model = "gpt-3.5-turbo"
llm = ChatOpenAI(temperature=0.0, model=llm_model)
memory = ConversationBufferMemory()
# Create the conversation chain
conversation = ConversationChain(llm=llm, memory=memory, verbose=True)
# Start the conversation
response = conversation.predict(input="Hi, my name is Rutam")
print(response)
# Output: Hello Rutam! It's nice to meet you. How can I assist you today?
response = conversation.predict(input="What is 1 + 1")
print(response)
# Output: 1 + 1 equals 2. Is there anything else you would like to know?
response = conversation.predict(input="Whats my name?")
print(response)
# Output: Your name is Rutam. Is there anything else you would like to know or discuss?
如您所见,ConversationBufferMemory 允许聊天机器人记住用户的名称并在后续响应中引用它,从而创建更自然和个性化的对话流程。
2. ConversationBufferWindowMemory
虽然 ConversationBufferMemory 存储整个会话历史记录,但在某些情况下,您可能希望将内存限制为最近交换的固定窗口。当您不希望内存无限增长时,此内存类型特别有用。假设您正在为一个简单的天气应用程序构建一个聊天机器人。您可能只需要记住用户在当前对话中的位置,然后将其丢弃。
下面介绍如何使用 ConversationBufferWindowMemory 实现此目的:
from langchain.memory import ConversationBufferWindowMemory
# Set the window size to 1 (remember only the most recent exchange)
memory = ConversationBufferWindowMemory(k=1)
# ... (continue with setting up the LLM and conversation chain as before)
# Start the conversation
response = conversation.predict(input="What's the weather like in New York today?")
print(response)
# Output: I'm sorry, I don't have enough context to provide the weather for New York. Could you please provide your location?
response = conversation.predict(input="New York City")
print(response)
# Output: Here's the current weather forecast for New York City: ...
在此示例中,k=1 的 ConversationBufferWindowMemory 会忘记用户之前的输入(“今天纽约的天气怎么样?”),迫使聊天机器人再次询问位置。一旦用户提供了位置,聊天机器人就可以做出相应的响应。
3. ConversationTokenBufferMemory
使用语言模型时,关键考虑因素之一是令牌使用和成本优化。LLM(大型语言模型)通常根据处理的令牌数量收费,因此有效管理内存至关重要。ConversationTokenBufferMemory:一种内存类型,用于根据令牌数限制存储的对话。此功能与许多 LLM 的定价模型完全一致,允许您在保持对话上下文的同时控制成本。假设您正在为产品推荐系统构建一个聊天机器人。您希望将对话集中在当前正在讨论的产品上,而不会从以前的交互中积累不必要的令牌使用。
下面介绍如何使用 ConversationTokenBufferMemory:
from langchain.memory import ConversationTokenBufferMemory
# Set the maximum token limit
memory = ConversationTokenBufferMemory(llm=llm, max_token_limit=100)
# ... (continue with setting up the LLM and conversation chain as before)
# Start the conversation
response = conversation.predict(input="I'm looking for a new laptop")
print(response)
# Output: Okay, great! What are your main priorities for the new laptop? (e.g., portability, performance, battery life)
response = conversation.predict(input="Portability and long battery life are important to me")
print(response)
# Output: Got it. Based on your priorities, I'd recommend checking out the [laptop model] ...
在此示例中,ConversationSummaryBufferMemory 汇总了对话详细信息,允许虚拟助手在保持指定令牌限制的同时维护整体上下文,从而确保高效且经济实惠的内存管理。
二、其他类型
虽然我们已经探索了LangChain中一些最常用的内存类型,该库提供了其他几个选项来满足不同的用例。
矢量数据内存:如果您熟悉单词嵌入和文本嵌入,则此存储器类型存储对话的矢量表示,从而可以使用矢量相似度计算高效检索相关上下文。
实体内存:当您需要在对话上下文中记住有关实体(如人、地点或对象)的特定详细信息时,此内存类型特别有用。例如,如果您的聊天机器人正在讨论特定的朋友或同事,实体记忆可以存储和回忆有关该人的重要事实,从而确保更加个性化和上下文对话。
from langchain.chains import ConversationChain
from langchain.memory import ConversationEntityMemory
from langchain.memory.prompt import ENTITY_MEMORY_CONVERSATION_TEMPLATE
from pydantic import BaseModel
from typing import List, Dict, Any
conversation = ConversationChain(
llm=llm,
verbose=True,
prompt=ENTITY_MEMORY_CONVERSATION_TEMPLATE,
memory=ConversationEntityMemory(llm=llm)
)
conversation.predict(input="Deven & Sam are working on a hackathon project")
# Output: That sounds like a great project! What kind of project are they working on?
conversation.memory.entity_store.store
# Output: {'Deven': 'Deven is working on a hackathon project with Sam, which they are entering into a hackathon.',
# 'Sam': 'Sam is working on a hackathon project with Deven.'}
conversation.predict(input="They are trying to add more complex memory structures to Langchain")
# Output: That sounds like an interesting project! What kind of memory structures are they trying to add?
conversation.predict(input="They are adding in a key-value store for entities mentioned so far in the conversation.")
# Output: That sounds like a great idea! How will the key-value store help with the project?
conversation.predict(input="What do you know about Deven & Sam?")
# Output: Deven and Sam are working on a hackathon project together, trying to add more complex memory structures to Langchain, including a key-value store for entities mentioned so far in the conversation. They seem to be working hard on this project and have a great idea for how the key-value store can help.
三、组合多种内存类型
LangChain的一个强大方面是能够组合多种内存类型,以创建更全面和量身定制的解决方案。例如,可以使用 ConversationBufferMemory 或 ConversationSummaryBufferMemory 来维护整体对话上下文,同时还可以利用实体内存来存储和调用有关对话中提到的个人或对象的特定详细信息。这种方法使您能够在捕获对话流程和保留特定于实体的重要信息之间取得完美平衡,使您的聊天机器人或虚拟助手能够提供更明智和个性化的响应。
四、集成数据库
虽然LangChain的内置内存类型提供了强大的功能来管理会话上下文,但在某些情况下,您可能需要存储整个会话历史记录,以便进行审计、分析或将来的参考。在这种情况下,您可以将LangChain与传统数据库(例如键值存储或SQL数据库)无缝集成。这种方法允许您利用LangChain内存管理的优势,同时保持所有对话的持久性和可访问性记录。
例如,您可以将每个对话交换存储在数据库表中,其中包含用于用户输入、聊天机器人响应和其他元数据。这种全面的记录对下面场景非常有用:
- 对话审核:回顾过去的对话,以确定需要改进的领域或确保符合法规要求。
- 对话数据分析:分析对话模式、情绪和用户行为,以获得洞察力并改善整体聊天机器人体验。
- 个性化和上下文丰富:通过引用过去的对话,您可以为回访用户提供更加个性化和上下文化的体验,从而提高参与度和客户满意度。
小节
今天我们学习的是LangChain的内存管理模块,通过将LangChain的内存管理功能与强大的数据库解决方案相结合,您可以创建一个强大的对话式AI系统,该系统不仅可以在实时交互期间维护上下文,还可以保留全面的记录,以供将来的分析和优化。
无论您是处理通用文本、Markdown 文档、代码片段还是其他类型的内容,LangChain 的文本拆分器都提供了灵活性和自定义选项,可以有效地拆分您的文档。通过了解文档拆分中涉及的细微差别和注意事项,可以优化语言模型和下游任务的性能和准确性。