赞
踩
在人工智能领域,对话记忆是聊天机器人技术的一个重要组成部分。它使得机器人能够记住与用户的历史交互,从而进行连贯的对话。如果没有对话记忆,每个查询都会被当作完全独立的输入来处理,这将大大降低对话的连贯性和实用性。
对话记忆指的是机器人记住与用户之前交互的能力。默认情况下,机器人是无状态的,也就是说,它们处理每个输入时都不会考虑之前的交互。对话记忆的存在,使得机器人能够记住之前的交互,这在聊天机器人等应用中非常重要。
LangChain是一个用于构建语言模型应用的框架,它提供了多种实现对话记忆的方法。在这里,我们将探索LangChain库中对话记忆的不同形式。
pip install -qU langchain openai tiktoken
在LangChain中,我们首先需要设置使用的语言模型。例如,使用OpenAI的GPT模型:
from langchain import OpenAI
from getpass import getpass
OPENAI_API_KEY = getpass()
llm = OpenAI(
temperature=0,
openai_api_key=OPENAI_API_KEY,
model_name='text-davinci-003'
)
LangChain提供了几种不同的对话记忆类型,每种类型都有其特点和适用场景。
ConversationBufferMemory:这种记忆类型保留对话的原始片段,使得机器人可以回顾整个对话历史。这种机制简单直接,这种方法也存在一些缺点,由于LLM token限制,并不总是能够按预期存储所有内容。并且token的高使用率会导致响应时间变慢和计算成本增加。
ConversationBufferWindowMemory:这种记忆类型只保留最近的几次交互,类似于短期记忆,适用于需要快速响应的场景。
ConversationSummaryMemory:这种记忆类型通过LLM对对话历史进行摘要,有助于减少记忆占用的空间,适用于长对话。
ConversationKGMemory:这种记忆类型基于知识图谱,将对话中的实体和它们的关系存储起来,适用于需要理解和利用复杂关系的场景。
在 LangChain 中,链通常用于分解任务,由链接组成。Lang Chain提供了 ConversationChain,它是专门为有一些记忆概念的场景而创建的。创建类的实例时ConversationChain,必须提供三个参数:
示例代码:
from langchain.llms import OpenAI from langchain.chains import ConversationChain from langchain.chains.conversation.memory import ConversationBufferMemory # 初始化大型语言模型 api_key = "你的api密钥" api_url = "你的api网址" model_name = "模型名称" # 替换为你的模型名称 llm = OpenAI(model_name=model_name, openai_api_key=api_key, openai_api_base=api_url) # 使用ConversationBufferMemory初始化对话链 conversation = ConversationChain( llm=llm, memory=ConversationBufferMemory() ) # 示例对话 # 第一轮 user_input = "今天天气怎么样?" response = conversation(user_input) print("AI回应:", response) # 现在内存缓冲区包含了第一轮对话 print("第一轮后的记忆:", conversation.memory.buffer) # 第二轮 user_input = "你能推荐一把适合雨天的伞吗?" response = conversation(user_input) print("AI回应:", response) # 现在内存缓冲区包含了两轮对话 print("第二轮后的记忆:", conversation.memory.buffer)
这种方法针对前面的全历史记忆有容量限制问题提供了解决办法。但也存在一些问题。
示例代码:
from langchain.llms import OpenAI from langchain.chains import ConversationChain from langchain.chains.conversation.memory import ConversationBufferWindowMemory # 初始化大型语言模型 api_key = "你的api密钥" api_url = "你的api网址" model_name = "模型名称" # 替换为你的模型名称 llm = OpenAI(model_name=model_name, openai_api_key=api_key, openai_api_base=api_url) # 使用ConversationBufferWindowMemory初始化对话链 # 设置窗口大小为5(例如,只保留最近5轮对话) conversation = ConversationChain( llm=llm, memory=ConversationBufferWindowMemory(k=5) ) # 示例对话 # 进行多轮对话 for i in range(1, 8): user_input = f"这是第{i}轮对话。" response = conversation(user_input) print(f"第{i}轮 - AI回应:", response) print(f"第{i}轮后的记忆:", conversation.memory.buffer)
内存效率:通过限制记忆的大小,这种方法可以有效地控制内存使用,避免因长时间对话积累而导致的内存溢出。
关注重点:窗口记忆机制使模型集中于最近的对话内容,这通常是最相关和最重要的信息,有助于提高对话的相关性和准确性。
动态更新:随着新的对话输入,旧的对话内容会被移除,保持了记忆的实时更新,这对于快速变化的对话主题尤其有用。
减少噪声:限制记忆的大小有助于减少无关或过时信息的干扰,提高对话质量。
信息丢失:由于只保留最近的对话内容,较早的信息可能会被遗忘,这在需要长期记忆或上下文的场景中可能是一个问题。
窗口大小的选择:确定合适的窗口大小可能是一个挑战,太小的窗口可能丢失重要信息,而太大的窗口则可能导致内存效率降低。
对话连贯性的影响:在某些情况下,如果重要的上下文信息被窗口机制切除,可能会影响对话的连贯性和逻辑性。
处理复杂对话的限制:对于需要深入理解和长期记忆的复杂对话(如专业咨询或详细的故事叙述),这种方法可能不够有效。
这种相比于ConversationBufferMemory和ConversationBufferWindowMemory的主要优势在于:
from langchain.llms import OpenAI from langchain.chains import ConversationChain from langchain.chains.conversation.memory import ConversationSummaryMemory # 初始化大型语言模型 api_key = "你的api密钥" api_url = "你的api网址" model_name = "模型名称" # 替换为你的模型名称 llm = OpenAI(model_name=model_name, openai_api_key=api_key, openai_api_base=api_url) # 使用ConversationSummaryMemory初始化对话链 conversation = ConversationChain( llm=llm, memory=ConversationSummaryMemory(llm=llm) ) # 示例对话 # 进行多轮对话 for i in range(1, 5): user_input = f"这是第{i}轮对话的内容。" response = conversation(user_input) print(f"第{i}轮 - AI回应:", response) # 打印每轮对话后的摘要记忆 print(f"第{i}轮后的记忆摘要:", conversation.memory.buffer)
当然这种方法也有不足之处:
这是一种在对话中利用知识图谱(Knowledge Graph, KG)的记忆机制。它通过从对话中提取实体和事件,并将它们组织成知识图谱的形式,从而实现更高级的记忆和推理能力。
示例代码:
from langchain.llms import OpenAI from langchain.chains import ConversationChain from langchain.chains.conversation.memory import ConversationKGMemory # 初始化大型语言模型 api_key = "你的api密钥" api_url = "你的api网址" model_name = "模型名称" # 替换为你的模型名称 llm = OpenAI(model_name=model_name, openai_api_key=api_key, openai_api_base=api_url) # 使用 ConversationKGMemory 初始化对话链 conversation = ConversationChain( llm=llm, memory=ConversationKGMemory(llm=llm) ) # 示例对话 user_input = "苹果公司是由乔布斯创立的。" response = conversation(user_input) print("AI回应:", response) # 打印知识图谱 print("当前知识图谱:", conversation.memory.kg) # 进行另一轮对话 user_input = "乔布斯是谁?" response = conversation(user_input) print("AI回应:", response) # 再次打印知识图谱 print("更新后的知识图谱:", conversation.memory.kg)
输出大概也就这样:
''' AI回应: 是的,苹果公司是由史蒂夫·乔布斯、史蒂夫·沃兹尼亚克和罗纳德·韦恩于1976年共同创立的。 当前知识图谱: { "实体": ["苹果公司", "史蒂夫·乔布斯", "史蒂夫·沃兹尼亚克", "罗纳德·韦恩"], "关系": [ {"起点": "苹果公司", "关系": "创始人", "终点": "史蒂夫·乔布斯"}, {"起点": "苹果公司", "关系": "创始人", "终点": "史蒂夫·沃兹尼亚克"}, {"起点": "苹果公司", "关系": "创始人", "终点": "罗纳德·韦恩"} ] } AI回应: 史蒂夫·乔布斯是苹果公司的联合创始人之一,也是一位著名的企业家和发明家。 更新后的知识图谱: { "实体": ["苹果公司", "史蒂夫·乔布斯", "史蒂夫·沃兹尼亚克", "罗纳德·韦恩"], "关系": [ {"起点": "苹果公司", "关系": "创始人", "终点": "史蒂夫·乔布斯"}, {"起点": "苹果公司", "关系": "创始人", "终点": "史蒂夫·沃兹尼亚克"}, {"起点": "苹果公司", "关系": "创始人", "终点": "罗纳德·韦恩"}, {"起点": "史蒂夫·乔布斯", "关系": "职业", "终点": "企业家"} ] } '''
结构化知识:通过构建知识图谱,它能够以结构化的方式存储和管理信息,有助于更有效地组织和检索知识。
深度理解和推理:知识图谱支持对实体之间的关系进行深入理解和逻辑推理,这对于复杂的对话和问题解答非常有用。
上下文保持:它能够在对话过程中保持和更新重要的上下文信息,提高对话的连贯性和相关性。
动态更新:知识图谱可以根据新的对话输入动态更新,使得记忆保持最新状态。
实现复杂性:构建和维护知识图谱比简单的记忆机制要复杂得多,需要更高级的算法和处理能力。
依赖于准确的实体识别和关系提取:如果实体识别或关系提取不准确,可能会导致知识图谱中的错误或误解。
处理时间和资源消耗:构建和更新知识图谱可能需要更多的计算资源和处理时间,尤其是在处理大量数据时。
灵活性和泛化能力的限制:知识图谱可能过于依赖特定领域的知识,对于泛化或跨领域的对话可能存在限制。
不同的对话记忆机制适用于不同的对话场景。
ConversationBufferMemory适用于需要完整上下文的场景,
ConversationBufferWindowMemory适用于需要控制内存的场景,
ConversationSummaryMemory适用于需要精炼信息的场景,
ConversationKGMemory适用于需要深度理解和推理的复杂场景。选择记忆机制时,需根据具体需求权衡其优劣势。
LangChain基础3 - Memory 存储模块详解 - OpenAI 聊天机器人
什么是 LangChain?
LangChain的记忆组件
Langchain实聊天机器人
LangChain大模型应用开发指南-大模型Memory不止于对话
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。