本笔记本适用于以下场景:
本笔记本将带您完成一个简单的流程,设置Weaviate实例,连接到它(使用OpenAI API密钥),配置数据模式,导入数据(这将自动生成您数据的向量嵌入),并运行混合搜索(向量搜索和BM25搜索的混合)。
这是客户常见的需求,他们希望在安全环境中存储和搜索我们的嵌入,并支持生产用例,如聊天机器人、主题建模等。
Weaviate是一个开源的向量搜索引擎,它将数据对象与它们的向量一起存储。这允许将向量搜索与结构化过滤相结合。
Weaviate使用KNN算法创建一个向量优化的索引,使您的查询运行非常快。了解更多信息,请点击这里。
Weaviate让您可以使用您喜欢的ML模型,并且可以无缝扩展到数十亿个数据对象。
无论您的场景或生产设置如何,Weaviate都有适合您的选项。您可以在以下设置中部署Weaviate:
Weaviate提供四种客户端库,允许您从您的应用程序进行通信:
此外,Weaviate还有一个REST层。基本上,您可以从支持REST请求的任何语言调用Weaviate。
演示流程如下:
完成本笔记后,您应该对如何设置和使用向量数据库有基本的了解,并可以继续进行更复杂的用例,利用我们的嵌入。
所有Weaviate实例都配备有text2vec-openai模块。
该模块负责在导入(或任何CRUD操作)期间处理向量化,以及在运行查询时。
这对您来说是个好消息。使用text2vec-openai,您无需手动向量化您的数据,因为Weaviate会在必要时为您调用OpenAI。
您只需要:
在开始这个项目之前,我们需要设置以下内容:
Weaviate
实例weaviate-client
datasets
apache-beam
===========================================================
要创建 Weaviate 实例,我们有两个选项:
使用 Weaviate 云服务(WCS)创建一个免费的 Weaviate 集群。
Weaviate 集群
:Sandbox Free
Disabled
集群 ID
。链接将带您到您集群的完整路径(稍后您将需要连接到它)。它应该类似于:https://your-project-name.weaviate.network
使用 Docker 在本地安装和运行 Weaviate。
docker-compose up -d
注意:要关闭 Docker 实例,您可以运行:docker-compose down
要了解更多关于使用 Docker 部署 Weaviate 的信息,请参阅安装文档。
===========================================================
在运行此项目之前,请确保安装以下库:
Weaviate Python客户端 允许您从Python项目中与Weaviate实例进行通信。
要加载示例数据,您需要 datasets
库及其依赖项 apache-beam
。
# 安装适用于 Python 的 Weaviate 客户端
!pip install weaviate-client>3.11.0
# 安装数据集和apache-beam以加载示例数据集
!pip install datasets apache-beam
===========================================================
OpenAI API密钥
用于在导入数据时对数据进行向量化,并用于运行查询。
如果您没有OpenAI API密钥,可以从https://beta.openai.com/account/api-keys获取一个。
获取密钥后,请将其添加到您的环境变量中,名称为 OPENAI_API_KEY
。
# 导出 OpenAI API 密钥
!export OPENAI_API_KEY="your key"
# 测试您的OpenAI API密钥是否已正确设置为环境变量。
# 注意:如果您在本地运行此笔记本,您需要重新加载终端和笔记本,以使环境变量生效。
import os
# 注意:或者,您也可以像这样设置一个临时的环境变量:
# os.environ['OPENAI_API_KEY'] = 'your-key-goes-here'
if os.getenv("OPENAI_API_KEY") is not None:
print ("OPENAI_API_KEY is ready")
else:
print ("OPENAI_API_KEY environment variable not found")
import weaviate
from datasets import load_dataset
import os
# 连接到您的 Weaviate 实例
client = weaviate.Client(
url="https://your-wcs-instance-name.weaviate.network/",
# url="http://localhost:8080/",
auth_client_secret=weaviate.auth.AuthApiKey(api_key="<YOUR-WEAVIATE-API-KEY>"), # 如果您没有为您的 Weaviate 实例使用身份验证(例如,对于本地部署的实例),请注释掉这一行。
additional_headers={
"X-OpenAI-Api-Key": os.getenv("OPENAI_API_KEY")
}
)
# 检查您的实例是否已上线并准备就绪
# 这将返回 `True`
client.is_ready()
在本节中,我们将:
这是第二步,也是最后一步,需要进行 OpenAI 特定的配置。 在这一步之后,其余的说明将只涉及到 Weaviate,因为 OpenAI 任务将被自动处理。
在 Weaviate 中,您创建 模式 来捕捉您将要搜索的每个实体。
模式是您告诉 Weaviate 的方式:
在本教程中,我们将使用一个包含以下内容的 Articles
数据集:
title
content
url
我们希望对 title
和 content
进行向量化,但不包括 url
。
为了对数据进行向量化和查询,我们将使用 text-embedding-3-small
。
# 清理架构,以便我们能够重新创建它。
client.schema.delete_all()
client.schema.get()
# 定义Schema对象,对`title`和`content`字段使用`text-embedding-3-small`进行处理,但跳过`url`字段。
article_schema = {
"class": "Article",
"description": "A collection of articles",
"vectorizer": "text2vec-openai",
"moduleConfig": {
"text2vec-openai": {
"model": "ada",
"modelVersion": "002",
"type": "text"
}
},
"properties": [{
"name": "title",
"description": "Title of the article",
"dataType": ["string"]
},
{
"name": "content",
"description": "Contents of the article",
"dataType": ["text"]
},
{
"name": "url",
"description": "URL to the article",
"dataType": ["string"],
"moduleConfig": { "text2vec-openai": { "skip": True } }
}]
}
# 添加文章模式
client.schema.create_class(article_schema)
# 获取架构以确保其正常工作
client.schema.get()
在本节中,我们将:
注意:
如前所述。我们不需要手动对数据进行向量化。
text2vec-openai 模块会处理这部分。
# ## 步骤1 - 加载数据集
from datasets import load_dataset
from typing import List, Iterator
# 我们将使用datasets库来提取Simple Wikipedia数据集以进行嵌入。
dataset = list(load_dataset("wikipedia", "20220301.simple")["train"])
# 在测试阶段,为了演示目的,仅限于2500篇文章。
dataset = dataset[:2_500]
# 为了进行更大规模的演示,限制在2.5万篇文章以内
# 数据集 = 数据集[:25_000]
# 对于免费的OpenAI账户,您可以使用50个对象。
# 数据集 = 数据集[:50]
# ##步骤2 - 配置Weaviate批处理功能
# - 初始批次大小为100
# - 根据性能动态增减
# - 如果出现问题,增加超时重试机制
client.batch.configure(
batch_size=10,
dynamic=True,
timeout_retries=3,
# 回调函数=None,
)
# ##步骤3 - 导入数据
print("Importing Articles")
counter=0
with client.batch as batch:
for article in dataset:
if (counter %10 == 0):
print(f"Import {counter} / {len(dataset)} ")
properties = {
"title": article["title"],
"content": article["text"],
"url": article["url"]
}
batch.add_data_object(properties, "Article")
counter = counter+1
print("Importing Articles complete")
# 测试所有数据是否已加载 —— 获取对象数量
result = (
client.query.aggregate("Article")
.with_fields("meta { count }")
.do()
)
print("Object count: ", result["data"]["Aggregate"]["Article"], "\n")
# 通过检查一个对象,测试一篇文章已经成功运作。
test_article = (
client.query
.get("Article", ["title", "url", "content"])
.with_limit(1)
.do()
)["data"]["Get"]["Article"][0]
print(test_article['title'])
print(test_article['url'])
print(test_article['content'])
def hybrid_query_weaviate(query, collection_name, alpha_val):
nearText = {
"concepts": [query],
"distance": 0.7,
}
properties = [
"title", "content", "url",
"_additional { score }"
]
result = (
client.query
.get(collection_name, properties)
.with_hybrid(nearText, alpha=alpha_val)
.with_limit(10)
.do()
)
# 检查错误
if ("errors" in result):
print ("\033[91mYou probably have run out of OpenAI API calls for the current minute – the limit is set at 60 per minute.")
raise Exception(result["errors"][0]['message'])
return result["data"]["Get"][collection_name]
query_result = hybrid_query_weaviate("modern art in Europe", "Article", 0.5)
for i, article in enumerate(query_result):
print(f"{i+1}. { article['title']} (Score: {article['_additional']['score']})")
query_result = hybrid_query_weaviate("Famous battles in Scottish history", "Article", 0.5)
for i, article in enumerate(query_result):
print(f"{i+1}. { article['title']} (Score: {article['_additional']['score']})")
感谢您的跟随,现在您已经具备了设置自己的向量数据库并使用嵌入来做各种酷炫事情的能力 - 尽情享受吧!对于更复杂的用例,请继续阅读此存储库中的其他示例。