Memory

概述

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

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

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

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

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

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

记忆的查询:

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

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

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

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

ConversationChain中的记忆

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

# 导入所需的库
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)

打印ConversationChain中的内置提示模板

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:

两个参数:

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

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

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

缓冲记忆:ConversationBufferMemory

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

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

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

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)

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

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)

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

记忆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个人参果。虽然这个数字已经很多了,但对于猪八戒来说可能只是小意思。不过,我还是希望他能够注意自己的健康,不要贪吃过量。

对话缓存

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

将历史记录提取为字符串

memory = ConversationBufferMemory()

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

res = memory.load_memory_variables({})
print(res)  # {'history': 'Human: 你是谁\nAI: 我是LangChain'}

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

memory = ConversationBufferMemory(return_messages=True) 

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

res = memory.load_memory_variables({})
print(res) # {'history': [HumanMessage(content='你是谁'), AIMessage(content='我是LangChain')]}

LLMChain中的记忆

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

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)

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

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)

在这里插入图片描述

实体记忆:ConversationEntityMemory

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

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

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)

在这里插入图片描述

知识图谱记忆:ConversationKGMemory

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

需要安装库

pip install networkx

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

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="请告诉我小明的信息"))

在这里插入图片描述

缓冲窗口记忆:ConversationBufferWindowMemory

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

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

对话记忆设置与提取

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({})

完整使用示例如下:

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)

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

记忆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个人参果。但是,我必须提醒您,这只是一个虚构的故事,所以这些细节可能并不真实。您还有其他的问题吗?'}

摘要总结记忆:ConversationSummaryMemory

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

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

核心特点:

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

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

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

优缺点:

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

对于较短的对话可能会增加Token使用量。同时,对话历史的记忆完全依赖于中间摘要LLM的能力,需要为摘要LLM分配Token,增加成本且未限制对话长度。
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)

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

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

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
)

摘要缓冲混合记忆:ConversationSummaryBufferMemory

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

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

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)

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

令牌缓冲记忆:ConversationTokenBufferMemory

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

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.max_token_limit=50 在这里插入图片描述 2.max_token_limit=100 在这里插入图片描述

向量存储库记忆:VectorStoreRetrieverMemory

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

安装Faiss,使用CPU版本:

pip install faiss-cpu

使用示例如下:

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))

在这里插入图片描述