GPT之路(九) LangChain - Memory
记忆封装 - Memory (langchain memory)
Memory:这里不是物理内存,从文本的角度,可以理解为“上文”、“历史记录”或者说“记忆力”的管理
ConversationBufferMemory可也用来保留会话信息
In [ ]:
from langchain.memory import ConversationBufferMemory
history = ConversationBufferMemory()
history.save_context({"input":"electronic是做什么的?"},{"output":"Electron是一个使用JavaScript、HTML和CSS构建桌面应用程序的框架"})
print(history.load_memory_variables({}))
history.save_context({"input":"给我一个它的教程链接?"},{"output":"https://www.electronjs.org/zh/docs/latest/tutorial/quick-start"})
print(history.load_memory_variables({}))
{'history': 'Human: electronic是做什么的?\nAI: Electron是一个使用JavaScript、HTML和CSS构建桌面应用程序的框架'} {'history': 'Human: electronic是做什么的?\nAI: Electron是一个使用JavaScript、HTML和CSS构建桌面应用程序的框架\nHuman: 给我一个它的教程链接?\nAI: https://www.electronjs.org/zh/docs/latest/tutorial/quick-start'}
ChatMessageHistory可也用来保留会话信息,是基于Message的
In [ ]:
#Message格式
from langchain.memory import ChatMessageHistory
history = ChatMessageHistory()
history.add_user_message("electronic是做什么的?")
history.add_ai_message("Electron是一个使用JavaScript、HTML和CSS构建桌面应用程序的框架")
print(history)
messages=[HumanMessage(content='electronic是做什么的?', additional_kwargs={}, example=False), AIMessage(content='Electron是一个使用JavaScript、HTML和CSS构建桌面应用程序的框架', additional_kwargs={}, example=False)]
ConversationBufferWindowMemory可也用来保留会话窗口轮次
In [ ]:
#保留指定window的历史会话信息
from langchain.memory import ConversationBufferWindowMemory
window = ConversationBufferWindowMemory(k=8) #k=8表示保留最近8轮的历史会话信息
window.save_context({"input": "第一轮问"}, {"output": "第一轮答"})
window.save_context({"input": "第二轮问"}, {"output": "第二轮答"})
window.save_context({"input": "第三轮问"}, {"output": "第三轮答"})
window.save_context({"input": "第四轮问"}, {"output": "第四轮答"})
window.save_context({"input": "第五轮问"}, {"output": "第五轮答"})
window.save_context({"input": "第六轮问"}, {"output": "第六轮答"})
window.save_context({"input": "第七轮问"}, {"output": "第七轮答"})
window.save_context({"input": "第八轮问"}, {"output": "第八轮答"})
window.save_context({"input": "第九轮问"}, {"output": "第九轮答"})
window.save_context({"input": "第十轮问"}, {"output": "第十轮答"})
print(window.load_memory_variables({}))
{'history': 'Human: 第三轮问\nAI: 第三轮答\nHuman: 第四轮问\nAI: 第四轮答\nHuman: 第五轮问\nAI: 第五轮答\nHuman: 第六轮问\nAI: 第六轮答\nHuman: 第七轮问\nAI: 第七轮答\nHuman: 第八轮问\nAI: 第八轮答\nHuman: 第九轮问\nAI: 第九轮答\nHuman: 第十轮问\nAI: 第十轮答'}
自动对历史信息做摘要:ConversationSummaryMemory
In [ ]:
import warnings
warnings.filterwarnings("ignore")
from langchain.llms import OpenAI
from langchain.chat_models import ChatOpenAI
import os
from dotenv import load_dotenv
load_dotenv()
api_key = os.environ["OPENAI_B_API_KEY"]
api_base = os.environ["OPENAI_B_API_BASE"]
In [ ]:
from langchain.memory import ConversationSummaryMemory
from langchain.llms import OpenAI
memory = ConversationSummaryMemory(
llm=OpenAI(temperature=0,openai_api_base=api_base ,openai_api_key=api_key,verbose=True),
# buffer="The conversation is between a developer and Electron develop expert."
buffer="以中文表示"
)
memory.save_context({"input":"'Electron'是做什么的?"},{"output":"'Electron'是一个使用JavaScript、HTML和CSS构建桌面应用程序的框架"})
print(memory.load_memory_variables({}))
{'history': "\n以中文表示\n人类问AI关于'Electron'的事情,AI回答它是一个使用JavaScript、HTML和CSS构建桌面应用程序的框架。"}
用向量数据库存储记忆
In [ ]:
from datetime import datetime
from langchain.embeddings.openai import OpenAIEmbeddings
from langchain.llms import OpenAI
from langchain.memory import VectorStoreRetrieverMemory
from langchain.chains import ConversationChain
from langchain.prompts import PromptTemplate
import faiss
from langchain.docstore import InMemoryDocstore
from langchain.vectorstores import FAISS
embedding_size = 1536 # OpenAIEmbeddings的维度
index = faiss.IndexFlatL2(embedding_size)
embedding_fn = OpenAIEmbeddings().embed_query
vectorstore = FAISS(embedding_fn, index, InMemoryDocstore({}), {})
# 实际应用中k可以稍大一些,这里k=1演示方便
retriever = vectorstore.as_retriever(search_kwargs=dict(k=3))
memory = VectorStoreRetrieverMemory(retriever=retriever)
# 把记忆存在向量数据库中
memory.save_context({"input":"我喜欢爬山"},{"output":"不错啊"})
memory.save_context({"input":"我喜欢打羽毛球"},{"output":"nice"})
memory.save_context({"input":"我想去吃烤肉"},{"output":"附近有三家烤肉店"})
memory.save_context({"input":"他们家水果很便宜"},{"output":"有多便宜?"})
# 聊到相关话题,检索之前的记忆
print(memory.load_memory_variables({"prompt": "明天放假了吃点哈?"})["history"])
input: 他们家水果很便宜 output: 有多便宜? input: 我想去吃烤肉 output: 附近有三家烤肉店 input: 我喜欢爬山 output: 不错啊