ETL 流水线

提取、转换和加载 (ETL) 框架是检索增强生成 (RAG) 用例中数据处理的骨干。spring-doc.cadn.net.cn

ETL 流水线协调从原始数据源到结构化向量存储的流程,确保数据处于供 AI 模型检索的最佳格式。spring-doc.cadn.net.cn

RAG 用例是通过从数据体中检索相关信息来增强生成模型的能力,从而提升生成输出的质量和相关性。spring-doc.cadn.net.cn

API概述

ETL 流水线创建、转换并存储 Document 个实例。spring-doc.cadn.net.cn

Spring AI Message API

Document 类包含文本、元数据,以及可选的其他媒体类型(如图像、音频和视频)。spring-doc.cadn.net.cn

ETL 流水线主要有三个组成部分,spring-doc.cadn.net.cn

Document 类的内容由 DocumentReader 协助从 PDF、文本文件及其他文档类型创建。spring-doc.cadn.net.cn

要构建一个简单的 ETL 管道,您可以将每种类型的实例链接在一起。spring-doc.cadn.net.cn

etl pipeline

假设我们有以下三种 ETL 类型的实例spring-doc.cadn.net.cn

要在向量数据库中执行基本的数据加载以用于检索增强生成模式,请在 Java 函数式语法中使用以下代码。spring-doc.cadn.net.cn

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

或者,您可以使用对领域而言更自然表达的方法名称。spring-doc.cadn.net.cn

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

ETL 接口

ETL 流水线由以下接口和实现组成。 详细的 ETL 类图展示在 ETL 类图 部分。spring-doc.cadn.net.cn

文档阅读器

提供来自不同来源的文档资源。spring-doc.cadn.net.cn

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

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

文档转换器

作为处理工作流的一部分,转换一批文档。spring-doc.cadn.net.cn

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

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

文档写入器

管理 ETL 流程的最后阶段,为文档存储做准备。spring-doc.cadn.net.cn

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

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

ETL 类图

以下类图展示了 ETL 接口及其实现。spring-doc.cadn.net.cn

etl class diagram

文档读取器

JSON

JsonReader 处理 JSON 文档,将其转换为 Document 对象列表。spring-doc.cadn.net.cn

例举

@Component
class MyJsonReader {

	private final Resource resource;

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

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

构造函数选项

JsonReader 提供了多种构造函数选项:spring-doc.cadn.net.cn

  1. JsonReader(Resource resource)spring-doc.cadn.net.cn

  2. JsonReader(Resource resource, String…​ jsonKeysToUse)spring-doc.cadn.net.cn

  3. JsonReader(Resource resource, JsonMetadataGenerator jsonMetadataGenerator, String…​ jsonKeysToUse)spring-doc.cadn.net.cn

参数

  • resource:一个指向 JSON 文件的 Spring Resource 对象。spring-doc.cadn.net.cn

  • jsonKeysToUse:来自 JSON 的键数组,这些键将用作结果 Document 对象中的文本内容。spring-doc.cadn.net.cn

  • jsonMetadataGenerator: 一个可选的JsonMetadataGenerator,用于为每个Document创建元数据。spring-doc.cadn.net.cn

行为

JsonReader 按以下方式处理 JSON 内容:spring-doc.cadn.net.cn

使用 JSON 指针

JsonReader 现在支持使用 JSON Pointer 检索 JSON 文档的特定部分。此功能让您能够轻松地从复杂的 JSON 结构中提取嵌套数据。spring-doc.cadn.net.cn

get(String pointer)方法
public List<Document> get(String pointer)

此方法允许您使用 JSON 指针检索 JSON 文档的特定部分。spring-doc.cadn.net.cn

参数
  • pointer:一个 JSON Pointer 字符串(如 RFC 6901 所定义),用于在 JSON 结构中定位所需元素。spring-doc.cadn.net.cn

返回值
  • 返回一个包含从指针定位的 JSON 元素解析出的文档的 List<Document>spring-doc.cadn.net.cn

行为
例举
JsonReader jsonReader = new JsonReader(resource, "description");
List<Document> documents = this.jsonReader.get("/store/books/0");

示例 JSON 结构

[
  {
    "id": 1,
    "brand": "Trek",
    "description": "A high-performance mountain bike for trail riding."
  },
  {
    "id": 2,
    "brand": "Cannondale",
    "description": "An aerodynamic road bike for racing enthusiasts."
  }
]

在此示例中,如果将 JsonReader 配置为以 "description" 作为 jsonKeysToUse,它将创建 Document 个对象,其中内容为数组中每辆自行车的“description”字段的值。spring-doc.cadn.net.cn

注释

text

TextReader 处理纯文本文档,将其转换为 Document 对象列表。spring-doc.cadn.net.cn

例举

@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(this.resource);
		textReader.getCustomMetadata().put("filename", "text-source.txt");

		return textReader.read();
    }
}

构造函数选项

TextReader 提供了两种构造函数选项:spring-doc.cadn.net.cn

  1. TextReader(String resourceUrl)spring-doc.cadn.net.cn

  2. TextReader(Resource resource)spring-doc.cadn.net.cn

参数

配置

  • setCharset(Charset charset): 设置读取文本文件时使用的字符集。默认值为 UTF-8。spring-doc.cadn.net.cn

  • getCustomMetadata():返回一个可变映射,您可以向其中添加文档的自定义元数据。spring-doc.cadn.net.cn

行为

TextReader 按以下方式处理文本内容:spring-doc.cadn.net.cn

注释

  • TextReader 会将整个文件内容读取到内存中,因此可能不适用于非常大的文件。spring-doc.cadn.net.cn

  • 如果您需要将文本分割成更小的块,可以在读取文档后使用像 TokenTextSplitter 这样的文本分割器:spring-doc.cadn.net.cn

List<Document> documents = textReader.get();
List<Document> splitDocuments = new TokenTextSplitter().apply(this.documents);
  • 读取器使用 Spring 的 Resource 抽象,使其能够从各种来源(类路径、文件系统、URL 等)进行读取。spring-doc.cadn.net.cn

  • 可以使用 getCustomMetadata() 方法将自定义元数据添加到读取器创建的所有文档中。spring-doc.cadn.net.cn

HTML (JSoup)

JsoupDocumentReader 处理 HTML 文档,使用 JSoup 库将其转换为 Document 对象列表。spring-doc.cadn.net.cn

依赖项

使用 Maven 或 Gradle 将依赖项添加到您的项目中。spring-doc.cadn.net.cn

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-jsoup-document-reader</artifactId>
</dependency>
dependencies {
    implementation 'org.springframework.ai:spring-ai-jsoup-document-reader'
}

例举

@Component
class MyHtmlReader {

    private final Resource resource;

    MyHtmlReader(@Value("classpath:/my-page.html") Resource resource) {
        this.resource = resource;
    }

    List<Document> loadHtml() {
        JsoupDocumentReaderConfig config = JsoupDocumentReaderConfig.builder()
            .selector("article p") // Extract paragraphs within <article> tags
            .charset("ISO-8859-1")  // Use ISO-8859-1 encoding
            .includeLinkUrls(true) // Include link URLs in metadata
            .metadataTags(List.of("author", "date")) // Extract author and date meta tags
            .additionalMetadata("source", "my-page.html") // Add custom metadata
            .build();

        JsoupDocumentReader reader = new JsoupDocumentReader(this.resource, config);
        return reader.get();
    }
}

JsoupDocumentReaderConfig 允许您自定义 JsoupDocumentReader 的行为:spring-doc.cadn.net.cn

  • charset: 指定 HTML 文档的字符编码(默认为"UTF-8")。spring-doc.cadn.net.cn

  • selector: 一个 JSoup CSS 选择器,用于指定从哪些元素中提取文本(默认为"body")。spring-doc.cadn.net.cn

  • separator: 用于连接多个选中元素文本的字符串(默认为"\n")。spring-doc.cadn.net.cn

  • allElements: 如果为 true,则从 <body> 元素中提取所有文本,忽略 selector(默认为 false)。spring-doc.cadn.net.cn

  • groupByElement: 如果为 true,则为 selector 匹配的每个元素创建一个单独的 Document(默认为 false)。spring-doc.cadn.net.cn

  • includeLinkUrls: 如果为 true,则提取绝对链接 URL 并将其添加到元数据中(默认值为 false)。spring-doc.cadn.net.cn

  • metadataTags: 要从中提取内容的 <meta> 标签名称列表(默认为 ["description", "keywords"])。spring-doc.cadn.net.cn

  • additionalMetadata: 允许您向所有创建的 Document 对象添加自定义元数据。spring-doc.cadn.net.cn

示例文档:my-page.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>My Web Page</title>
    <meta name="description" content="A sample web page for Spring AI">
    <meta name="keywords" content="spring, ai, html, example">
    <meta name="author" content="John Doe">
    <meta name="date" content="2024-01-15">
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <header>
        <h1>Welcome to My Page</h1>
    </header>
    <nav>
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/about">About</a></li>
        </ul>
    </nav>
    <article>
        <h2>Main Content</h2>
        <p>This is the main content of my web page.</p>
        <p>It contains multiple paragraphs.</p>
        <a href="https://www.example.com">External Link</a>
    </article>
    <footer>
        <p>&copy; 2024 John Doe</p>
    </footer>
</body>
</html>

JsoupDocumentReader 处理 HTML 内容,并根据配置创建 Document 对象:spring-doc.cadn.net.cn

  • selector 决定了哪些元素用于文本提取。spring-doc.cadn.net.cn

  • 如果 allElementstrue,则 <body> 内的所有文本将被提取到单个 Document 中。spring-doc.cadn.net.cn

  • 如果 groupByElementtrue,则每个匹配 selector 的元素都会创建一个独立的 Documentspring-doc.cadn.net.cn

  • 如果 allElementsgroupByElement 都不是 true,则使用 separator 将匹配 selector 的所有元素的文本连接起来。spring-doc.cadn.net.cn

  • 文档标题、来自指定 <meta> 标签的内容,以及(可选的)链接 URL 会被添加到 Document 元数据中。spring-doc.cadn.net.cn

  • 用于解析相对链接的基础 URI 将从 URL 资源中提取。spring-doc.cadn.net.cn

读取器会保留所选元素的文本内容,但会移除其中的任何 HTML 标签。spring-doc.cadn.net.cn

Markdown

MarkdownDocumentReader 处理 Markdown 文档,将其转换为 Document 对象列表。spring-doc.cadn.net.cn

依赖项

使用 Maven 或 Gradle 将依赖项添加到您的项目中。spring-doc.cadn.net.cn

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-markdown-document-reader</artifactId>
</dependency>
dependencies {
    implementation 'org.springframework.ai:spring-ai-markdown-document-reader'
}

例举

@Component
class MyMarkdownReader {

    private final Resource resource;

    MyMarkdownReader(@Value("classpath:code.md") Resource resource) {
        this.resource = resource;
    }

    List<Document> loadMarkdown() {
        MarkdownDocumentReaderConfig config = MarkdownDocumentReaderConfig.builder()
            .withHorizontalRuleCreateDocument(true)
            .withIncludeCodeBlock(false)
            .withIncludeBlockquote(false)
            .withAdditionalMetadata("filename", "code.md")
            .build();

        MarkdownDocumentReader reader = new MarkdownDocumentReader(this.resource, config);
        return reader.get();
    }
}

MarkdownDocumentReaderConfig 允许您自定义 MarkdownDocumentReader 的行为:spring-doc.cadn.net.cn

  • horizontalRuleCreateDocument:当设置为 true 时,Markdown 中的水平线将创建新的 Document 对象。spring-doc.cadn.net.cn

  • includeCodeBlock: 当设置为 true 时,代码块将包含在与周围文本相同的 Document 中。当为 false 时,代码块会创建单独的 Document 对象。spring-doc.cadn.net.cn

  • includeBlockquote:当设置为 true 时,引用块将与周围文本包含在同一个 Document 中。当为 false 时,引用块会创建独立的 Document 对象。spring-doc.cadn.net.cn

  • additionalMetadata: 允许您向所有创建的 Document 对象添加自定义元数据。spring-doc.cadn.net.cn

示例文档:code.md

This is a Java sample application:

```java
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
```

Markdown also provides the possibility to `use inline code formatting throughout` the entire sentence.

---

Another possibility is to set block code without specific highlighting:

```
./mvnw spring-javaformat:apply
```

行为:MarkdownDocumentReader 处理 Markdown 内容,并根据配置创建 Document 对象:spring-doc.cadn.net.cn

阅读器会保留文档对象内容中的格式,如内联代码、列表和文本样式。spring-doc.cadn.net.cn

PDF 页面

PagePdfDocumentReader 使用 Apache PdfBox 库来解析 PDF 文档。spring-doc.cadn.net.cn

依赖项

使用 Maven 或 Gradle 将依赖项添加到您的项目中。spring-doc.cadn.net.cn

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-pdf-document-reader</artifactId>
</dependency>
dependencies {
    implementation 'org.springframework.ai:spring-ai-pdf-document-reader'
}

例举

@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();
    }

}

PDF 段落

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

依赖项

使用 Maven 或 Gradle 将依赖项添加到您的项目中。spring-doc.cadn.net.cn

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-pdf-document-reader</artifactId>
</dependency>
dependencies {
    implementation 'org.springframework.ai:spring-ai-pdf-document-reader'
}

例举

@Component
public class MyPagePdfDocumentReader {

	List<Document> getDocsFromPdfWithCatalog() {

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

	    return pdfReader.read();
    }
}

Tika(DOCX、PPTX、HTML…)

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

依赖项

使用 Maven 或 Gradle 将依赖项添加到您的项目中。spring-doc.cadn.net.cn

<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-tika-document-reader</artifactId>
</dependency>
dependencies {
    implementation 'org.springframework.ai:spring-ai-tika-document-reader'
}

例举

@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(this.resource);
        return tikaDocumentReader.read();
    }
}

转换器

文本分割器

TextSplitter 是一个抽象基类,用于帮助拆分文档以适应 AI 模型的上下文窗口。spring-doc.cadn.net.cn

TokenTextSplitter

TokenTextSplitterTextSplitter 的一个实现,它根据Tokens数量将文本分割成块,使用 CL100K_BASE 编码。spring-doc.cadn.net.cn

用法

基本用法
@Component
class MyTokenTextSplitter {

    public List<Document> splitDocuments(List<Document> documents) {
        TokenTextSplitter splitter = new TokenTextSplitter();
        return splitter.apply(documents);
    }

    public List<Document> splitCustomized(List<Document> documents) {
        TokenTextSplitter splitter = new TokenTextSplitter(1000, 400, 10, 5000, true, List.of('.', '?', '!', '\n'));
        return splitter.apply(documents);
    }
}
使用构建器模式

创建 TokenTextSplitter 的推荐方式是使用构建器模式,它提供了更易读且灵活的 API:spring-doc.cadn.net.cn

@Component
class MyTokenTextSplitter {

    public List<Document> splitWithBuilder(List<Document> documents) {
        TokenTextSplitter splitter = TokenTextSplitter.builder()
            .withChunkSize(1000)
            .withMinChunkSizeChars(400)
            .withMinChunkLengthToEmbed(10)
            .withMaxNumChunks(5000)
            .withKeepSeparator(true)
            .build();

        return splitter.apply(documents);
    }
}
自定义标点符号

您可以自定义用于将文本分割为具有语义意义的块儿的标点符号。这对于国际化特别有用:spring-doc.cadn.net.cn

@Component
class MyInternationalTextSplitter {

    public List<Document> splitChineseText(List<Document> documents) {
        // Use Chinese punctuation marks
        TokenTextSplitter splitter = TokenTextSplitter.builder()
            .withChunkSize(800)
            .withMinChunkSizeChars(350)
            .withPunctuationMarks(List.of('。', '?', '!', ';'))  // Chinese punctuation
            .build();

        return splitter.apply(documents);
    }

    public List<Document> splitWithCustomMarks(List<Document> documents) {
        // Mix of English and other punctuation marks
        TokenTextSplitter splitter = TokenTextSplitter.builder()
            .withChunkSize(800)
            .withPunctuationMarks(List.of('.', '?', '!', '\n', ';', ':', '。'))
            .build();

        return splitter.apply(documents);
    }
}

构造函数选项

TokenTextSplitter 提供了三种构造函数选项:spring-doc.cadn.net.cn

  1. TokenTextSplitter(): 使用默认设置创建分割器。spring-doc.cadn.net.cn

  2. TokenTextSplitter(boolean keepSeparator): 创建一个具有自定义分隔符行为的分割器。spring-doc.cadn.net.cn

  3. TokenTextSplitter(int chunkSize, int minChunkSizeChars, int minChunkLengthToEmbed, int maxNumChunks, boolean keepSeparator, List<Character> punctuationMarks): 包含所有自定义选项的完整构造函数。spring-doc.cadn.net.cn

建造者模式(如上所示)是创建具有自定义配置实例的推荐方法。

参数

行为

TokenTextSplitter 按以下方式处理文本内容:spring-doc.cadn.net.cn

  1. 它使用 CL100K_BASE 编码将输入文本编码为Tokens。spring-doc.cadn.net.cn

  2. 它根据 chunkSize 将编码后的文本分割成块。spring-doc.cadn.net.cn

  3. 对于每个块:spring-doc.cadn.net.cn

    1. 它将数据块解码回文本。spring-doc.cadn.net.cn

    2. 仅当总Tokens数超过分块大小时,它才会尝试在 minChunkSizeChars 之后找到一个合适的断点(使用配置的 punctuationMarks)。spring-doc.cadn.net.cn

    3. 如果找到断点,它会在该点截断块。spring-doc.cadn.net.cn

    4. 它会根据 keepSeparator 设置修剪代码块,并可选择性地移除换行符。spring-doc.cadn.net.cn

    5. 如果生成的块长度大于 minChunkLengthToEmbed,则将其添加到输出中。spring-doc.cadn.net.cn

  4. 此过程会持续进行,直到所有Tokens处理完毕或达到 maxNumChunksspring-doc.cadn.net.cn

  5. 任何剩余文本如果长度大于 minChunkLengthToEmbed,将作为最后一个块添加。spring-doc.cadn.net.cn

基于标点的拆分仅在Tokens数量超过块大小时适用。完全匹配或小于块大小的文本将作为单个块返回,不会进行基于标点的截断。这可避免对小型文本进行不必要的拆分。

例举

Document doc1 = new Document("This is a long piece of text that needs to be split into smaller chunks for processing.",
        Map.of("source", "example.txt"));
Document doc2 = new Document("Another document with content that will be split based on token count.",
        Map.of("source", "example2.txt"));

TokenTextSplitter splitter = new TokenTextSplitter();
List<Document> splitDocuments = this.splitter.apply(List.of(this.doc1, this.doc2));

for (Document doc : splitDocuments) {
    System.out.println("Chunk: " + doc.getContent());
    System.out.println("Metadata: " + doc.getMetadata());
}

注释

  • TokenTextSplitter 使用来自 jtokkit 库的 CL100K_BASE 编码,该编码与较新的 OpenAI 模型兼容。spring-doc.cadn.net.cn

  • 分割器尝试在可能的情况下于句子边界处进行拆分,以创建具有语义意义的块。spring-doc.cadn.net.cn

  • 来自原始文档的元数据将被保留,并复制到从该文档派生的所有块中。spring-doc.cadn.net.cn

  • 如果将 copyContentFormatter 设置为 true(默认行为),原始文档中的内容格式化器(如果已设置)也会被复制到派生的块中。spring-doc.cadn.net.cn

  • 此分割器特别适用于为具有Tokens限制的大型语言模型准备文本,确保每个块都在模型的处理能力范围内。spring-doc.cadn.net.cn

  • 自定义标点符号:默认标点符号(.?!\n)适用于英文文本。对于其他语言或专业内容,请使用构建器的 withPunctuationMarks() 方法自定义标点符号。spring-doc.cadn.net.cn

  • 性能考虑:虽然分割器可以处理任意数量的标点符号,但为了获得最佳性能,建议将列表保持在合理的小规模(少于 20 个字符),因为每个块都会检查每个标记。spring-doc.cadn.net.cn

  • 可扩展性getLastPunctuationIndex(String) 方法是 protected,允许子类重写标点检测逻辑以满足特定用例。spring-doc.cadn.net.cn

  • 小文本处理:自 2.0 版本起,小文本(Tokens数量等于或低于分块大小)不再在标点符号处拆分,从而避免了对已符合大小限制的内容进行不必要的碎片化。spring-doc.cadn.net.cn

ContentFormatTransformer

确保所有文档的内容格式统一。spring-doc.cadn.net.cn

KeywordMetadataEnricher

KeywordMetadataEnricher 是一个 DocumentTransformer,它使用生成式 AI 模型从文档内容中提取关键词并将其添加为元数据。spring-doc.cadn.net.cn

用法

@Component
class MyKeywordEnricher {

    private final ChatModel chatModel;

    MyKeywordEnricher(ChatModel chatModel) {
        this.chatModel = chatModel;
    }

    List<Document> enrichDocuments(List<Document> documents) {
        KeywordMetadataEnricher enricher = KeywordMetadataEnricher.builder(chatModel)
                .keywordCount(5)
                .build();

        // Or use custom templates
        KeywordMetadataEnricher enricher = KeywordMetadataEnricher.builder(chatModel)
               .keywordsTemplate(YOUR_CUSTOM_TEMPLATE)
               .build();

        return enricher.apply(documents);
    }
}

构造函数选项

KeywordMetadataEnricher 提供了两种构造函数选项:spring-doc.cadn.net.cn

  1. KeywordMetadataEnricher(ChatModel chatModel, int keywordCount): 使用默认模板并提取指定数量的关键词。spring-doc.cadn.net.cn

  2. KeywordMetadataEnricher(ChatModel chatModel, PromptTemplate keywordsTemplate): 使用自定义模板进行关键词提取。spring-doc.cadn.net.cn

行为

KeywordMetadataEnricher 按以下方式处理文档:spring-doc.cadn.net.cn

  1. 对于每个输入文档,它都会使用该文档的内容创建一个提示。spring-doc.cadn.net.cn

  2. 它将此提示发送到提供的 ChatModel 以生成关键词。spring-doc.cadn.net.cn

  3. 生成的关键词会以键 "excerpt_keywords" 添加到文档的元数据中。spring-doc.cadn.net.cn

  4. 返回已增强的文档。spring-doc.cadn.net.cn

自定义

您可以使用默认模板,或通过 keywordsTemplate 参数自定义模板。 默认模板为:spring-doc.cadn.net.cn

\{context_str}. Give %s unique keywords for this document. Format as comma separated. Keywords:

其中 {context_str} 将被替换为文档内容,%s 将被替换为指定的关键词数量。spring-doc.cadn.net.cn

例举

ChatModel chatModel = // initialize your chat model
KeywordMetadataEnricher enricher = KeywordMetadataEnricher.builder(chatModel)
                .keywordCount(5)
                .build();

// Or use custom templates
KeywordMetadataEnricher enricher = KeywordMetadataEnricher.builder(chatModel)
                .keywordsTemplate(new PromptTemplate("Extract 5 important keywords from the following text and separate them with commas:\n{context_str}"))
                .build();

Document doc = new Document("This is a document about artificial intelligence and its applications in modern technology.");

List<Document> enrichedDocs = enricher.apply(List.of(this.doc));

Document enrichedDoc = this.enrichedDocs.get(0);
String keywords = (String) this.enrichedDoc.getMetadata().get("excerpt_keywords");
System.out.println("Extracted keywords: " + keywords);

注释

SummaryMetadataEnricher

SummaryMetadataEnricher 是一个 DocumentTransformer,它使用生成式 AI 模型为文档创建摘要并将其作为元数据添加。它可以为当前文档以及相邻文档(前一篇和后一篇)生成摘要。spring-doc.cadn.net.cn

用法

@Configuration
class EnricherConfig {

    @Bean
    public SummaryMetadataEnricher summaryMetadata(OpenAiChatModel aiClient) {
        return new SummaryMetadataEnricher(aiClient,
            List.of(SummaryType.PREVIOUS, SummaryType.CURRENT, SummaryType.NEXT));
    }
}

@Component
class MySummaryEnricher {

    private final SummaryMetadataEnricher enricher;

    MySummaryEnricher(SummaryMetadataEnricher enricher) {
        this.enricher = enricher;
    }

    List<Document> enrichDocuments(List<Document> documents) {
        return this.enricher.apply(documents);
    }
}

构造函数

SummaryMetadataEnricher 提供了两个构造函数:spring-doc.cadn.net.cn

  1. SummaryMetadataEnricher(ChatModel chatModel, List<SummaryType> summaryTypes)spring-doc.cadn.net.cn

  2. SummaryMetadataEnricher(ChatModel chatModel, List<SummaryType> summaryTypes, String summaryTemplate, MetadataMode metadataMode)spring-doc.cadn.net.cn

参数

行为

SummaryMetadataEnricher 按以下方式处理文档:spring-doc.cadn.net.cn

  1. 对于每个输入文档,它会根据文档内容和指定的摘要模板创建一个提示。spring-doc.cadn.net.cn

  2. 它将此提示发送到提供的 ChatModel 以生成摘要。spring-doc.cadn.net.cn

  3. 根据指定的 summaryTypes,它会向每个文档添加以下元数据:spring-doc.cadn.net.cn

  4. 返回已增强的文档。spring-doc.cadn.net.cn

自定义

摘要生成提示可以通过提供自定义的 summaryTemplate 进行定制。默认模板为:spring-doc.cadn.net.cn

"""
Here is the content of the section:
{context_str}

Summarize the key topics and entities of the section.

Summary:
"""

例举

ChatModel chatModel = // initialize your chat model
SummaryMetadataEnricher enricher = new SummaryMetadataEnricher(chatModel,
    List.of(SummaryType.PREVIOUS, SummaryType.CURRENT, SummaryType.NEXT));

Document doc1 = new Document("Content of document 1");
Document doc2 = new Document("Content of document 2");

List<Document> enrichedDocs = enricher.apply(List.of(this.doc1, this.doc2));

// Check the metadata of the enriched documents
for (Document doc : enrichedDocs) {
    System.out.println("Current summary: " + doc.getMetadata().get("section_summary"));
    System.out.println("Previous summary: " + doc.getMetadata().get("prev_section_summary"));
    System.out.println("Next summary: " + doc.getMetadata().get("next_section_summary"));
}

提供的示例展示了预期的行为:spring-doc.cadn.net.cn

注释

  • SummaryMetadataEnricher 需要正常运行的 ChatModel 来生成摘要。spring-doc.cadn.net.cn

  • 增强器可以处理任意大小的文档列表,并妥善处理首尾文档的边界情况。spring-doc.cadn.net.cn

  • 此增强器特别适用于创建上下文感知的摘要,从而更好地理解序列中文档之间的关系。spring-doc.cadn.net.cn

  • MetadataMode 参数允许控制现有元数据如何被纳入摘要生成过程。spring-doc.cadn.net.cn

作者

file

FileDocumentWriter 是一个 DocumentWriter 实现,用于将 Document 对象列表的内容写入文件。spring-doc.cadn.net.cn

用法

@Component
class MyDocumentWriter {

    public void writeDocuments(List<Document> documents) {
        FileDocumentWriter writer = new FileDocumentWriter("output.txt", true, MetadataMode.ALL, false);
        writer.accept(documents);
    }
}

构造函数

FileDocumentWriter 提供了三个构造函数:spring-doc.cadn.net.cn

  1. FileDocumentWriter(String fileName)spring-doc.cadn.net.cn

  2. FileDocumentWriter(String fileName, boolean withDocumentMarkers)spring-doc.cadn.net.cn

  3. FileDocumentWriter(String fileName, boolean withDocumentMarkers, MetadataMode metadataMode, boolean append)spring-doc.cadn.net.cn

参数

行为

FileDocumentWriter 按以下方式处理文档:spring-doc.cadn.net.cn

  1. 它为指定的文件名打开一个 FileWriter。spring-doc.cadn.net.cn

  2. 对于输入列表中的每个文档:spring-doc.cadn.net.cn

    1. 如果 withDocumentMarkers 为真,则写入一个包含文档索引和页码的文档标记。spring-doc.cadn.net.cn

    2. 它根据指定的 metadataMode 写入文档的格式化内容。spring-doc.cadn.net.cn

  3. 所有文档写入完成后,文件将被关闭。spring-doc.cadn.net.cn

文档标记

withDocumentMarkers 设置为 true 时,写入器会按以下格式为每个文档包含标记:spring-doc.cadn.net.cn

### Doc: [index], pages:[start_page_number,end_page_number]

元数据处理

作者使用了两个特定的元数据键:spring-doc.cadn.net.cn

这些用于编写文档标记。spring-doc.cadn.net.cn

例举

List<Document> documents = // initialize your documents
FileDocumentWriter writer = new FileDocumentWriter("output.txt", true, MetadataMode.ALL, true);
writer.accept(documents);

这将把所有文档(包括文档标记)写入"output.txt",使用所有可用的元数据,并在文件已存在时追加内容。spring-doc.cadn.net.cn

注释

  • 写入器使用 FileWriter,因此它会以操作系统的默认字符编码写入文本文件。spring-doc.cadn.net.cn

  • 如果在写入过程中发生错误,将抛出一个 RuntimeException,其原因为原始异常。spring-doc.cadn.net.cn

  • metadataMode 参数允许控制如何将现有元数据整合到写入的内容中。spring-doc.cadn.net.cn

  • 此写入器特别适用于调试或创建文档集合的可读输出。spring-doc.cadn.net.cn

向量存储

提供与各种向量存储的集成。 请参阅 向量数据库文档 获取完整列表。spring-doc.cadn.net.cn