ETL 管道

提取、转换和加载 (ETL) 框架是检索增强生成 (RAG) 用例中数据处理的支柱。

ETL 管道协调从原始数据源到结构化向量存储的流程,确保数据以最佳格式供 AI 模型检索。

RAG 用例是文本,通过从数据主体检索相关信息来增强生成模型的功能,从而提高生成输出的质量和相关性。

API 概述

ETL 管道主要包含三个组件:

  • DocumentReader 实现 Supplier<List<Document>>

  • DocumentTransformer 实现 Function<List<Document>, List<Document>>

  • DocumentWriter 实现 Consumer<List<Document>>

Document 类包含文本和元数据,并通过 DocumentReader 从 PDF、文本文件和其他文档类型创建。

要构建一个简单的 ETL 管道,您可以将每种类型的实例链接在一起。

etl pipeline

假设我们有以下三种 ETL 类型的实例:

  • PagePdfDocumentReaderDocumentReader 的实现

  • TokenTextSplitterDocumentTransformer 的实现

  • VectorStoreDocumentWriter 的实现

要将数据加载到向量数据库中以用于检索增强生成模式,请在 Java 函数式语法中使用以下代码。

vectorStore.accept(tokenTextSplitter.apply(pdfReader.get()));

或者,您可以使用更自然地表达域的函数名称。

vectorStore.write(tokenTextSplitter.split(pdfReader.read()));

入门

要开始创建 Spring AI RAG 应用程序,请按照以下步骤操作:

  1. 下载最新的 Spring CLI 版本 并按照 安装说明 进行操作。

  2. 要创建一个简单的基于 OpenAI 的应用程序,请使用以下命令:

    spring boot new --from ai-rag --name myrag
  3. 请参阅生成的 README.md 文件,了解有关获取 OpenAI API 密钥和运行第一个 AI RAG 应用程序的指南。

ETL 接口和实现

ETL 管道由以下接口和实现组成。详细的 ETL 类图在 ETL 类图 部分中显示。

DocumentReader

提供来自不同来源的文档来源。

public interface DocumentReader extends Supplier<List<Document>> {

    default List<Document> read() {
		return get();
	}
}

JsonReader

JsonReader 解析 JSON 格式的文档。

示例

@Component
class MyAiAppComponent {

	private final Resource resource;

    MyAiAppComponent(@Value("classpath:bikes.json") Resource resource) {
        this.resource = resource;
    }

	List<Document> loadJsonAsDocuments() {
		JsonReader jsonReader = new JsonReader(resource, "description");
		return jsonReader.read();
	}
}

TextReader

TextReader 处理纯文本文档。

示例

@Component
class MyTextReader {

    private final Resource resource;

    MyTextReader(@Value("classpath:text-source.txt") Resource resource) {
        this.resource = resource;
    }
	List<Document> loadText() {
		TextReader textReader = new TextReader(resource);
		textReader.getCustomMetadata().put("filename", "text-source.txt");

		return textReader.read();
    }
}

PagePdfDocumentReader

PagePdfDocumentReader 使用 Apache PdfBox 库解析 PDF 文档。

示例

@Component
public class MyPagePdfDocumentReader {

	List<Document> getDocsFromPdf() {

		PagePdfDocumentReader pdfReader = new PagePdfDocumentReader("classpath:/sample1.pdf",
				PdfDocumentReaderConfig.builder()
					.withPageTopMargin(0)
					.withPageExtractedTextFormatter(ExtractedTextFormatter.builder()
						.withNumberOfTopTextLinesToDelete(0)
						.build())
					.withPagesPerDocument(1)
					.build());

		return pdfReader.read();
    }

}

ParagraphPdfDocumentReader

ParagraphPdfDocumentReader 使用 PDF 目录(例如 TOC)信息将输入 PDF 拆分为文本段落,并为每个段落输出一个 Document。注意:并非所有 PDF 文档都包含 PDF 目录。

示例

@Component
public class MyPagePdfDocumentReader {

	List<Document> getDocsFromPdfwithCatalog() {

        new ParagraphPdfDocumentReader("classpath:/sample1.pdf",
                PdfDocumentReaderConfig.builder()
                    .withPageTopMargin(0)
                    .withPageExtractedTextFormatter(ExtractedTextFormatter.builder()
                        .withNumberOfTopTextLinesToDelete(0)
                        .build())
                    .withPagesPerDocument(1)
                    .build());

		return pdfReader.read();
    }
}

TikaDocumentReader

TikaDocumentReader 使用 Apache Tika 从各种文档格式(如 PDF、DOC/DOCX、PPT/PPTX 和 HTML)中提取文本。有关支持格式的完整列表,请参阅 Tika 文档

示例

@Component
class MyTikaDocumentReader {

    private final Resource resource;

    MyTikaDocumentReader(@Value("classpath:/word-sample.docx")
                            Resource resource) {
        this.resource = resource;
    }

    List<Document> loadText() {
        TikaDocumentReader tikaDocumentReader = new TikaDocumentReader(resource);
        return tikaDocumentReader.read();
    }
}

DocumentTransformer

在处理工作流中转换一批文档。

public interface DocumentTransformer extends Function<List<Document>, List<Document>> {

    default List<Document> transform(List<Document> transform) {
		return apply(transform);
	}
}

TextSplitter

TextSplitter 是一个抽象基类,它有助于将文档划分为适合 AI 模型上下文窗口的大小。

TokenTextSplitter

在保留令牌级完整性的同时拆分文档。

ContentFormatTransformer

确保所有文档的统一内容格式。

KeywordMetadataEnricher

使用必要的关键字元数据增强文档。

SummaryMetadataEnricher

使用摘要元数据丰富文档,以增强检索功能。

DocumentWriter

管理 ETL 过程的最后阶段,准备文档以供存储。

public interface DocumentWriter extends Consumer<List<Document>> {

    default void write(List<Document> documents) {
		accept(documents);
	}
}

FileDocumentWriter

将文档持久化到文件。

向量存储

提供与各种向量存储的集成。有关完整列表,请参见 向量数据库文档

ETL 类图

以下类图说明了 ETL 接口和实现。

etl class diagram