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

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

ETL数据流程由三个主要组成部分构成。spring-doc.cadn.net.cn

The Document class content is created from PDFs, text files and other document types with the help of DocumentReader.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 InterfacesETL接口

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

文档读取器DocumentReaders

JSON

The processes JSON documents, converting them into a list of objects.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();
	}
}

构造器选项

The 代码0提供了一些构造器选项: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

参数

行为

0 处理JSON内容如下:spring-doc.cadn.net.cn

使用JSON指针

0 现在支持使用 JSON Pointers 获取 JSON 文档中的具体部分。这个功能允许您轻松从复杂 JSON 结构中提取嵌套数据。spring-doc.cadn.net.cn

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

该方法允许你使用JSON指针来获取特定的JSON文档部分。spring-doc.cadn.net.cn

参数
  • pointer: 一个根据RFC 6901规定定义的JSON指针字符串,用于定位JSON结构中的所需元素。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."
  }
]

In this example, if the JsonReader is configured with "description" as the jsonKeysToUse, it will create Document objects where the content is the value of the "description" field for each bike in the array.spring-doc.cadn.net.cn

注释

  • JsonReader 使用 Jackson 进行 JSON 解析。spring-doc.cadn.net.cn

  • 它可以高效地处理大型JSON文件,通过流式处理数组来实现。spring-doc.cadn.net.cn

  • 如果在jsonKeysToUse中指定了多个键,则内容将是这些键值的合并。spring-doc.cadn.net.cn

  • 可调整和灵活的设计允许对JSON结构进行定制。 jsonKeysToUseJsonMetadataGenerator 可以根据需要进行修改。spring-doc.cadn.net.cn

C0文本

The 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

  • 0: Returns a mutable map where you can add custom metadata for the documents.spring-doc.cadn.net.cn

行为

The TextReader processes text content as follows:spring-doc.cadn.net.cn

注释

  • The TextReader 一次性读取文件内容到内存中,因此,它可能不适合处理非常大的文件。spring-doc.cadn.net.cn

  • If you need to split the text into smaller chunks, you can use a text splitter like TokenTextSplitter after reading the document:spring-doc.cadn.net.cn

List<Document> documents = textReader.get();
List<Document> splitDocuments = new TokenTextSplitter().apply(this.documents);
  • 读者使用Spring的0版本抽象层,允许其从各种来源读取,如类路径、文件系统、URL等。spring-doc.cadn.net.cn

  • 可以为所有由读者创建的文档添加自定义元数据。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>

The JsoupDocumentReader processes the HTML content and creates Document objects based on the configuration:spring-doc.cadn.net.cn

  • The selector determines which elements are used for text extraction.spring-doc.cadn.net.cn

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

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

  • 如果allElementsgroupByElement都不是true,则匹配selector的所有元素的文本将使用separator连接。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

The MarkdownDocumentReader processes Markdown documents, converting them into a list of Document objects.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();
    }
}

The MarkdownDocumentReaderConfig allows you to customize the behavior of the 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 页面

The PagePdfDocumentReader uses Apache PdfBox library to parse PDF documents.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段落

The ParagraphPdfDocumentReader uses the PDF catalog (e.g. TOC) information to split the input PDF into text paragraphs and output a single Document per paragraph. NOTE: Not all PDF documents contain the PDF catalog.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…​)

The TikaDocumentReader uses Apache Tika to extract text from a variety of document formats, such as PDF, DOC/DOCX, PPT/PPTX, and HTML. For a comprehensive list of supported formats, refer to the Tika documentation.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();
    }
}

转换器

文本拆分器

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

Tokens文本拆分器

The TokenTextSplitter is an implementation of TextSplitter that splits text into chunks based on token count, using the CL100K_BASE encoding.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);
    }
}

构造器选项

The TokenTextSplitter provides three constructor options: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

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

参数

行为

The TokenTextSplitter processes text content as follows:spring-doc.cadn.net.cn

  1. 它使用 CL100K_BASE 编码将输入文本编码为标记。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. 仅当总标记数超过分块大小时,它才会尝试在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. 此过程将持续,直到所有标记被处理完毕或达到maxNumChunksspring-doc.cadn.net.cn

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

仅当标记数量超过分块大小时,基于标点的拆分才会生效。与分块大小完全匹配或小于分块大小的文本将作为一个单独的分块返回,不会进行基于标点的截断。这可以避免对小文本进行不必要的拆分。

示例

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

注释

  • The TokenTextSplitter uses the CL100K_BASE encoding from the jtokkit library, which is compatible with newer OpenAI models.spring-doc.cadn.net.cn

  • 拆分器会尝试在可能的情况下,以句子边界为依据,创建语义上有意义的片段。spring-doc.cadn.net.cn

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

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

  • 该分词器特别适用于为具有标记限制的大型语言模型准备文本,确保每个片段都在模型的处理能力范围内。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起,小文本(标记数量等于或低于分块大小)不再在标点符号处进行拆分,从而避免了对已符合大小限制的内容进行不必要的碎片化。spring-doc.cadn.net.cn

内容格式转换器

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

关键字元数据丰富器

The KeywordMetadataEnricher is a DocumentTransformer that uses a generative AI model to extract keywords from document content and add them as metadata.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

行为

The KeywordMetadataEnricher processes documents as follows: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 是一个使用生成式 AI 模型为文档创建摘要并将其作为元数据添加的 DocumentTransformer。它可以为当前文档以及相邻文档(上一篇和下一篇)生成摘要。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

参数

行为

The SummaryMetadataEnricher processes documents as follows: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

编写器

文件

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

参数

行为

The FileDocumentWriter processes documents as follows: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