|
此版本仍在开发中,尚未被视为稳定版。为了获取最新的快照版本,请使用Spring AI 1.1.3! |
ETL 管道
提取、转换和加载(ETL)框架是RAG场景中数据处理的核心。
ETL管道组织了从原始数据源到结构化向量存储的数据流,确保数据以适合AI模型检索的最优格式存在。
RAG应用场景是通过文本增强生成模型的能力,从大量数据中检索相关信息,以提高生成输出的质量和相关性。
API概述
ETL管道创建、转换和存储了Document实例。

The Document类包含文本、元数据,以及可选的其他媒体类型,如图片、音频和视频。
ETL数据流程由三个主要组成部分构成。
-
那么实现
-
那么实现
-
那么实现
The Document class content is created from PDFs, text files and other document types with the help of DocumentReader.
要构建一个简单的ETL管道,你可以将每种类型的实例连接在一起。

假设我们有以下这三种ETL类型的实例。
-
PagePdfDocumentReader是一种实现方式DocumentReader -
TokenTextSplitter是一种实现方式DocumentTransformer -
VectorStore是一种实现方式DocumentWriter
为了在向量数据库中进行基本加载,以便与检索增强生成模式一起使用,使用以下代码在Java函数风格语法下。
vectorStore.accept(tokenTextSplitter.apply(pdfReader.get()));
或者,你可以使用更适合领域的方法名。
vectorStore.write(tokenTextSplitter.split(pdfReader.read()));
ETL InterfacesETL接口
ETL管道由以下接口和实现组成。 详细的ETL类图在ETL类图部分展示。
文档读取器
提供来自不同来源的文档。
public interface DocumentReader extends Supplier<List<Document>> {
default List<Document> read() {
return get();
}
}
文档转换器
该组件负责批量处理一批文档,作为整个处理工作流程的一部分。
public interface DocumentTransformer extends Function<List<Document>, List<Document>> {
default List<Document> transform(List<Document> transform) {
return apply(transform);
}
}
文档编写器
处理ETL流程的最后阶段,准备文档供存储。
public interface DocumentWriter extends Consumer<List<Document>> {
default void write(List<Document> documents) {
accept(documents);
}
}
文档读取器DocumentReaders
JSON
The 零 processes JSON documents, converting them into a list of 一 objects.
示例
@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提供了一些构造器选项:
-
JsonReader(Resource resource) -
JsonReader(Resource resource, String… jsonKeysToUse) -
JsonReader(Resource resource, JsonMetadataGenerator jsonMetadataGenerator, String… jsonKeysToUse)
参数
-
resource: 一个SpringResource对象指向JSON文件。 -
`0`:从JSON中取出的一组键,这些键将作为结果中`1`对象的文本内容。
-
jsonMetadataGenerator: 可选的JsonMetadataGenerator用于创建每个Document的元数据。
行为
0 处理JSON内容如下:
-
该框架支持处理JSON数组和单个JSON对象。
-
对于每个JSON对象(无论是数组中的一个对象,还是单独的一个对象):
-
它基于指定的
jsonKeysToUse提取内容。 -
如果没有指定键,它会使用整个JSON对象作为内容。
-
It generates metadata using the provided
JsonMetadataGenerator(or an empty one if not provided). -
It creates a
Documentobject with the extracted content and metadata.
-
使用JSON指针
0 现在支持使用 JSON Pointers 获取 JSON 文档中的具体部分。这个功能允许您轻松从复杂 JSON 结构中提取嵌套数据。
0方法
public List<Document> get(String pointer)
该方法允许你使用JSON指针来获取特定的JSON文档部分。
参数
-
pointer: 一个根据RFC 6901规定定义的JSON指针字符串,用于定位JSON结构中的所需元素。
示例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.
C0文本
The TextReader处理纯文本文件,将其转换为一个由Document对象组成的列表中。
示例
@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();
}
}
参数
-
resourceUrl: 表示要读取的资源的URL字符串。 -
resource: SpringResource对象指向文本文件。
配置
-
参数
setCharset(Charset charset):指定读取文本文件时使用的字符集。默认值为UTF-8。 -
0: Returns a mutable map where you can add custom metadata for the documents.
行为
The TextReader processes text content as follows:
-
It reads the entire content of the text file into a single
Documentobject. -
文件的内容将存储在标记0中。
-
Metadata会被自动添加到
零:-
charset: 字符集用于读取文件(默认值:"UTF-8")。 -
source: 源文本文件的文件名.
-
-
任何自定义的元数据,通过添加
getCustomMetadata()的方式包含在内,将包含在Document中。
注释
-
The
TextReader一次性读取文件内容到内存中,因此,它可能不适合处理非常大的文件。 -
If you need to split the text into smaller chunks, you can use a text splitter like
TokenTextSplitterafter reading the document:
List<Document> documents = textReader.get();
List<Document> splitDocuments = TokenTextSplitter.builder().build().apply(this.documents);
-
读者使用Spring的0版本抽象层,允许其从各种来源读取,如类路径、文件系统、URL等。
-
可以为所有由读者创建的文档添加自定义元数据。
HTML(JSoup)
JsoupDocumentReader 会处理HTML文档,使用JSoup库将其转换为 Document 对象的列表。
依赖项
使用 Maven 或 Gradle 将依赖项添加到您的项目中。
-
Maven
-
Gradle
<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 的行为:
-
charset:指定HTML文档的字符编码(默认为“UTF-8”)。 -
selector: 一个JSoup CSS选择器,用于指定从中提取文本的元素(默认为"body")。 -
separator: 用于连接来自多个选定元素的文本的字符串(默认为“\n”)。 -
allElements:如果为true,则从<body>元素中提取所有文本,忽略selector(默认为false)。 -
groupByElement:如果为true,则为每个由selector匹配到的元素创建一个独立的Document(默认值为false)。 -
includeLinkUrls:如果为true,则提取绝对链接URL并将其添加到元数据中(默认为false)。 -
metadataTags:要从中提取内容的<meta>标签名称列表(默认为["description", "keywords"])。 -
additionalMetadata:允许您向所有创建的Document对象添加自定义元数据。
示例文档: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>© 2024 John Doe</p>
</footer>
</body>
</html>
Behavior:
The JsoupDocumentReader processes the HTML content and creates Document objects based on the configuration:
-
The
selectordetermines which elements are used for text extraction. -
如果
allElements是true,则<body>内的所有文本将被提取到一个单独的Document中。 -
如果
groupByElement是true,则每个匹配selector的元素都会创建一个单独的Document。 -
如果
allElements和groupByElement都不是true,则匹配selector的所有元素的文本将使用separator连接。 -
文档标题、来自指定
<meta>标签的内容,以及(可选)链接 URL 会被添加到Document元数据中。 -
基础 URI 将从 URL 资源中提取,用于解析相对链接。
读者保留所选元素的文本内容,但移除其中的任何 HTML 标签。
Markdown
The MarkdownDocumentReader processes Markdown documents, converting them into a list of Document objects.
依赖项
使用 Maven 或 Gradle 将依赖项添加到您的项目中。
-
Maven
-
Gradle
<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:
-
horizontalRuleCreateDocument: 当设置为true时,Markdown 中的水平线将创建新的Document对象。 -
includeCodeBlock: 当设置为true时,代码块将与周围文本位于同一个Document中。当设置为false时,代码块会创建独立的Document对象。 -
includeBlockquote: 当设置为true时,引用块将与周围文本位于同一Document中。当设置为false时,引用块会创建单独的Document对象。 -
additionalMetadata:允许您向所有创建的Document对象添加自定义元数据。
示例文档: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 对象。
-
头部信息在 Document 对象中成为元数据。
-
段落成为 Document 对象的内容。
-
代码块可以被分离成独立的 Document 对象,也可以与周围文本一起包含。
-
块引用可以被分离成独立的 Document 对象,也可以与周围文本一起包含。
-
水平线可用于将内容拆分为独立的 Document 对象。
读者会保留文档对象内容中的格式,例如内联代码、列表和文本样式。
PDF 页面
The PagePdfDocumentReader uses Apache PdfBox library to parse PDF documents.
依赖项
使用 Maven 或 Gradle 将依赖项添加到您的项目中。
-
Maven
-
Gradle
<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.
依赖项
使用 Maven 或 Gradle 将依赖项添加到您的项目中。
-
Maven
-
Gradle
<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.
依赖项
使用 Maven 或 Gradle 将依赖项添加到您的项目中。
-
Maven
-
Gradle
<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();
}
}
转换器
Tokens文本拆分器
TokenTextSplitter 是一种基于标记数量将文本拆分为块的 TextSplitter 实现。它支持可配置的编码类型(例如 CL100K_BASE、P50K_BASE、O200K_BASE),默认使用 CL100K_BASE。
用法
基本用法
@Component
class MyTokenTextSplitter {
public List<Document> splitDocuments(List<Document> documents) {
TokenTextSplitter splitter = TokenTextSplitter.builder().build();
return splitter.apply(documents);
}
public List<Document> splitCustomized(List<Document> documents) {
TokenTextSplitter splitter = TokenTextSplitter.builder()
.withChunkSize(1000)
.withMinChunkSizeChars(400)
.withMinChunkLengthToEmbed(10)
.withMaxNumChunks(5000)
.withKeepSeparator(true)
.build();
return splitter.apply(documents);
}
}
自定义编码类型
您可以配置用于分词的编码类型。这在使用不同分词器的模型时非常有用:
TokenTextSplitter splitter = TokenTextSplitter.builder()
.withEncodingType(EncodingType.O200K_BASE)
.withChunkSize(1000)
.build();
自定义标点符号
您可以自定义用于将文本拆分为语义上有意义的片段的标点符号。这对于国际化尤其有用:
@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);
}
}
参数
-
encodingType: 要使用的标记化编码类型(默认:CL100K_BASE)。支持的值包括CL100K_BASE、P50K_BASE和O200K_BASE。 -
chunkSize: 每个文本块的目标大小(以标记为单位)(默认值:800)。 -
minChunkSizeChars: 每个文本块的最小字符数(默认值:350)。 -
minChunkLengthToEmbed: 要包含的分块的最小长度(默认:5)。 -
maxNumChunks: 从文本中生成的最大分块数量(默认:10000)。 -
keepSeparator: 是否在分块中保留分隔符(如换行符)(默认:true)。 -
punctuationMarks: 用于作为句子边界进行拆分的字符列表(默认值:.,?,!,\n)。
行为
The TokenTextSplitter processes text content as follows:
-
它使用 CL100K_BASE 编码将输入文本编码为标记。
-
它根据
chunkSize将编码后的文本拆分为若干块。 -
对于每个块:
-
它将该数据块解码回文本。
-
仅当总标记数超过分块大小时,它才会尝试在
minChunkSizeChars之后找到一个合适的断点(使用配置的punctuationMarks)。 -
如果发现断点,则在该点截断数据块。
-
它会裁剪该块,并根据
keepSeparator设置可选地移除换行符。 -
如果生成的片段长度大于
minChunkLengthToEmbed,则将其添加到输出中。
-
-
此过程将持续,直到所有标记被处理完毕或达到
maxNumChunks。 -
任何剩余的文本如果长度大于
minChunkLengthToEmbed,则作为最后一块添加。
| 仅当标记数量超过分块大小时,基于标点的拆分才会生效。与分块大小完全匹配或小于分块大小的文本将作为一个单独的分块返回,不会进行基于标点的截断。这可以避免对小文本进行不必要的拆分。 |
示例
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 = TokenTextSplitter.builder().build();
List<Document> splitDocuments = splitter.apply(List.of(doc1, doc2));
for (Document doc : splitDocuments) {
System.out.println("Chunk: " + doc.getContent());
System.out.println("Metadata: " + doc.getMetadata());
}
注释
-
The
TokenTextSplitteruses the CL100K_BASE encoding from thejtokkitlibrary, which is compatible with newer OpenAI models. -
拆分器会尝试在可能的情况下,以句子边界为依据,创建语义上有意义的片段。
-
原始文档的元数据会被保留,并复制到从该文档派生的所有分块中。
-
如果将
copyContentFormatter设置为true(默认行为),则原始文档中的内容格式化器(如果已设置)也会被复制到派生的片段中。 -
该分词器特别适用于为具有标记限制的大型语言模型准备文本,确保每个片段都在模型的处理能力范围内。
-
自定义标点符号:默认的标点符号(
.、?、!、\n) 适用于英语文本。对于其他语言或特殊内容,可以使用构建器的withPunctuationMarks()方法自定义标点符号。 -
性能考虑:虽然分词器可以处理任意数量的标点符号,但为了获得最佳性能,建议将列表保持在合理的小范围内(少于20个字符),因为每个标记都会被逐个检查。
-
可扩展性:
getLastPunctuationIndex(String)方法是protected,允许子类覆盖标点符号检测逻辑以用于特定用例。 -
小文本处理:自版本2.0起,小文本(标记数量等于或低于分块大小)不再在标点符号处进行拆分,从而避免了对已符合大小限制的内容进行不必要的碎片化。
关键字元数据丰富器
The KeywordMetadataEnricher is a DocumentTransformer that uses a generative AI model to extract keywords from document content and add them as metadata.
用法
@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 提供了两种构造方式:
-
KeywordMetadataEnricher(ChatModel chatModel, int keywordCount): 使用默认模板并提取指定数量的关键词。 -
KeywordMetadataEnricher(ChatModel chatModel, PromptTemplate keywordsTemplate): 使用自定义模板进行关键词提取。
行为
The KeywordMetadataEnricher processes documents as follows:
-
对于每个输入文档,它会使用该文档的内容创建一个提示。
-
它会将此提示发送到提供的
ChatModel以生成关键字。 -
生成的关键词被添加到文档的元数据中,键为“excerpt_keywords”。
-
丰富的文档已返回。
自定义
您可以使用默认模板,或通过 keywordsTemplate 参数自定义模板。 默认模板为:
\{context_str}. Give %s unique keywords for this document. Format as comma separated. Keywords:
其中 {context_str} 被替换为文档内容,%s 被替换为指定的关键词数量。
示例
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。它可以为当前文档以及相邻文档(上一篇和下一篇)生成摘要。
用法
@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 提供了两个构造函数:
-
SummaryMetadataEnricher(ChatModel chatModel, List<SummaryType> summaryTypes) -
SummaryMetadataEnricher(ChatModel chatModel, List<SummaryType> summaryTypes, String summaryTemplate, MetadataMode metadataMode)
参数
-
chatModel: 用于生成摘要的AI模型。 -
summaryTypes: 一个包含SummaryType枚举值的列表,用于指示生成哪些摘要(PREVIOUS、CURRENT、NEXT)。 -
summaryTemplate: 用于摘要生成的自定义模板(可选)。 -
metadataMode: 指定在生成摘要时如何处理文档元数据(可选)。
行为
The SummaryMetadataEnricher processes documents as follows:
-
对于每个输入文档,它都会使用文档内容和指定的摘要模板创建一个提示。
-
它将此提示发送到提供的
ChatModel以生成摘要。 -
根据指定的
summaryTypes,它会向每个文档添加以下元数据:-
section_summary: 当前文档的摘要。 -
prev_section_summary: 上一份文档的摘要(如果可用且已请求)。 -
next_section_summary: 下一个文档的摘要(如果可用且已请求)。
-
-
丰富的文档已返回。
自定义
摘要生成提示可以通过提供自定义的 summaryTemplate 来进行定制。默认模板为:
"""
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"));
}
所提供的示例演示了预期的行为:
-
对于两份文档的列表,这两份文档均收到
section_summary。 -
第一个文档接收一个
next_section_summary,但没有prev_section_summary。 -
第二个文档接收一个
prev_section_summary,但没有next_section_summary。 -
第一个文档的
section_summary与第二个文档的prev_section_summary匹配。 -
第一个文档的
next_section_summary与第二个文档的section_summary匹配。
编写器
文件
FileDocumentWriter 是一个 DocumentWriter 实现,用于将一组 Document 对象的内容写入文件。
用法
@Component
class MyDocumentWriter {
public void writeDocuments(List<Document> documents) {
FileDocumentWriter writer = new FileDocumentWriter("output.txt", true, MetadataMode.ALL, false);
writer.accept(documents);
}
}
构造函数
FileDocumentWriter 提供了三个构造函数:
-
FileDocumentWriter(String fileName) -
FileDocumentWriter(String fileName, boolean withDocumentMarkers) -
FileDocumentWriter(String fileName, boolean withDocumentMarkers, MetadataMode metadataMode, boolean append)
参数
-
fileName: 要写入文档的文件名。 -
withDocumentMarkers: 是否在输出中包含文档标记(默认:false)。 -
metadataMode: 指定要写入文件的文档内容(默认值:MetadataMode.NONE)。 -
append: 如果为 true,数据将写入文件末尾而非开头(默认值:false)。
行为
The FileDocumentWriter processes documents as follows:
-
它为指定的文件名打开一个 FileWriter。
-
对于输入列表中的每个文档:
-
如果
withDocumentMarkers为真,则写入一个包含文档索引和页码的文档标记。 -
它根据指定的
metadataMode写入文档的格式化内容。
-
-
文件在所有文档写入完成后关闭。
文档标记
当将 withDocumentMarkers 设置为 true 时,写入器会以以下格式为每个文档包含标记:
### Doc: [index], pages:[start_page_number,end_page_number]
向量存储
提供与各种向量存储的集成。 请参阅 向量数据库文档 以获取完整列表。
