使用 LangChain 将 S3 数据发送到 Qdrant 向量存储
时长:30 分钟 | 级别:初学者 |
---|
将数据摄取到向量存储中对于构建高效的搜索和检索算法至关重要,特别是因为近 80% 的数据是非结构化的,缺乏任何预定义格式。
在本教程中,我们将创建一个简化的数据摄取管道,直接从 AWS S3 中拉取数据并将其馈送到 Qdrant 中。我们将深入探讨向量嵌入,将非结构化数据转换为允许您进行语义搜索的格式。准备好发现新的方法来揭示非结构化数据中隐藏的见解!
摄取工作流程架构
在此工作流程中,我们将使用云存储、自然语言处理 (NLP) 工具和嵌入技术设置强大的文档摄取和分析管道。首先,在 S3 存储桶中处理原始数据,然后使用 LangChain对其进行预处理,应用文本和图像的嵌入 API,并将结果存储在 Qdrant 中——一个针对相似性搜索优化的向量数据库。
图 1:数据摄取工作流程架构
让我们分解一下此工作流程的每个组件
- S3 存储桶:这是我们的起点——一个集中式、可扩展的存储解决方案,适用于各种文件类型,如 PDF、图像和文本。
- LangChain:LangChain 作为管道的协调器,负责提取、预处理和管理数据流以生成嵌入。它简化了 PDF 的处理,因此您无需在此处担心应用 OCR(光学字符识别)。
- Qdrant:作为您的向量数据库,Qdrant 存储嵌入及其负载 (payloads),从而可以在所有内容类型上实现高效的相似性搜索和检索。
先决条件
在本节中,您将获得一个从 S3 存储桶中摄取数据的分步指南。但在深入之前,请确保您已设置所有先决条件
示例数据 | 我们将使用一个示例数据集,其中每个文件夹都包含文本格式的产品评论以及相应的图像。 |
AWS 账户 | 一个活跃的AWS 账户,并有权访问 S3 服务。 |
Qdrant Cloud | 一个Qdrant Cloud 账户,并有权访问用于管理集合和运行查询的 WebUI。 |
LangChain | 您将使用这个流行的框架将所有内容联系起来。 |
支持的文档类型
用于摄取的文档可以是各种类型,如 PDF、文本文件或图像。我们将组织一个带有文件夹的结构化 S3 存储桶,其中包含支持的文档类型,用于测试和实验。
Python 环境
确保您有一个安装了以下库的 Python 环境(Python 3.9 或更高版本)
boto3
langchain-community
langchain
python-dotenv
unstructured
unstructured[pdf]
qdrant_client
fastembed
访问密钥:将您的 AWS 访问密钥、S3 密钥和 Qdrant API 密钥存储在 .env 文件中以便于访问。这是一个示例 .env
文件。
ACCESS_KEY = ""
SECRET_ACCESS_KEY = ""
QDRANT_KEY = ""
步骤 1:从 S3 摄取数据
LangChain 框架使得从 AWS S3 等存储服务中摄取数据变得容易,它内置支持加载 PDF、图像和文本文件等格式的文档。
要将 LangChain 与 S3 连接,您将使用 S3DirectoryLoader
,它允许您直接从 S3 存储桶将文件加载到 LangChain 的管道中。
示例:配置 LangChain 从 S3 加载文件
以下是如何设置 LangChain 从 S3 存储桶摄取数据
from langchain_community.document_loaders import S3DirectoryLoader
# Initialize the S3 document loader
loader = S3DirectoryLoader(
"product-dataset", # S3 bucket name
"p_1", #S3 Folder name containing the data for the first product
aws_access_key_id=aws_access_key_id, # AWS Access Key
aws_secret_access_key=aws_secret_access_key # AWS Secret Access Key
)
# Load documents from the specified S3 bucket
docs = loader.load()
步骤 2:将文档转换为嵌入
嵌入 (Embeddings) 是这里的秘密武器——它们是数据的数值表示(如文本、图像或音频),以易于比较的形式捕获“含义”。通过将文本和图像转换为嵌入,您将能够快速高效地执行相似性搜索。将嵌入视为在 Qdrant 中存储和检索数据中有意义见解的桥梁。
我们将用于生成嵌入的模型
为了启动流程,我们将使用两个强大的模型
sentence-transformers/all-MiniLM-L6-v2
嵌入用于转换文本数据。CLIP
(对比语言-图像预训练)用于图像数据。
文档处理函数
接下来,我们将定义两个函数 — process_text
和 process_image
,以处理文档管道中的不同文件类型。process_text
函数提取并返回基于文本的文档的原始内容,而 process_image
从 S3 源检索图像并将其加载到内存中。
from PIL import Image
def process_text(doc):
source = doc.metadata['source'] # Extract document source (e.g., S3 URL)
text = doc.page_content # Extract the content from the text file
print(f"Processing text from {source}")
return source, text
def process_image(doc):
source = doc.metadata['source'] # Extract document source (e.g., S3 URL)
print(f"Processing image from {source}")
bucket_name, object_key = parse_s3_url(source) # Parse the S3 URL
response = s3.get_object(Bucket=bucket_name, Key=object_key) # Fetch image from S3
img_bytes = response['Body'].read()
img = Image.open(io.BytesIO(img_bytes))
return source, img
文档处理的辅助函数
为了从 S3 检索图像,辅助函数 parse_s3_url
将 S3 URL 分解为其存储桶和关键组件。这对于从 S3 存储中获取图像至关重要。
def parse_s3_url(s3_url):
parts = s3_url.replace("s3://", "").split("/", 1)
bucket_name = parts[0]
object_key = parts[1]
return bucket_name, object_key
步骤 3:将嵌入加载到 Qdrant 中
现在您的文档已处理并转换为嵌入,下一步是将这些嵌入加载到 Qdrant 中。
在 Qdrant 中创建集合
在 Qdrant 中,数据按集合组织,每个集合代表一组嵌入(或点)及其关联的元数据(负载)。要存储之前生成的嵌入,您首先需要创建一个集合。
以下是如何在 Qdrant 中创建集合来存储文本和图像嵌入
def create_collection(collection_name):
qdrant_client.create_collection(
collection_name,
vectors_config={
"text_embedding": models.VectorParams(
size=384, # Dimension of text embeddings
distance=models.Distance.COSINE, # Cosine similarity is used for comparison
),
"image_embedding": models.VectorParams(
size=512, # Dimension of image embeddings
distance=models.Distance.COSINE, # Cosine similarity is used for comparison
),
},
)
create_collection("products-data")
此函数创建了一个用于存储文本(384 维)和图像(512 维)嵌入的集合,使用余弦相似度比较集合中的嵌入。
设置好集合后,您可以将嵌入加载到 Qdrant 中。这涉及将嵌入及其关联的元数据(负载)插入(或更新)到指定的集合中。
以下是将嵌入加载到 Qdrant 中的代码
def ingest_data(points):
operation_info = qdrant_client.upsert(
collection_name="products-data", # Collection where data is being inserted
points=points
)
return operation_info
摄取说明
- 更新或插入数据点:
qdrant_client
上的 upsert 方法将每个 PointStruct 插入到指定的集合中。如果具有相同 ID 的点已存在,它将使用新值进行更新。 - 操作信息:该函数返回
operation_info
,其中包含有关 upsert 操作的详细信息,例如成功状态或任何潜在错误。
运行摄取代码
以下是如何调用函数并摄取数据
from qdrant_client import models
if __name__ == "__main__":
collection_name = "products-data"
create_collection(collection_name)
for i in range(1,6): # Five documents
folder = f"p_{i}"
loader = S3DirectoryLoader(
"product-dataset",
folder,
aws_access_key_id=aws_access_key_id,
aws_secret_access_key=aws_secret_access_key
)
docs = loader.load()
points, text_review, product_image = [], "", ""
for idx, doc in enumerate(docs):
source = doc.metadata['source']
if source.endswith(".txt") or source.endswith(".pdf"):
_text_review_source, text_review = process_text(doc)
elif source.endswith(".png"):
product_image_source, product_image = process_image(doc)
if text_review:
point = models.PointStruct(
id=idx, # Unique identifier for each point
vector={
"text_embedding": models.Document(
text=text_review, model="sentence-transformers/all-MiniLM-L6-v2"
),
"image_embedding": models.Image(
image=product_image, model="Qdrant/clip-ViT-B-32-vision"
),
},
payload={"review": text_review, "product_image": product_image_source},
)
points.append(point)
operation_info = ingest_data(points)
print(operation_info)
PointStruct
通过以下关键参数实例化
id:每个嵌入的唯一标识符,通常是一个增量索引。
vector:一个字典,包含用于嵌入的文本和图像输入。
qdrant-client
在底层使用 FastEmbed 来自动在本地从这些输入生成向量表示。payload:一个字典,存储附加元数据,如产品评论和图像引用,这对于搜索期间的检索和上下文非常宝贵。
该代码动态加载 S3 存储桶中的文件夹,分别处理文本和图像文件,并将其嵌入及关联数据存储在专门的列表中。然后为每个数据条目创建一个 PointStruct
,并调用摄取函数将其加载到 Qdrant 中。
探索 Qdrant WebUI 控制面板
将嵌入加载到 Qdrant 后,您可以使用 WebUI 控制面板可视化和管理您的集合。该控制面板提供了一个清晰、结构化的界面,用于查看集合及其数据。让我们在下一节中仔细看看。
步骤 4:在 Qdrant WebUI 中可视化数据
要开始在 Qdrant WebUI 中可视化数据,请前往概览部分,然后选择访问数据库。
图 2:从 Qdrant UI 访问数据库
出现提示时,输入您的 API 密钥。进入后,您将能够查看您的集合和相应的数据点。您应该会看到您的集合显示如下
图 3:Qdrant 中的 product-data 集合
以下是摄入到 Qdrant 中的最新点
图 4:添加到 product-data 集合的最新点
Qdrant WebUI 的搜索功能允许您在您的集合中执行向量搜索。通过应用过滤器和参数的选项,检索相关嵌入和探索数据中的关系变得容易。要开始,请转到左侧面板中的控制台,您可以在其中创建查询
图 5:Qdrant 控制台概览
第一个查询检索所有集合,第二个从 product-data 集合中获取点,第三个执行一个示例查询。这展示了在 Qdrant UI 中与数据交互是多么直接。
现在,让我们使用一个查询从数据库中检索一些文档!
图 6:查询 Qdrant 客户端以检索相关文档
在这个示例中,我们查询了设计得到改进的手机。然后,我们使用 OpenAI 将文本转换为向量,并检索到了一条相关的手机评论,其中强调了设计改进。
结论
在本指南中,我们设置了一个 S3 存储桶,摄取了各种数据类型,并将嵌入存储在 Qdrant 中。使用 LangChain,我们动态处理了文本和图像文件,使得处理每种文件类型变得容易。
现在轮到您了。尝试使用不同的数据类型(例如视频)进行实验,并探索 Qdrant 的高级功能以增强您的应用程序。要开始,请立即注册 Qdrant。