在构建真实的 RAG 应用程序中,解析文档以使其信息可搜索是一个重要的步骤。Unstructured.io 和 Elasticsearch 在这种情况下有效地协同工作,为开发人员提供了互补的工具来构建 RAG 应用程序。
Unstructured.io 提供了一套工具,用于提取、清理和转换不同格式和不同内容源的文档。将文档添加到 Elasticsearch 索引后,开发人员可以选择许多 Elastic 功能,包括聚合、过滤器、RBAC 工具以及 BM25 或向量搜索功能,以将复杂的业务逻辑实现到 RAG 应用程序中。
在本博文中,我们将研究一个相当常见的用例,即 解析和摄取包含文本、表格和图像的 PDF 文档。我们将使用 Elastic 的 ELSER 模型创建稀疏向量嵌入,然后使用 Elasticsearch 作为向量数据库来存储和搜索嵌入。
Unstructured 的强大功能在于可以识别文档的唯一组件并将其提取到“文档元素”中的模型。Unstructured 还能够使用不同的策略而不是仅按字符数量来对分区进行分块。这些“智能分区和分块”策略可以提高搜索相关性并减少 RAG 应用程序中的幻觉。
解析数据后,我们将其作为向量嵌入存储在 Elasticsearch 向量数据库中并运行搜索操作。我们使用 Elasticsearch 向量数据库连接器将此数据发送到 Elastic。我们还在流程中附加了一个管道,以便在摄取时创建 ELSER(用于语义搜索的开箱即用的稀疏编码器模型)嵌入。
如何解析和搜索非结构化文档
- 在 Elastic 平台中部署 ELSER 模型,
- 创建一个 摄取管道,它将为摄取的分块创建嵌入。字段
text
将存储分块的文本,text_embeddings
将存储嵌入。我们将使用 ELSER v2 模型。
PUT _ingest/pipeline/chunks-to-elser
{
"processors": [
{
"inference": {
"model_id": ".elser_model_2_linux-x86_64",
"input_output": [
{
"input_field": "text",
"output_field": "text_embedding"
}
]
}
}
]
}
- 下一步是创建一个索引
unstructured-demo
,其中包含 ELSER 嵌入所需的映射。我们还将把我们在上一步中创建的管道附加到此索引。我们将允许所有其他字段进行动态映射。
PUT unstructured-demo
{
"settings": {
"default_pipeline": "chunks-to-elser"
},
"mappings": {
"properties": {
"text_embedding": {
"type": "sparse_vector"
},
"text": {
"type": "text"
}
}
}
}
- 最后一步是运行 Unstructured 的代码示例,使用 Elasticsearch 连接器 来创建分区和分块。按照 安装依赖项的说明 进行操作。
import os
from unstructured.ingest.connector.elasticsearch import (
ElasticsearchAccessConfig,
ElasticsearchWriteConfig,
SimpleElasticsearchConfig,
)
from unstructured.ingest.connector.local import SimpleLocalConfig
from unstructured.ingest.interfaces import (
ChunkingConfig,
PartitionConfig,
ProcessorConfig,
ReadConfig,
)
from unstructured.ingest.runner import LocalRunner
from unstructured.ingest.runner.writers.base_writer import Writer
from unstructured.ingest.runner.writers.elasticsearch import (
ElasticsearchWriter,
)
我们将主机设置为 Elastic Cloud(Elasticsearch 服务)。我们设置用户名和密码,并设置我们要写入的索引
def get_writer() -> Writer:
return ElasticsearchWriter(
connector_config=SimpleElasticsearchConfig(
access_config=ElasticsearchAccessConfig(
hosts="https://unstructured-demo.es.us-central1.gcp.cloud.es.io",
username="elastic",
password=<insert password>
),
index_name="unstructured-demo",
),
write_config=ElasticsearchWriteConfig(
batch_size_bytes=15_000_000,
num_processes=2,
),
)
对于下一步,注册 获取 Unstructured API 端点和密钥。Unstructured 中的分区函数从非结构化文档中提取结构化内容。partition
函数检测文档类型并自动确定适当的分区函数。如果用户知道其文件类型,他们还可以指定特定的分区函数。在分区步骤中,我们指示 Unstructured 通过传入 pdf_infer_table_structure=True
并将分区策略设置为 hi_res
来推断表结构,从而自动识别文档的布局。您可以在此处了解各种 Unstructured 分区策略。我们将 分块策略 设置为 by_title
,它“保留节和页面边界”。分块策略对 RAG 应用程序的性能和质量有重大影响。您可以在其 用于有效检索增强生成的分块论文 中了解更多关于 Unstructured 在这方面的工作。
writer = get_writer()
runner = LocalRunner(
processor_config=ProcessorConfig(
verbose=True,
output_dir="local-output-to-elasticsearch",
num_processes=2,
),
connector_config=SimpleLocalConfig(
input_path=<path to PDF>,
),
read_config=ReadConfig(),
partition_config=PartitionConfig(pdf_infer_table_structure=True,strategy='hi_res',partition_by_api=True, partition_endpoint=<your partition endpoint>', api_key=<your api key>),
chunking_config=ChunkingConfig(chunk_elements=True, max_characters=500, chunking_strategy="by_title"),
writer=writer,
writer_kwargs={},
)
runner.run()
在 Elasticsearch 向量数据库中的结果文档中,您将看到由 Unstructured API 生成的某些有趣的元数据。如果元素是表格,您将看到表格的 HTML 结构以及有关其外观的信息。如果是文本块并且是先前块的延续,您将看到 is_continuation
,这在您希望将段落的整个上下文传递给 LLM 的 RAG 场景中很有价值。如果您想知道哪些单独的分区构成一个块,您可以在 base-64 编码的 orig_elements
字段中找到它。在上面的示例中,我们使用了 Unstructured 的 API 服务。这些 API 服务可以通过三种不同的方式使用
- Unstructured API 的有限试用版
- Unstructured API 的 SaaS 版本
- AWS/Azure 市场上的 Unstructured API
试用版提供的处理能力上限为 1000 页,您的文档可用于专有模式的训练和评估目的。对于快速原型设计,您还可以查看 Unstructured 的开源 版本。非结构化库为您提供了使用其 Python 安装程序运行的选项。如果您想避免处理多个依赖项,您可以使用捆绑了所有必需库的 Docker 容器。Unstructured API 与开源版本相比,提供了以下其他功能
- 显着提高了文档和表格提取的性能,并具有高级分块和改进的转换管道
- 访问最新的视觉转换器模型和企业级功能,例如安全性、SOC2 合规性、IAM(身份验证和身份管理)
结论
有效的文档解析是构建有效的 RAG 解决方案的重要步骤。Unstructured 将原始文档转换为 LLM 可以理解的数据的方法,加上 Elastic 作为向量数据库和搜索平台的优势,将加速您构建 AI 的旅程。搜索愉快!
Elasticsearch 与行业领先的 Gen AI 工具和提供商具有原生集成。查看我们关于超越 RAG 基础知识的网络研讨会 Beyond RAG Basics,或构建生产就绪型应用程序 Elastic 向量数据库。