Xata
Xata 是一个基于
PostgreSQL和Elasticsearch的无服务器数据平台。它提供了一个 Python SDK 用于与数据库交互,以及一个用于管理数据的用户界面。通过使用XataChatMessageHistory类,你可以将 Xata 数据库用于聊天会话的长期持久化存储。
本笔记本涵盖:
- 一个简单的示例,展示
XataChatMessageHistory的作用。 - 一个更复杂的示例,使用REACT代理,该代理基于知识库或文档(存储在Xata中作为向量数据库)回答问题,并且还具有可搜索的长期历史记录其过去的消息(存储在Xata中作为记忆存储)
设置
创建一个数据库
在 Xata UI 中创建一个新的数据库。你可以将其命名为任何名称,在本示例中我们将使用 langchain。Langchain 集成功能可以自动创建用于存储记忆的表,这正是我们在本示例中将使用的功能。如果你想预先创建该表,请确保其具有正确的模式,并在创建类时将 create_table 设置为 False。预先创建表可以在每次会话初始化期间节省一次与数据库的往返通信。
首先让我们安装依赖项:
%pip install --upgrade --quiet xata langchain-openai langchain langchain-community
接下来,我们需要获取 Xata 的环境变量。您可以通过访问您的 账户设置 来创建新的 API 密钥。要查找数据库 URL,请前往您所创建的数据库的设置页面。数据库 URL 应类似于:https://demo-uni3q8.eu-west-1.xata.sh/db/langchain。
import getpass
api_key = getpass.getpass("Xata API key: ")
db_url = input("Xata database URL (copy it from your DB settings):")
创建一个简单的内存存储
为了独立测试内存存储功能,让我们使用以下代码片段:
from langchain_community.chat_message_histories import XataChatMessageHistory
history = XataChatMessageHistory(
session_id="session-1", api_key=api_key, db_url=db_url, table_name="memory"
)
history.add_user_message("hi!")
history.add_ai_message("whats up?")
上述代码创建了一个 ID 为 session-1 的会话,并在其中存储了两条消息。运行上述代码后,如果你访问 Xata 用户界面,你应该会看到一个名为 memory 的表,并且这两条消息已添加到该表中。
您可以使用以下代码检索特定会话的消息历史记录:
history.messages
使用记忆功能在您的数据上进行对话式问答链
现在让我们看一个更复杂的示例,其中我们将OpenAI、Xata向量存储集成以及Xata内存存储集成结合起来,基于您的数据创建一个支持后续提问和历史记录的问答聊天机器人。
我们需要访问 OpenAI API,因此让我们配置 API 密钥:
import os
if "OPENAI_API_KEY" not in os.environ:
os.environ["OPENAI_API_KEY"] = getpass.getpass("OpenAI API Key:")
为了存储聊天机器人用于搜索答案的文档,请使用 Xata 界面在你的 langchain 数据库中添加一个名为 docs 的表,并添加以下列:
content类型为“文本”。用于存储Document.pageContent的值。embedding类型为 \"Vector\"。请使用你计划使用的模型对应的维度。在本笔记本中,我们使用 OpenAI 嵌入,其维度为 1536。
让我们创建向量存储并添加一些示例文档到其中:
from langchain_community.vectorstores.xata import XataVectorStore
from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings()
texts = [
"Xata is a Serverless Data platform based on PostgreSQL",
"Xata offers a built-in vector type that can be used to store and query vectors",
"Xata includes similarity search",
]
vector_store = XataVectorStore.from_texts(
texts, embeddings, api_key=api_key, db_url=db_url, table_name="docs"
)
运行上述命令后,如果你进入 Xata 用户界面,你应该会在 docs 表中看到已加载的文档及其对应的嵌入(embeddings)。
现在让我们创建一个ConversationBufferMemory,用于存储来自用户和AI的聊天消息。
from uuid import uuid4
from langchain.memory import ConversationBufferMemory
chat_memory = XataChatMessageHistory(
session_id=str(uuid4()), # needs to be unique per user session
api_key=api_key,
db_url=db_url,
table_name="memory",
)
memory = ConversationBufferMemory(
memory_key="chat_history", chat_memory=chat_memory, return_messages=True
)
现在是时候创建一个 Agent,将向量存储和聊天记忆一起使用了。
from langchain.agents import AgentType, initialize_agent
from langchain.agents.agent_toolkits import create_retriever_tool
from langchain_openai import ChatOpenAI
tool = create_retriever_tool(
vector_store.as_retriever(),
"search_docs",
"Searches and returns documents from the Xata manual. Useful when you need to answer questions about Xata.",
)
tools = [tool]
llm = ChatOpenAI(temperature=0)
agent = initialize_agent(
tools,
llm,
agent=AgentType.CHAT_CONVERSATIONAL_REACT_DESCRIPTION,
verbose=True,
memory=memory,
)
测试一下,让我们告诉代理我们的名字:
agent.run(input="My name is bob")
现在,让我们向代理询问一些关于Xata的问题:
agent.run(input="What is xata?")
请注意,它根据存储在文档库中的数据进行回答。现在,让我们问一个后续问题:
agent.run(input="Does it support similarity search?")
现在让我们测试它的记忆功能:
agent.run(input="Did I tell you my name? What is it?")