支持向量存储
VectorStoreRetrieverMemory
将记忆存储在向量存储中,并在每次调用时查询最“显著”的前K个文档。
与大多数其他记忆类不同,它不明确跟踪交互的顺序。
在这种情况下,“文档”是先前的对话片段。这可以用来引用AI在对话早期告诉的相关信息。
from datetime import datetime
from langchain_openai import OpenAIEmbeddings
from langchain_openai import OpenAI
from langchain.memory import VectorStoreRetrieverMemory
from langchain.chains import ConversationChain
from langchain_core.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({}), {})
创建VectorStoreRetrieverMemory
从任何向量存储检索器实例化内存对象。
# 在实际使用中,您可以将“k”设置为较高的值,这里我们使用k=1以显示向量查找仍然返回语义相关信息
retriever = vectorstore.as_retriever(search_kwargs=dict(k=1))
memory = VectorStoreRetrieverMemory(retriever=retriever)
# 当添加到代理器时,内存对象可以保存对话或使用的工具的相关信息
memory.save_context({"input": "我最喜欢的食物是比萨饼"}, {"output": "这是个好消息"})
memory.save_context({"input": "我最喜欢的运动是足球"}, {"output": "..."})
memory.save_context({"input": "我不喜欢凯尔特人队"}, {"output": "好的"})
print(memory.load_memory_variables({"prompt": "我应该看什么运动?"})["history"])
input: 我最喜欢的运动是足球
output: ...
在链中使用
让我们通过一个示例来演示,再次设置verbose=True
以便查看提示。
llm = OpenAI(temperature=0) # 可以是任何有效的LLM
_DEFAULT_TEMPLATE = """以下是AI与人类之间的友好对话。AI健谈,提供了很多上下文的具体细节。如果AI不知道问题的答案,它会诚实地说它不知道。
先前对话的相关片段:
{history}
(如果不相关,您不需要使用这些信息)
当前对话:
人类:{input}
AI:"""
PROMPT = PromptTemplate(
input_variables=["history", "input"], template=_DEFAULT_TEMPLATE
)
conversation_with_summary = ConversationChain(
llm=llm,
prompt=PROMPT,
memory=memory,
verbose=True
)
conversation_with_summary.predict(input="你好,我叫Perry,怎么样?")
> 进入新的ConversationChain链...
格式化后的提示:
以下是AI与人类之间的友好对话。AI健谈,提供了很多上下文的具体细节。如果AI不知道问题的答案,它会诚实地说它不知道。
先前对话的相关片段:
输入:我最喜欢的食物是比萨饼
输出:这是个好消息
(如果不相关,您不需要使用这些信息)
当前对话:
人类:你好,我叫Perry,怎么样?
AI:
> 完成链
“嗨Perry,我很好。你呢?”
# 这里展示了与篮球相关的内容
conversation_with_summary.predict(input="我最喜欢的运动是什么?")
> 进入新的ConversationChain链...
格式化后的提示:
以下是AI与人类之间的友好对话。AI健谈,提供了很多上下文的具体细节。如果AI不知道问题的答案,它会诚实地说它不知道。
先前对话的相关片段:
输入:我最喜欢的运动是足球
输出:...
(如果不相关,您不需要使用这些信息)
当前对话:
人类:我最喜欢的运动是什么?
AI:
> 完成链
'你之前告诉我你最喜欢的运动是足球。'
# 即使语言模型是无状态的,由于获取了相关的记忆,它可以“推理”出时间的概念。
# 对记忆和数据进行时间戳是有用的,以便让代理程序确定时态相关性
conversation_with_summary.predict(input="我的最爱是什么食物")
> 进入新的ConversationChain链...
格式化后的提示:
以下是AI与人类之间的友好对话。AI健谈,提供了很多上下文的具体细节。如果AI不知道问题的答案,它会诚实地说它不知道。
先前对话的相关片段:
输入:我最喜欢的食物是比萨饼
输出:这是个好消息
(如果不相关,您不需要使用这些信息)
当前对话:
人类:我的最爱是什么食物
AI:
> 完成链
'你说过你最喜欢的食物是比萨饼。'
# 对话中的记忆会被自动存储,
# 由于此查询最符合上述引言聊天,代理程序能够“记住”用户的名字。
conversation_with_summary.predict(input="我的名字是什么?")
> 进入新的ConversationChain链...
格式化后的提示:
以下是AI与人类之间的友好对话。AI健谈,提供了很多上下文的具体细节。如果AI不知道问题的答案,它会诚实地说它不知道。
先前对话的相关片段:
输入:你好,我叫Perry,怎么样?
响应:嗨Perry,我很好。你呢?
(如果不相关,您不需要使用这些信息)
当前对话:
人类:我的名字是什么?
AI:
> 完成链
'你的名字是Perry。'