当前位置:   article > 正文

LangChain之内存记忆 ( Memory )_langchainmemory

langchainmemory

Memory

概述

大多数LLM应用都具有对话功能,如聊天机器人,记住先前的交互非常关键。对话的重要一环是能够引用之前提及的信息,这些信息需要进行存储,因此将这种存储过去交互信息的能力称为记忆 ( Memory )

默认情况下,链式模型和代理模型都是无状态的,这意味着它们会独立处理每个传入的查询,类似于底层的LLMs和聊天模型本身的处理方式。当有了记忆之后,每个链都定义了一些需要特定输入的核心执行逻辑。其中一些输入直接来自用户,但其中一些输入可以来自记忆。在给定的运行中,链将与其记忆系统交互两次。

记忆系统需要支持两种基本操作:读取和写入。

1.在接收到初始用户输入之后但在执行核心逻辑之前,链将从其内存系统中读取并增强用户输入。

2.在执行核心逻辑之后但在返回答案之前,链会将当前运行的输入和输出写入内存,以便在将来的运行中引用它们。 在这里插入图片描述 记忆的存储:

LangChain记忆内存模块的核心组件之一是其消息存储机制,该机制采用了一系列集成方案,用以管理聊天信息的存储。从动态的内存列表到持久化的数据库系统,这些集成确保了信息的即时访问与长期保留,从而为LangChain提供了一个高效、可靠的数据管理框架。

记忆的查询:

复制代码
简单的记忆系统:可能只会在每次运行时返回最新消息

稍微复杂的记忆系统:可能会返回过去 K 条消息的简洁摘要

更复杂的记忆系统:可能会从存储的消息中提取实体,并仅返回有关当前运行中引用的实体的信息

自定义记忆系统:每个应用程序对于内存记忆查询方式的要求可能有所不同,因此可以在需要时编写自己的自定义记忆系统
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

ConversationChain中的记忆

ConversationChain提供了包含AI角色和人类角色的对话摘要格式,这个对话格式和记忆机制结合得非常紧密。ConversationChain实际上是对Memory和LLMChain进行了封装,简化了初始化Memory的步骤。

python
复制代码
# 导入所需的库
from langchain_openai import OpenAI
from langchain.chains.conversation.base import ConversationChain

# 初始化大语言模型
llm = OpenAI(
    temperature=0.5,
    model_name="gpt-3.5-turbo-instruct"
)

# 初始化对话链
conv_chain = ConversationChain(llm=llm)

# 打印对话的模板
print(conv_chain.prompt.template)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

打印ConversationChain中的内置提示模板

python
复制代码
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:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

两个参数:

bash
复制代码
{history}:存储会话记忆的地方,也就是人类和人工智能之间对话历史的信息。

{input} :新输入的地方,可以把它看成是和ChatGPT对话时,文本框中的输入。
  • 1
  • 2
  • 3
  • 4
  • 5

有了history参数以及Human和AI这两个角色,就可以将历史对话信息存储在提示模板中,并在新一轮对话中以新的提示内容的形式传递给模型。这就是记忆机制的原理。

缓冲记忆:ConversationBufferMemory

在LangChain中,ConversationBufferMemory是一种非常简单的缓冲记忆,可以实现最简单的记忆机制,它只在缓冲区中保存聊天消息列表并将其传递到提示模板中。

通过记忆机制,LLM能够理解之前的对话内容。直接将存储的所有内容给LLM,因为大量信息意味着新输入中包含更多的Token,导致响应时间变慢和成本增加。此外,当达到LLM的令牌数限制时,太长的对话无法被记住。

使用memory.chat_memory.add_XX_message()方式添加对话记忆消息

python
复制代码
from langchain_openai import OpenAI
from langchain.memory import ConversationBufferMemory
from langchain.chains.conversation.base import ConversationChain

# 初始化大模型
llm = OpenAI(model="gpt-3.5-turbo-instruct", temperature=0)

# 添加聊天对话记忆
memory = ConversationBufferMemory()
memory.chat_memory.add_user_message("你是谁?")
memory.chat_memory.add_ai_message("你好,我是LangChain专家。")

# 初始化对话链
conversation = ConversationChain(llm=llm, memory=memory)

# 提问
res = conversation.invoke({"input": "你是谁?"})
print(res)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

记忆生效,执行回复如下 在这里插入图片描述 在对话过程中进行聊天消息的记忆存储

python
复制代码
from langchain_openai import OpenAI
from langchain.chains.conversation.base 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.invoke("今天早上猪八戒吃了2个人参果。")
print("记忆1: ", conversation.memory.buffer)
print()

conversation.invoke("下午猪八戒吃了1个人参果。")
print("记忆2: ", conversation.memory.buffer)
print()

conversation.invoke("晚上猪八戒吃了3个人参果。")
print("记忆3: ", conversation.memory.buffer)
print()

conversation.invoke("猪八戒今天一共吃了几个人参果?")
print("记忆4提示: ", conversation.prompt.template)
print("记忆4: ", conversation.memory.buffer)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

从打印可以看出: 聊天历史信息被传入ConversationChain的提示模板中的{history}参数,从而构建了包含聊天记录的新提示输入。

python
复制代码
记忆1:  Human: 今天早上猪八戒吃了2个人参果。
AI:  哇,猪八戒真是个贪吃的家伙!人参果是一种非常珍贵的水果,据说能够延年益寿,增强体力。它们通常生长在高山上,采摘起来非常困难。猪八戒应该是花了不少功夫才能吃到两个人参果呢。

记忆2:  Human: 今天早上猪八戒吃了2个人参果。
AI:  哇,猪八戒真是个贪吃的家伙!人参果是一种非常珍贵的水果,据说能够延年益寿,增强体力。它们通常生长在高山上,采摘起来非常困难。猪八戒应该是花了不少功夫才能吃到两个人参果呢。
Human: 下午猪八戒吃了1个人参果。
AI:  哦,那么猪八戒一天总共吃了3个人参果了。这个数量已经超过了一般人的想象,但对于猪八戒来说可能只是小菜一碟。不过,我还是建议他不要贪吃,毕竟人参果也是有限的资源,我们要珍惜它们。

记忆3:  Human: 今天早上猪八戒吃了2个人参果。
AI:  哇,猪八戒真是个贪吃的家伙!人参果是一种非常珍贵的水果,据说能够延年益寿,增强体力。它们通常生长在高山上,采摘起来非常困难。猪八戒应该是花了不少功夫才能吃到两个人参果呢。
Human: 下午猪八戒吃了1个人参果。
AI:  哦,那么猪八戒一天总共吃了3个人参果了。这个数量已经超过了一般人的想象,但对于猪八戒来说可能只是小菜一碟。不过,我还是建议他不要贪吃,毕竟人参果也是有限的资源,我们要珍惜它们。
Human: 晚上猪八戒吃了3个人参果。
AI:   哇,猪八戒今天的人参果摄入量已经达到6个了!这已经是一个非常惊人的数字了。人参果虽然有益健康,但也不能贪多,否则可能会有副作用。我建议猪八戒明天少吃一点,让身体有时间消化吸收。

记忆4提示:  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:
记忆4:  Human: 今天早上猪八戒吃了2个人参果。
AI:  哇,猪八戒真是个贪吃的家伙!人参果是一种非常珍贵的水果,据说能够延年益寿,增强体力。它们通常生长在高山上,采摘起来非常困难。猪八戒应该是花了不少功夫才能吃到两个人参果呢。
Human: 下午猪八戒吃了1个人参果。
AI:  哦,那么猪八戒一天总共吃了3个人参果了。这个数量已经超过了一般人的想象,但对于猪八戒来说可能只是小菜一碟。不过,我还是建议他不要贪吃,毕竟人参果也是有限的资源,我们要珍惜它们。
Human: 晚上猪八戒吃了3个人参果。
AI:   哇,猪八戒今天的人参果摄入量已经达到6个了!这已经是一个非常惊人的数字了。人参果虽然有益健康,但也不能贪多,否则可能会有副作用。我建议猪八戒明天少吃一点,让身体有时间消化吸收。
Human: 猪八戒今天一共吃了几个人参果?
AI:  今天猪八戒一共吃了6个人参果。虽然这个数字已经很多了,但对于猪八戒来说可能只是小意思。不过,我还是希望他能够注意自己的健康,不要贪吃过量。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

对话缓存

ConversationBufferMemory允许存储消息,然后以变量的形式提取这些消息

将历史记录提取为字符串

python
复制代码
memory = ConversationBufferMemory()

memory.save_context({"input":"你是谁"},{"output":"我是LangChain"})

res = memory.load_memory_variables({})
print(res)  # {'history': 'Human: 你是谁\nAI: 我是LangChain'}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

将历史记录作为消息列表获取,在使用聊天模型时很有用

python
复制代码
memory = ConversationBufferMemory(return_messages=True) 

memory.save_context({"input":"你是谁"},{"output":"我是LangChain"})

res = memory.load_memory_variables({})
print(res) # {'history': [HumanMessage(content='你是谁'), AIMessage(content='我是LangChain')]}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

LLMChain中的记忆

在LLMChain中使用Memory记忆一起使用

python
复制代码
from langchain_openai import OpenAI
from langchain.memory import ConversationBufferMemory
from langchain.chains.llm import LLMChain

# 初始化大模型
llm = OpenAI(model="gpt-3.5-turbo-instruct", temperature=0)

# # 创建提示   有两个输入键:实际输入与来自记忆类的输入 需确保PromptTemplate和ConversationBufferMemory中的键匹配
template = """你可以与人类对话。

当前对话: {chat_history}

人类问题: {question}

回复:
"""
prompt = PromptTemplate(
    input_variables=["chat_history", "question"], template=template
)

# 创建ConversationBufferMemory
memory = ConversationBufferMemory(memory_key="chat_history")

# 初始化链
chain = LLMChain(llm=llm,  prompt=prompt, memory=memory)

# 提问
res = chain.invoke({"question": "你是LangChain专家"})
print(str(res) + "\n")

res = chain.invoke({"question": "你是谁?"})
print(res)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

在这里插入图片描述 如果使用聊天模型,使用结构化的聊天消息可能会有更好的性能。

python
复制代码
from langchain_openai import ChatOpenAI
from langchain.memory import ConversationBufferMemory
from langchain.chains.llm import LLMChain
from langchain_core.messages import SystemMessage
from langchain_core.prompts import MessagesPlaceholder, HumanMessagePromptTemplate, ChatPromptTemplate


# 初始化大模型
llm = ChatOpenAI(model="gpt-3.5-turbo", temperature=0)

# 使用ChatPromptTemplate设置聊天提示
prompt = ChatPromptTemplate.from_messages(
    [
        SystemMessage(content="你是一个与人类对话的机器人。"),
        MessagesPlaceholder(variable_name="chat_history"),
        HumanMessagePromptTemplate.from_template("{question}"),
    ]
    )

# 创建ConversationBufferMemory
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)

# 初始化链
chain = LLMChain(llm=llm,  prompt=prompt, memory=memory)

# 提问
res = chain.invoke({"question": "你是LangChain专家"})
print(str(res) + "\n")

res = chain.invoke({"question": "你是谁?"})
print(res)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

在这里插入图片描述

实体记忆:ConversationEntityMemory

在LangChain 中,ConversationEntityMemory是实体记忆,它可以跟踪对话中提到的实体,在对话中记住关于特定实体的给定事实。它提取关于实体的信息(使用LLM),并随着时间的推移建立对该实体的知识(使用LLM)。

使用它来存储和查询对话中引用的各种信息,比如人物、地点、事件等。

python
复制代码
from langchain.chains.conversation.base import ConversationChain
from langchain.memory import ConversationEntityMemory
from langchain.memory.prompt import ENTITY_MEMORY_CONVERSATION_TEMPLATE
from langchain_openai import OpenAI


# 初始化大语言模型
llm = OpenAI(temperature=0)


conversation = ConversationChain(
    llm=llm,
    verbose=True,
    prompt=ENTITY_MEMORY_CONVERSATION_TEMPLATE,
    memory=ConversationEntityMemory(llm=llm)
)

# 开始对话
conversation.predict(input="你好,我是小明。我最近在学习 LangChain。")
conversation.predict(input="我最喜欢的编程语言是 Python。")
conversation.predict(input="我住在北京。")

# 查询对话中提到的实体
res = conversation.memory.entity_store.store
print(res)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

在这里插入图片描述

知识图谱记忆:ConversationKGMemory

ConversationKGMemory是知识图谱对话记忆,用于在对话过程中存储和检索知识图谱(Knowledge Graph)数据。这种记忆类型使用知识图谱来重现记忆。

需要安装库

python
复制代码
pip install networkx
  • 1
  • 2
  • 3

在历史对话中设置出现某些信息,然后使用知识图谱记忆构建这些信息成一个完整全面的知识图谱。

python
复制代码
from langchain.chains.conversation.base import ConversationChain
from langchain_community.memory.kg import ConversationKGMemory
from langchain_openai import OpenAI


# 初始化大语言模型
llm = OpenAI(temperature=0)

# 创建 ConversationKGMemory
kg_memory = ConversationKGMemory(
    llm=llm,
    verbose=True,
)
kg_memory.save_context({"input": "你好,小明是一名程序员。"},{"output":"程序很棒啊"})
kg_memory.save_context({"input": "小明最喜欢的编程语言是Python,因为它简单易学。"},{"output":"没错,人生苦短,我用Python"})
kg_memory.save_context({"input": "小明住在北京,那里的空气质量有时不太好。"},{"output":"确实是的"})

# print(kg_memory.load_memory_variables({"input":"请告诉我小明的信息"}))

# 创建 ConversationChain,并将 kg_memory 作为参数传入
conversation = ConversationChain(
    llm=llm,
    memory=kg_memory,
    verbose=True,
)

# 开始对话
# print(conversation.predict(input="你好,小明是一名程序员。"))
# print(conversation.predict(input="小明最喜欢的编程语言是Python,因为它简单易学。"))
# print(conversation.predict(input="小明住在北京,那里的空气质量有时不太好。"))
#

print(conversation.predict(input="请告诉我小明的信息"))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

在这里插入图片描述

缓冲窗口记忆:ConversationBufferWindowMemory

ConversationBufferWindowMemory是一种缓冲窗口记忆,它只保存最新最近的几次人类和AI的互动。它基于之前的缓冲记忆思想,增加了一个窗口值k。这意味着只保留一定数量的过去互动,然后“忘记”之前的互动。

缓冲窗口记忆不适合记住遥远的互动,但它在限制使用的Token数量方面表现优异。如果只需记住最近的互动,缓冲窗口记忆是一个不错的选择。

对话记忆设置与提取

python
复制代码
from langchain.memory import ConversationBufferWindowMemory

# 只保留最近1次交互在记忆中
memory = ConversationBufferWindowMemory(k=1)

# 只保留最近1次交互在记忆中 return_messages=True:适用于聊天模型
# memory = ConversationBufferWindowMemory(k=1, return_messages=True)

memory.save_context({"input":"你是谁"},{"output":"我是LangChain"})

memory.load_memory_variables({})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

完整使用示例如下:

python
复制代码
from langchain_openai import OpenAI
from langchain.chains.conversation.base import ConversationChain
from langchain.chains.conversation.memory import ConversationBufferWindowMemory

# 初始化大语言模型
llm = OpenAI(temperature=0.5, model_name="gpt-3.5-turbo-instruct")

# 初始化对话链
conversation = ConversationChain(
    llm=llm,
    # k=1,窗口只会记住与AI之间的最新互动,即保留上一次的人类和AI的回应
    memory=ConversationBufferWindowMemory(k=1)
)

conversation.invoke("今天早上猪八戒吃了2个人参果。")
print("记忆1: ", conversation.memory.buffer)
print()

conversation.invoke("下午猪八戒吃了1个人参果。")
print("记忆2: ", conversation.memory.buffer)
print()

result = conversation.invoke("晚上猪八戒吃了3个人参果。")
print("记忆3: ", result)
print()

result = conversation.invoke("猪八戒今天一共吃了几个人参果?")
print("记忆4提示: ", conversation.prompt.template)
print("记忆4: ", result)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

模型在回答新问题的时候,对之前的问题进行了总结,即使窗口大小k=1,还是能够回答正确答案。

python
复制代码
记忆1:  Human: 今天早上猪八戒吃了2个人参果。
AI:  您好!根据我所知,猪八戒是《西游记》中的一个角色,他是唐僧的徒弟,也是一个猪妖。人参果是一种神奇的药物,据说可以让人长生不老。但是猪八戒吃了2个人参果,这听起来有点不太可能。我不知道您是从哪里得到这个信息的,但是根据我的计算,猪八戒可能会因为吃了太多人参果而变得更加聪明和有智慧。不过,我也不能确定这个信息的准确性,因为这只是一个虚构的故事。您有什么其他的问题吗?

记忆2:  Human: 下午猪八戒吃了1个人参果。
AI:   哦,下午猪八戒又吃了1个人参果吗?那么他现在应该已经吃了3个人参果了。如果这个消息是真实的,那么猪八戒可能已经变得非常聪明和有智慧了。但是,我仍然不能确认这个消息的真实性,因为这只是一个虚构的故事。您还有其他的问题吗?

记忆3:  {'input': '晚上猪八戒吃了3个人参果。', 'history': 'Human: 下午猪八戒吃了1个人参果。\nAI:   哦,下午猪八戒又吃了1个人参果吗?那么他现在应该已经吃了3个人参果了。如果这个消息是真实的,那么猪八戒可能已经变得非常聪明和有智慧了。但是,我仍然不能确认这个消息的真实性,因为这只是一个虚构的故事。您还有其他的问题吗?', 'response': ' 哦,晚上猪八戒又吃了3个人参果吗?那么他现在应该已经吃了6个人参果了。如果这个消息是真实的,那么猪八戒一定变得非常聪明和有智慧了。但是,我仍然不能确认这个消息的真实性,因为这只是一个虚构的故事。您还有其他的问题吗?'}

记忆4提示:  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:
记忆4:  {'input': '猪八戒今天一共吃了几个人参果?', 'history': 'Human: 晚上猪八戒吃了3个人参果。\nAI:  哦,晚上猪八戒又吃了3个人参果吗?那么他现在应该已经吃了6个人参果了。如果这个消息是真实的,那么猪八戒一定变得非常聪明和有智慧了。但是,我仍然不能确认这个消息的真实性,因为这只是一个虚构的故事。您还有其他的问题吗?', 'response': ' 据我所知,猪八戒今天一共吃了6个人参果。但是,我必须提醒您,这只是一个虚构的故事,所以这些细节可能并不真实。您还有其他的问题吗?'}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

摘要总结记忆:ConversationSummaryMemory

ConversationSummaryMemory这种类型的记忆随着时间的推移创建对话的摘要。对话摘要记忆随着对话的发生而总结对话,并在记忆中存储当前的摘要。

ConversationSummaryMemory这种记忆对于较长的对话最有用,可以避免过度使用Token,因为将过去的信息历史以原文形式保留在提示中会占用太多的Token。

核心特点:

复制代码
摘要对话:每次新的互动发生时对对话进行摘要,而不是保存完整的对话历史。

使用LLM进行摘要:摘要功能由另一个LLM驱动,AI自行进行对话摘要。

适合长对话:长对话时效果明显,虽然最初使用的 Token 数量较多,随着对话进行,摘要方法增长速度减慢,与常规缓冲内存模型相比具有优势。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

优缺点:

复制代码
是可以减少长对话中使用的Token数量,记录更多轮的对话信息,易于理解。

对于较短的对话可能会增加Token使用量。同时,对话历史的记忆完全依赖于中间摘要LLM的能力,需要为摘要LLM分配Token,增加成本且未限制对话长度。
  • 1
  • 2
  • 3
  • 4
python
复制代码
from langchain_openai import OpenAI
from langchain.memory import ConversationSummaryMemory, ChatMessageHistory


# 初始化大模型
llm = OpenAI(temperature=0)

# 使用ChatMessageHistory初始化历史记忆,在加载过程中计算摘要
history = ChatMessageHistory()
history.add_user_message("你好,你能帮助我解决问题吗?")
history.add_ai_message("好啊,没问题,请告诉我你的问题")

# 创建摘要Memory
memory = ConversationSummaryMemory.from_messages(
    llm=llm,
    chat_memory=history,
    return_messages=True
)

# 创建ConversationChain
conversation_with_summary = ConversationChain(
    llm=llm,
    memory=memory,
    verbose=True
)

# 打印
res = conversation_with_summary.predict(input="嗨,什么情况?")
print(res)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

执行日志可以看出生成摘要:人类向人工智能打招呼,并询问它是否可以帮助解决问题。人工智能同意并要求说明问题。 然后LLM基于摘要进行了回答。 在这里插入图片描述

可以使用之前生成的摘要来加速初始化,并避免通过直接初始化来重新生成摘要。

python
复制代码
memory = ConversationSummaryMemory(
    llm=llm,
    buffer="The human greets the AI in Chinese. The AI responds with a friendly greeting in Chinese",
    chat_memory=history,
    return_messages=True
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

摘要缓冲混合记忆:ConversationSummaryBufferMemory

ConversationSummaryBufferMemory对话摘要缓冲记忆是一种混合记忆模型,结合了ConversationSummaryMemory和ConversationBufferWindowMemory的特点。它旨在对对话进行摘要总结,同时保留最近互动中的原始内容,但不是简单地清除旧的交互,而是将它们编译成摘要并同时使用。它使用标记长度而不是交互数量来确定何时清除交互。

使用max_token_limit参数,让它在对话长度在200字内时记忆原始内容,在超出长度时对内容进行总结以节省Token数量。

python
复制代码
from langchain_openai import OpenAI
from langchain.chains.conversation.base import ConversationChain
from langchain.chains.conversation.memory import ConversationSummaryBufferMemory

# 初始化大语言模型
llm = OpenAI(temperature=0)

# 初始化对话链
conversation = ConversationChain(
    llm=llm,
    memory=ConversationSummaryBufferMemory(llm=llm, max_token_limit=200)
)

conversation.invoke({"input": "今天早上猪八戒吃了2个人参果。"})
print("记忆1: ", conversation.memory.buffer)
print()

conversation.invoke("下午猪八戒吃了1个人参果。")
print("记忆2: ", conversation.memory.buffer)
print()

result = conversation.predict(input="晚上猪八戒吃了3个人参果。")
print("记忆3: ", result)
print()

result = conversation.predict(input="猪八戒今天一共吃了几个人参果?")
print("记忆4: ", result)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

根据执行日志,可以看到这里摘要和缓冲区 在这里插入图片描述

令牌缓冲记忆:ConversationTokenBufferMemory

ConversationTokenBufferMemory 在内存中保持最近交互的缓冲区,并使用标记长度而不是交互数量来确定何时清除交互。

python
复制代码
from langchain_openai import OpenAI
from langchain.memory import ConversationTokenBufferMemory
from langchain.chains import ConversationChain

# 初始化大语言模型
llm = OpenAI(temperature=0)

# 使用ChatMessageHistory初始化历史记忆
memory = ConversationTokenBufferMemory(llm=llm, max_token_limit=50)
memory.save_context({"input": "今天早上猪八戒吃了2个人参果"}, {"output": "好的,我知道猪八戒今天吃了2个人参果了。"})
memory.save_context({"input": "今天中午猪八戒又吃了3个人参果"}, {"output": "好的,我知道猪八戒今天吃了5个人参果了。"})

conversation_with_summary = ConversationChain(
    llm=llm,
    memory=memory,
    verbose=True,
)
res = conversation_with_summary.predict(input="刚刚猪八戒又吃了1个人参果,那么今天猪八戒吃了多少个人参果?")
print("记忆: ", res)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

从执行日志可以看出:使用不同长度的标记,将会影响模型的记忆。

1.max_token_limit=50 在这里插入图片描述 2.max_token_limit=100 在这里插入图片描述

向量存储库记忆:VectorStoreRetrieverMemory

VectorStoreRetrieverMemory 将记忆存储在向量存储中,并在每次调用时查询前 K 个最匹配的文档。

安装Faiss,使用CPU版本:

python
复制代码
pip install faiss-cpu
  • 1
  • 2
  • 3

使用示例如下:

python
复制代码
from langchain_openai import OpenAI, OpenAIEmbeddings
from langchain.memory import VectorStoreRetrieverMemory
from langchain.chains import ConversationChain
from langchain.prompts import PromptTemplate

import faiss
from langchain.docstore import InMemoryDocstore
from langchain_community.vectorstores import FAISS

# 初始化向量存储
embedding_size = 1536  # OpenAIEmbeddings 的维度
index = faiss.IndexFlatL2(embedding_size)
embedding_fn = OpenAIEmbeddings().embed_query
vectorstore = FAISS(embedding_fn, index, InMemoryDocstore({}), {})


# 向量查找返回语义相关的信息
retriever = vectorstore.as_retriever(search_kwargs=dict(k=1))
# 相关文档信息放到memory
memory = VectorStoreRetrieverMemory(retriever=retriever)

# 当添加到代理中时,记忆对象可以保存对话中的重要信息或使用的工具
memory.save_context({"Human":"我最喜欢的食物是披萨"},{"AI":"很高兴知道"})
memory.save_context({"Human":"我喜欢的运动是跑步"},{"AI":"好的,我知道了"})
memory.save_context({"Human":"我最喜欢的运动是足球"},{"AI":"好的,我知道了"})


llm = OpenAI(temperature=0)
_DEFAULT_TEMPLATE ="""
以下是人类和人工智能之间的友好对话。人工智能很健谈,并从其上下文中提供了许多具体细节。如果人工智能不知道问题的答案,它就会如实说它不知道。

之前对话的相关片段: {history} 
(如果不相关,则无需使用这些信息)

当前对话:
Human: {input}
AI:
"""
PROMPT = PromptTemplate(
    input_variables=["history","input"], template=_DEFAULT_TEMPLATE
)

# 创建Chain
conversation_with_summary = ConversationChain(
    llm=llm,
    prompt=PROMPT,
    memory=memory,
    verbose=True
)

# 提问
res = conversation_with_summary.predict(input="我最喜欢什么运动")
print(str(res))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

在这里插入图片描述

如何系统的去学习大模型LLM ?

作为一名热心肠的互联网老兵,我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。

但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的 AI大模型资料 包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来

所有资料 ⚡️ ,朋友们如果有需要全套 《LLM大模型入门+进阶学习资源包》,扫码获取~

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/680687
推荐阅读
相关标签