Spring AI 中的 DocumentTransformer 与 RAG 深度解析
本文将深入解析 Spring AI 中的 DocumentTransformer 和检索增强生成(RAG)模块,详细讲解每个核心类的功能、参数、使用方法以及高级技巧。通过结合实际代码示例和应用场景,帮助开发者全面掌握这些组件的使用。
一、Spring AI 中的 DocumentTransformer
DocumentTransformer 是 Spring AI ETL(Extract, Transform, Load)管道的关键组件,负责对文档执行转换操作,确保数据以最优格式进入后续的存储和检索阶段。

1.1 核心功能与实现类
DocumentTransformer 提供了多种实现类,每种实现类针对不同的转换需求提供了专门的功能。
1.1.1 TextSplitter:文档切割
功能描述
TextSplitter 用于将长文档切割成更小的文本块,以适应 AI 模型的上下文窗口限制。
核心实现类:TokenTextSplitter
- 基于 Token 分割:采用 CL100K_BASE 编码,支持按 Token 数量分割文本。
- 参数解析:
defaultChunkSize:每个文本块的目标 Token 数量(默认 800)。minChunkSizeChars:每个文本块的最小字符数(默认 350)。minChunkLengthToEmbed:可嵌入分块的最小长度(默认 5)。maxNumChunks:单个文本生成的最大分块数(默认 10000)。keepSeparator:是否保留分隔符(默认 true)。
使用示例:
TokenTextSplitter splitter = new TokenTextSplitter(500, 200, 10, 10000, true);
List<Document> splitDocuments = splitter.apply(documents);
高级技巧:
- 动态分块:根据文档类型动态调整分块大小。例如,技术文档可采用更小的分块以保留细节。
- 分块优化:在分块时尽量保持语义完整性,避免在句子中间切割。
效果:
- 提高检索效率:小块文档更容易与查询匹配。
- 节省内存:避免加载整个文档到内存。
1.1.2 ContentFormatTransformer:元数据格式化
功能描述
ContentFormatTransformer 将文档中的元数据转换为键值对格式,确保数据一致性。
核心实现:
- 模板配置:支持自定义元数据格式模板。
- 参数解析:
formatTemplate:指定元数据格式的模板字符串。metadataKey:指定存储格式化后元数据的键。
使用示例:
ContentFormatTransformer transformer = new ContentFormatTransformer(
"{ \\\\"title\\\\": \\\\"%s\\\\", \\\\"author\\\\": \\\\"%s\\\\" }",
"formatted_metadata"
);
List<Document> transformedDocs = transformer.apply(documents);
高级技巧:
- 统一格式:在多源数据整合时,统一元数据格式以便后续检索和分析。
- 嵌套结构支持:通过复杂模板支持嵌套元数据结构。
效果:
- 提升数据一致性:确保所有文档的元数据格式统一。
- 便于检索:格式化的元数据更容易被检索系统使用。
1.1.3 SummaryMetadataEnricher:摘要生成
功能描述
SummaryMetadataEnricher 利用 AI 模型为文档生成摘要,并将其存储为元数据。
核心实现:
- 摘要模板:支持自定义摘要生成模板。
- 参数解析:
chatModel:用于生成摘要的 AI 模型。summaryTypes:指定生成摘要的类型(如当前文档摘要、前文档摘要、后文档摘要)。summaryTemplate:自定义摘要生成模板。
使用示例:
SummaryMetadataEnricher enricher = new SummaryMetadataEnricher(
chatModel,
List.of(SummaryType.CURRENT, SummaryType.NEXT),
"简洁风格摘要模板"
);
List<Document> enrichedDocs = enricher.apply(documents);
高级技巧:
- 上下文感知摘要:结合前后文档内容生成上下文感知的摘要。
- 多风格支持:通过模板生成不同风格的摘要(如专业风格、通俗风格)。
效果:
- 快速定位核心内容:摘要信息帮助用户快速理解文档主题。
- 提升检索效率:摘要作为元数据可加速文档检索。
1.1.4 KeywordMetadataEnricher:关键词提取
功能描述
KeywordMetadataEnricher 从文档内容中提取关键词,并将其添加到元数据中。
核心实现:
- 关键词数量:支持指定提取的关键词数量。
- 参数解析:
chatModel:用于提取关键词的 AI 模型。keywordCount:指定提取的关键词数量。
使用示例:
KeywordMetadataEnricher enricher = new KeywordMetadataEnricher(chatModel, 5);
List<Document> enrichedDocs = enricher.apply(documents);
高级技巧:
- 自定义关键词:通过提示词模板自定义关键词提取逻辑。
- 多语言支持:结合翻译模型提取多语言关键词。
效果:
- 提升文档可检索性:关键词作为元数据可提高文档检索精度。
- 支持文档分类:关键词可用于文档的自动分类和标签生成。
1.2 高级功能与组合使用
1.2.1 组合多个转换器
通过 ChainingDocumentTransformer,可以将多个 DocumentTransformer 实现类组合在一起,形成强大的转换流水线。
使用示例:
DocumentTransformer transformerPipeline = new ChainingDocumentTransformer(
new ContentFormatTransformer(),
new TokenTextSplitter(500, 200, true),
new SummaryMetadataEnricher(chatModel, 3)
);
List<Document> transformedDocs = transformerPipeline.apply(documents);
效果:
- 流水线处理:文档依次经过格式化、分块和摘要生成,最终输出标准化的文档集合。
- 灵活性:支持按需组合不同的转换器,适应多样化需求。
1.2.2 并行处理
利用 ParallelDocumentTransformer,可以加速大规模文档转换任务。
使用示例:
DocumentTransformer parallelTransformer = new ParallelDocumentTransformer(
new TokenTextSplitter(500, 200, true),
4 // 线程数量
);
List<Document> transformedDocs = parallelTransformer.apply(documents);
效果:
- 性能提升:多线程处理显著减少文档转换时间。
- 资源优化:合理利用 CPU 资源,提高系统吞吐量。
二、Spring AI 中的 RAG(检索增强生成)
RAG 是 Spring AI 的核心模块之一,通过检索相关文档并结合生成模型,提供精准的回答。以下将详细解析 RAG 的核心组件及其使用方法。
以下类图展示了 ETL 核心接口与实现类的关系架构。

2.1 RAG 的核心组件
2.1.1 QuestionAnswerAdvisor
功能描述
QuestionAnswerAdvisor 是一个开箱即用的 Advisor,用于执行检索增强生成(RAG)。它通过查询向量数据库获取与用户问题相关的文档,并将这些文档作为上下文提供给 AI 模型。
核心参数:
vectorStore:向量数据库实例,用于存储和检索文档。searchRequest:检索配置,包括相似度阈值、返回结果数量等。
使用示例:
QuestionAnswerAdvisor qaAdvisor = QuestionAnswerAdvisor.builder(vectorStore)
.searchRequest(SearchRequest.builder()
.similarityThreshold(0.8d)
.topK(6)
.build())
.build();
String response = ChatClient.builder(chatModel)
.build()
.prompt()
.advisors(qaAdvisor)
.user("What is the capital of Denmark?")
.call()
.content();
高级技巧:
- 动态过滤器:通过
FILTER_EXPRESSION参数动态更新检索过滤条件。 - 自定义模板:使用
promptTemplate方法自定义上下文与用户查询的合并逻辑。
效果:
- 精准回答:基于检索到的文档生成精准的回答。
- 上下文增强:附加的文档上下文帮助模型生成更准确的内容。
2.1.2 RetrievalAugmentationAdvisor
功能描述
RetrievalAugmentationAdvisor 是一个更灵活的 Advisor,支持构建自定义 RAG 流程。它集成了文档检索和查询增强功能。
核心参数:
documentRetriever:文档检索器,用于从向量数据库检索文档。queryAugmenter:查询增强器,用于处理用户查询并生成增强后的查询。
使用示例:
Advisor advisor = RetrievalAugmentationAdvisor.builder()
.documentRetriever(VectorStoreDocumentRetriever.builder()
.vectorStore(vectorStore)
.similarityThreshold(0.5)
.topK(3)
.build())
.queryAugmenter(ContextualQueryAugmenter.builder()
.allowEmptyContext(true)
.build())
.build();
String response = chatClient.prompt()
.user("机器人有哪些功能?")
.advisors(advisor)
.call()
.content();
高级技巧:
- 多查询扩展:结合 MultiQueryExpander 生成多个查询变体,提高检索召回率。
- 查询重写:使用 RewriteQueryTransformer 优化查询结构,提升检索精度。
效果:
- 自动化流程:无缝集成文档检索和查询处理,简化开发工作。
- 智能回答:基于增强后的查询生成更智能的回答。
2.1.3 ContextualQueryAugmenter
功能描述
ContextualQueryAugmenter 用于增强用户查询,通过附加检索到的文档内容生成更丰富的查询上下文。
核心参数:
allowEmptyContext:是否允许空上下文查询。maxTokens:查询上下文的最大 Token 数量。temperature:控制查询扩展的创造性。
使用示例:
ContextualQueryAugmenter queryAugmenter = ContextualQueryAugmenter.builder()
.allowEmptyContext(true)
.maxTokens(300)
.temperature(0.7)
.build();
高级技巧:
- 上下文感知:结合历史对话生成上下文感知的查询。
- 多轮对话支持:在多轮对话中动态更新查询上下文。
效果:
- 增强上下文:生成的查询包含更丰富的上下文信息,帮助模型生成更准确的回答。
- 对话连贯性:保持多轮对话的连贯性,提升用户体验。
2.1.4 VectorStoreDocumentRetriever
功能描述
VectorStoreDocumentRetriever 用于从向量数据库检索与查询语义相似的文档。
核心参数:
vectorStore:向量数据库实例。similarityThreshold:文档匹配的最低相似度阈值。topK:返回的文档数量。filterExpression:基于元数据的过滤条件。
使用示例:
DocumentRetriever retriever = VectorStoreDocumentRetriever.builder()
.vectorStore(vectorStore)
.similarityThreshold(0.5)
.topK(3)
.filterExpression(new FilterExpressionBuilder()
.eq("type", "tutorial")
.build())
.build();
List<Document> documents = retriever.retrieve(query);
高级技巧:
- 复杂过滤:使用 FilterExpressionBuilder 构建复杂的过滤条件。
- 动态调整:根据查询动态调整相似度阈值和返回结果数量。
效果:
- 精准检索:基于相似度和元数据过滤返回最相关的文档。
- 高效性:快速从大规模文档集合中定位目标文档。
2.2 RAG 的高级技巧与优化策略
2.2.1 多查询扩展与重写
通过结合 MultiQueryExpander 和 RewriteQueryTransformer,可以显著提升检索的召回率和精度。
使用示例:
MultiQueryExpander queryExpander = MultiQueryExpander.builder()
.chatClientBuilder(chatClientBuilder)
.numberOfQueries(3)
.includeOriginal(false)
.build();
List<Query> expandedQueries = queryExpander.expand(new Query("What is AI?"));
RewriteQueryTransformer queryRewriter = RewriteQueryTransformer.builder()
.chatClientBuilder(chatClientBuilder)
.build();
Query rewrittenQuery = queryRewriter.transform(new Query("What is AI?"));
效果:
- 提高召回率:多查询扩展生成多个相关查询,增加检索结果的覆盖面。
- 提升精度:查询重写优化查询结构,使检索结果更精准。
2.2.2 上下文感知查询
在多轮对话中,利用 CompressionQueryTransformer 处理带有上下文的查询,消除歧义并提高回答的准确性。
使用示例:
Query query = Query.builder()
.text("What is the capital of that country?")
.history(
new UserMessage("Which country has the largest population in Europe?"),
new AssistantMessage("The country with the largest population in Europe is Germany.")
)
.build();
QueryTransformer contextTransformer = CompressionQueryTransformer.builder()
.chatClientBuilder(chatClientBuilder)
.build();
Query transformedQuery = contextTransformer.transform(query);
效果:
- 消除歧义:将模糊的查询转换为明确的查询(如 "What is the capital of Germany?")。
- 对话连贯性:保持多轮对话的连贯性,提升用户体验。
2.2.3 文档合并与去重
使用 ConcatenationDocumentJoiner 合并来自多个查询或数据源的文档,并去除重复内容。
使用示例:
DocumentJoiner documentJoiner = new ConcatenationDocumentJoiner();
List<Document> mergedDocuments = documentJoiner.join(documentsForQuery);
效果:
- 统一文档集合:将多个来源的文档合并为一个统一的文档集合。
- 去重:自动去除重复文档,避免冗余信息。
2.2.4 错误处理与边界情况
通过配置 ContextualQueryAugmenter 和合理的异常处理机制,可以优雅地处理文档未找到或相似度过低的情况。
使用示例:
Advisor advisor = RetrievalAugmentationAdvisor.builder()
.queryAugmenter(ContextualQueryAugmenter.builder()
.allowEmptyContext(true)
.build())
.documentRetriever(retriever)
.build();
String response = chatClient.prompt()
.user("What is the capital of Mars?")
.advisors(advisor)
.call()
.content();
效果:
- 友好提示:当未找到相关文档时,返回友好的提示信息。
- 引导用户:引导用户提供更多上下文信息,以生成更准确的回答。
2.3 RAG 的性能优化策略
2.3.1 向量存储优化
选择合适的向量存储方案,并根据数据规模优化存储配置。
使用示例:
VectorStore vectorStore = SimpleVectorStore.builder(embeddingModel)
.build();
优化建议:
- 内存存储:适用于小规模数据集的快速开发和测试。
- 分布式存储:使用 Redis 或 MongoDB 等分布式存储方案,支持大规模数据集。
2.3.2 检索器配置优化
通过合理配置相似度阈值和返回结果数量,优化检索性能。
使用示例:
DocumentRetriever retriever = VectorStoreDocumentRetriever.builder()
.vectorStore(vectorStore)
.similarityThreshold(0.5)
.topK(3)
.build();
优化建议:
- 动态调整阈值:根据查询类型动态调整相似度阈值。
- 限制结果数量:控制返回结果数量,避免过多不相关文档。
2.3.3 缓存机制
对频繁访问的文档启用缓存,减少重复计算和检索开销。
使用示例:
CachingDocumentRetriever cachedRetriever = new CachingDocumentRetriever(retriever, 1000);
优化建议:
- 合理设置缓存大小:根据内存资源和文档访问频率设置缓存大小。
- 缓存失效策略:定期清理过期缓存,确保数据新鲜度。
三、实战案例:构建智能文档检索系统
以下是一个完整的实战案例,展示如何使用 DocumentTransformer 和 RAG 模块构建智能文档检索系统。
3.1 配置类
@Configuration
public class DocumentProcessingConfig {
@Bean
public TikaDocumentReader tikaReader() {
return new TikaDocumentReader("classpath:documents/");
}
@Bean
public DocumentTransformer transformerChain() {
return new ChainingDocumentTransformer(
new ContentFormatTransformer(),
new TokenTextSplitter(500, 200, true)
);
}
@Bean
public VectorStore vectorStore() {
return new SimpleVectorStore(embeddingModel);
}
@Bean
public QuestionAnswerAdvisor qaAdvisor() {
return QuestionAnswerAdvisor.builder(vectorStore)
.searchRequest(SearchRequest.builder()
.similarityThreshold(0.8d)
.topK(6)
.build())
.build();
}
}
3.2 处理流程
@Service
public class DocumentProcessingService {
@Autowired
private TikaDocumentReader reader;
@Autowired
private DocumentTransformer transformer;
@Autowired
private VectorStore vectorStore;
public void process() {
// 读取文档
List<Document> docs = reader.read();
// 转换文档
List<Document> transformedDocs = transformer.apply(docs);
// 写入向量数据库
vectorStore.add(transformedDocs);
}
}
3.3 检索增强
@RestController
public class RetrievalController {
@Autowired
private ChatClient chatClient;
@Autowired
private QuestionAnswerAdvisor qaAdvisor;
@PostMapping("/retrieve")
public String retrieveDocuments(@RequestBody QueryRequest request) {
String answer = chatClient.prompt()
.user(request.getQuery())
.advisors(qaAdvisor)
.call()
.content();
return answer;
}
}
3.4 高级功能集成
多查询扩展与重写结合:
MultiQueryExpander queryExpander = MultiQueryExpander.builder()
.chatClientBuilder(chatClientBuilder)
.numberOfQueries(3)
.includeOriginal(false)
.build();
RewriteQueryTransformer queryRewriter = RewriteQueryTransformer.builder()
.chatClientBuilder(chatClientBuilder)
.build();
List<Query> expandedQueries = queryExpander.expand(new Query("What is AI?"));
Query rewrittenQuery = queryRewriter.transform(new Query("What is AI?"));
上下文感知查询:
Query query = Query.builder()
.text("What is the capital of that country?")
.history(
new UserMessage("Which country has the largest population in Europe?"),
new AssistantMessage("The country with the largest population in Europe is Germany.")
)
.build();
QueryTransformer contextTransformer = CompressionQueryTransformer.builder()
.chatClientBuilder(chatClientBuilder)
.build();
Query transformedQuery = contextTransformer.transform(query);
3.5 完整高级检索
// 1. 初始化向量存储
SimpleVectorStore vectorStore = SimpleVectorStore.builder(embeddingModel)
.build();
// 2. 配置AI助手角色
ChatClient chatClient = builder
.defaultSystem("你是一位专业的室内设计顾问,精通各种装修风格、材料选择和空间布局。请基于提供的参考资料,为用户提供专业、详细且实用的建议。在回答时,请注意:\\\\n" +
"1. 准确理解用户的具体需求\\\\n" +
"2. 结合参考资料中的实际案例\\\\n" +
"3. 提供专业的设计理念和原理解释\\\\n" +
"4. 考虑实用性、美观性和成本效益\\\\n" +
"5. 如有需要,可以提供替代方案")
.build();
// 3. 构建复杂的文档过滤条件
var b = new FilterExpressionBuilder();
var filterExpression = b.and(
b.and(
b.eq("year", "2023"), // 筛选2023年的案例
b.eq("location", "indoor")), // 仅选择室内案例
b.and(
b.eq("type", "interior"), // 类型为室内设计
b.in("room", "living_room", "study", "kitchen") // 指定房间类型
));
// 4. 配置文档检索器
DocumentRetriever retriever = VectorStoreDocumentRetriever.builder()
.vectorStore(vectorStore)
.similarityThreshold(0.5) // 设置相似度阈值
.topK(3) // 返回前3个最相关的文档
.filterExpression(filterExpression.build())
.build();
// 5. 创建上下文感知的查询增强器
Advisor advisor = RetrievalAugmentationAdvisor.builder()
.queryAugmenter(ContextualQueryAugmenter.builder()
.allowEmptyContext(true)
.build())
.documentRetriever(retriever)
.build();
// 6. 执行查询并获取响应
String userQuestion = "根据已经提供的资料,请描述所有相关的场景风格,输出案例编号,尽可能详细地描述其内容。";
String response = chatClient.prompt()
.user(userQuestion)
.advisors(advisor)
.call()
.content();
四、总结
Spring AI 的 DocumentTransformer 和 RAG 模块提供了强大的工具集,帮助开发者构建高效的文档处理和检索系统。通过合理选择和配置这些组件,可以显著提升文档处理效率和检索精度。
- DocumentTransformer:通过多样化的转换功能(如分块、格式化、摘要生成、关键词提取)确保数据以最优格式进入后续流程。
- RAG 模块:通过检索增强生成技术,结合文档检索和生成模型,提供精准的回答。
高级技巧总结:
- 组合使用:通过 ChainingDocumentTransformer 组合多个转换器,形成强大的转换流水线。
- 并行处理:利用 ParallelDocumentTransformer 加速大规模文档转换任务。
- 多查询扩展:结合 MultiQueryExpander 和 RewriteQueryTransformer 提升检索召回率和精度。
- 上下文感知:利用 CompressionQueryTransformer 处理带有上下文的查询,消除歧义并提高回答的准确性。
- 文档合并:使用 ConcatenationDocumentJoiner 合并来自多个查询或数据源的文档,并去除重复内容。
通过深入理解和灵活运用这些组件,开发者可以构建高效、智能的文档处理和检索系统,满足复杂业务场景的需求。
欢迎查看文章:Spring AI 中的 DocumentTransformer 与 RAG 深度解析 | Honesty Blog
更多推荐




所有评论(0)