一、前言
LangChain 的记忆组件发挥着至关重要的作用,其旨在协助大语言模型(LLM)有效地留存历史对话信息。通过这一功能,使得大语言模型在对话过程中能够更出色地维持上下文的连贯性和一致性,进而能够像人类的记忆运作方式那样,进行更为自然、流畅且智能化的交互。
它仿佛是为大语言模型赋予了一种类似人类记忆的能力,让其在处理对话时,不仅能够清晰地记住之前交流的内容,还能依据这些历史信息做出更贴合语境、更富有逻辑和更具有针对性的回应,极大地提升了交互的质量和效果。
本篇学习如何正确使用ConversationEntityMemory组件。
二、术语
2.1.记忆组件
记忆组件是一种用于帮助大语言模型(LLM)记住历史对话信息的工具。大语言模型本身是无状态的,不会记住之前的对话内容,而记忆组件通过存储和管理历史对话的相关信息,让 LLM 在对话中能够更好地保持上下文,从而进行更自然和智能的交互。
2.2.ConversationEntityMemory
是 LangChain 框架中的一种记忆组件,用于记住关于特定实体的细节信息,它可以帮助语言模型在对话过程中更好地理解和处理与实体相关的内容。
2.3.load_memory_variables方法
用于获取当前存储在该记忆组件中的对话历史信息。通过调用这个方法,可以以特定的格式返回之前保存的对话内容。默认情况下,它可能会返回一个包含对话历史的变量字典,其中有一个名为"history"的变量存储了具体的对话记录。这些对话历史信息可以作为上下文提供给大语言模型,使其在生成回答时能够参考之前的对话内容,从而实现更自然和智能的交互,就像人类在对话中能够记住之前的讨论内容一样。
2.4.save_context方法
用于将对话的上下文信息保存到记忆组件对象中。
三、前提条件
3.1. 基础环境
- 操作系统:不限
3.2. 安装虚拟环境
conda create --name langchain python=3.10
conda activate langchain
pip install langchain langchain-openai langchain-community
四、技术实现
4.1.ConversationEntityMemory基础示例
import os
from langchain.chains.conversation.base import ConversationChain
from langchain.memory import ConversationEntityMemory
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
os.environ["OPENAI_API_KEY"] = "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
if __name__ == '__main__':
template = '''如果你不清楚如何回答某个问题,不要猜测,可以参考以下的上下文和已知实体信息来提供回答:
```
上下文:
{history}
```
```
实体:
{entities}
```
问题: {input}
'''
prompt = ChatPromptTemplate.from_template(template)
llm = ChatOpenAI(model_name='gpt-3.5-turbo-1106', temperature=0.1, max_tokens=512)
memory = ConversationEntityMemory(llm=llm)
memory.save_context({"input":"你好,我叫蜘蛛侠,我的好朋友包括钢铁侠,美国队长和绿巨人"},{"output":"很高兴认识你,蜘蛛侠。你所说的这些英雄角色我都很熟悉,他们确实都是非常出色的超级英雄。"})
memory.save_context({"input":"我住在广州,你呢?"}, {"output": "作为一名人工智能助理,我不居住在任何地方。"})
memory.save_context({"input":"我马上要高考了,我喜欢编程,你能推荐一些大学的对口专业吗?"}, {"output": "对于喜欢编程的学生来说,以下一些大学专业可能会很适合:1.计算机科学和技术,2.软件工程,3.信息安全,4.人工智能"})
# 创建一个对话链
conversation = ConversationChain(
llm=llm,
memory=memory,
prompt=prompt,
verbose=True
)
print(conversation.memory.entity_cache)
print(conversation.predict(input="我的好朋友有哪些?"))
上面示例代码共设置三轮历史对话内容,分别是
USER | AI | |
第一轮 | 你好,我叫蜘蛛侠,我的好朋友包括钢铁侠,美国队长和绿巨人 | 很高兴认识你,蜘蛛侠。你所说的这些英雄角色我都很熟悉,他们确实都是非常出色的超级英雄。 |
第二轮 | 我住在广州,你呢? | 作为一名人工智能助理,我不居住在任何地方。 |
第三轮 | 我马上要高考了,我喜欢编程,你能推荐一些大学的对口专业吗? | 对于喜欢编程的学生来说,以下一些大学专业可能会很适合:1.计算机科学和技术,2.软件工程,3.信息安全,4.人工智能 |
调用结果:
说明:
1. 基于三轮的历史对话,识别出以下实体
'蜘蛛侠', '钢铁侠', '美国队长', '绿巨人', '广州', '高考', '编程', '计算机科学和技术', '软件工程', '信息安全', '人工智能'
4.2.ConversationEntityMemory进阶示例
指定k属性,即更新实体时要考虑的最近消息对的数量
import os
from langchain.chains.conversation.base import ConversationChain
from langchain.memory import ConversationEntityMemory
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
os.environ["OPENAI_API_KEY"] = "sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
if __name__ == '__main__':
template = '''如果你不清楚如何回答某个问题,不要猜测,可以参考以下的上下文和已知实体信息来提供回答:
```
上下文:
{history}
```
```
实体:
{entities}
```
问题: {input}
'''
prompt = ChatPromptTemplate.from_template(template)
llm = ChatOpenAI(model_name='gpt-3.5-turbo-1106', temperature=0.1, max_tokens=512)
memory = ConversationEntityMemory(llm=llm,k=2)
memory.save_context({"input":"你好,我叫蜘蛛侠,我的好朋友包括钢铁侠,美国队长和绿巨人"},{"output":"很高兴认识你,蜘蛛侠。你所说的这些英雄角色我都很熟悉,他们确实都是非常出色的超级英雄。"})
memory.save_context({"input":"我住在广州,你呢?"}, {"output": "作为一名人工智能助理,我不居住在任何地方。"})
memory.save_context({"input":"我马上要高考了,我喜欢编程,你能推荐一些大学的对口专业吗?"}, {"output": "对于喜欢编程的学生来说,以下一些大学专业可能会很适合:1.计算机科学和技术,2.软件工程,3.信息安全,4.人工智能"})
# 创建一个对话链
conversation = ConversationChain(
llm=llm,
memory=memory,
prompt=prompt,
verbose=True
)
print(conversation.memory.entity_cache)
print(conversation.predict(input="我的好朋友有哪些?"))
调用结果:
说明:
1. 由于设置k=2,即保留最近两轮对话内容,
Human: 我住在广州,你呢?
AI: 作为一名人工智能助理,我不居住在任何地方。
Human: 我马上要高考了,我喜欢编程,你能推荐一些大学的对口专业吗?
AI: 对于喜欢编程的学生来说,以下一些大学专业可能会很适合:1.计算机科学和技术,2.软件工程,3.信息安全,4.人工智能
2. 在上述两轮对话中,未能提取出实体信息