Spring AI RAG 模块源码架构分析
1. 模块概述
spring-ai-rag 模块实现了基于 Modular RAG Architecture(模块化检索增强生成架构)的 RAG 流程编排能力。该架构参考了多篇学术论文(arXiv:2407.21059、arXiv:2312.10997、arXiv:2410.20878),将传统 RAG 流程拆解为多个独立、可插拔的组件,允许开发者按需组合、替换和扩展各个阶段的行为。
模块的核心设计目标:
-
模块化:每个 RAG 阶段(查询预处理、检索、后处理、生成增强)都有明确定义的接口。
-
可组合:通过
RetrievalAugmentationAdvisor统一编排各组件的执行顺序与依赖关系。 -
可扩展:所有阶段均基于函数式接口定义,开发者可轻松提供自定义实现。
-
异步友好:文档检索阶段默认使用线程池并发执行,提升多查询扩展场景下的性能。
2. 包结构与核心接口
模块源码位于 org.springframework.ai.rag 及其子包下,按 RAG 流程阶段分层组织:
org.springframework.ai.rag ├── Query.java # RAG 查询对象 ├── advisor/ │ └── RetrievalAugmentationAdvisor.java # RAG 流程编排器(核心入口) ├── preretrieval/ # 检索前阶段:查询预处理 │ └── query/ │ ├── transformation/ # 查询转换 │ │ ├── QueryTransformer.java # 接口:Query → Query │ │ ├── RewriteQueryTransformer.java │ │ ├── TranslationQueryTransformer.java │ │ └── CompressionQueryTransformer.java │ └── expansion/ # 查询扩展 │ ├── QueryExpander.java # 接口:Query → List<Query> │ └── MultiQueryExpander.java ├── retrieval/ # 检索阶段 │ ├── search/ │ │ ├── DocumentRetriever.java # 接口:Query → List<Document> │ │ └── VectorStoreDocumentRetriever.java │ └── join/ │ ├── DocumentJoiner.java # 接口:合并多源文档 │ └── ConcatenationDocumentJoiner.java ├── postretrieval/ # 检索后阶段 │ └── document/ │ └── DocumentPostProcessor.java # 接口:文档后处理 ├── generation/ # 生成阶段:查询增强 │ └── augmentation/ │ ├── QueryAugmenter.java # 接口:Query + Documents → Query │ └── ContextualQueryAugmenter.java └── util/ └── PromptAssert.java # Prompt 模板校验工具
3. 核心接口详解
3.1 Query — RAG 查询对象
源码位置:org.springframework.ai.rag.Query
Query 是一个不可变的 Java Record,封装了 RAG 流程中传递的查询信息:
| 字段 | 类型 | 说明 |
|---|---|---|
text |
String |
查询文本(核心字段,不可为空) |
history |
List<Message> |
对话历史消息列表 |
context |
Map<String, Object> |
扩展上下文,供组件间传递额外数据 |
提供 builder() 和 mutate() 方法用于构造和派生新实例,保证不可变性的同时支持链式修改。
3.2 QueryTransformer — 查询转换器
源码位置:org.springframework.ai.rag.preretrieval.query.transformation.QueryTransformer
public interface QueryTransformer extends Function<Query, Query> {
Query transform(Query query);
}
职责:在检索前对原始查询进行转换,使其更适合目标检索系统。常见策略包括:
-
重写(Rewrite):去除冗余信息、优化措辞,提升向量检索质量。
-
翻译(Translation):将查询翻译为嵌入模型训练所用的目标语言。
-
压缩(Compression):将多轮对话历史压缩为单一独立查询,消除指代歧义。
3.3 QueryExpander — 查询扩展器
源码位置:org.springframework.ai.rag.preretrieval.query.expansion.QueryExpander
public interface QueryExpander extends Function<Query, List<Query>> {
List<Query> expand(Query query);
}
职责:将单个查询扩展为多个语义变体,从多视角检索文档,扩大召回率。当前提供基于大模型的 MultiQueryExpander 实现。
3.4 DocumentRetriever — 文档检索器
源码位置:org.springframework.ai.rag.retrieval.search.DocumentRetriever
public interface DocumentRetriever extends Function<Query, List<Document>> {
List<Document> retrieve(Query query);
}
职责:从底层数据源(向量库、搜索引擎、数据库、知识图谱等)检索与查询相关的文档。当前内置 VectorStoreDocumentRetriever,支持相似度阈值、Top-K、元数据过滤等参数。
3.5 DocumentJoiner — 文档合并器
源码位置:org.springframework.ai.rag.retrieval.join.DocumentJoiner
public interface DocumentJoiner extends Function<Map<Query, List<List<Document>>>, List<Document>> {
List<Document> join(Map<Query, List<List<Document>>> documentsForQuery);
}
职责:当查询被扩展为多个子查询时,每个子查询可能从多个数据源检索到文档。DocumentJoiner 负责将这些分散的结果合并为统一的文档列表,处理重复、排序等逻辑。
3.6 DocumentPostProcessor — 文档后处理器
源码位置:org.springframework.ai.rag.postretrieval.document.DocumentPostProcessor
public interface DocumentPostProcessor extends BiFunction<Query, List<Document>, List<Document>> {
List<Document> process(Query query, List<Document> documents);
}
职责:对检索后的文档集合进行后处理,解决以下问题:
-
Lost-in-the-middle:调整文档排序,使高相关性文档更靠近 prompt 首尾。
-
上下文长度限制:截断或压缩文档,适配模型上下文窗口。
-
去噪与去重:移除低相关性或冗余内容。
当前模块未提供内置实现,由外部或后续版本补充。
3.7 QueryAugmenter — 查询增强器
源码位置:org.springframework.ai.rag.generation.augmentation.QueryAugmenter
public interface QueryAugmenter extends BiFunction<Query, List<Document>, Query> {
Query augment(Query query, List<Document> documents);
}
职责:将检索到的文档上下文注入到原始查询中,构造最终提交给大模型的增强后查询。ContextualQueryAugmenter 是默认实现,使用 Prompt Template 将文档内容拼接为上下文块。
4. 关键实现类详解
4.1 RetrievalAugmentationAdvisor — RAG 编排核心
源码位置:org.springframework.ai.rag.advisor.RetrievalAugmentationAdvisor
该类实现 BaseAdvisor 接口,是 ChatClient 的 Advisor 机制与 RAG 流程的桥梁。它将 RAG 的完整生命周期嵌入到 ChatClient 的请求前后处理中。
核心字段
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
queryTransformers |
List<QueryTransformer> |
List.of() |
查询转换器链 |
queryExpander |
QueryExpander |
null |
查询扩展器 |
documentRetriever |
DocumentRetriever |
必填 | 文档检索器 |
documentJoiner |
DocumentJoiner |
ConcatenationDocumentJoiner |
文档合并器 |
documentPostProcessors |
List<DocumentPostProcessor> |
List.of() |
文档后处理器链 |
queryAugmenter |
QueryAugmenter |
ContextualQueryAugmenter |
查询增强器 |
taskExecutor |
TaskExecutor |
内置线程池 | 并发检索执行器 |
before(...) 方法执行流程
ChatClientRequest │ ▼ [Step 0] 构造 Query(提取 userMessage.text、instructions、context) │ ▼ [Step 1] QueryTransformer 链式转换 │ for (transformer : queryTransformers) │ query = transformer.apply(query) ▼ [Step 2] QueryExpander 扩展查询 │ expandedQueries = queryExpander.expand(query) 或 [query] ▼ [Step 3] DocumentRetriever 并发检索(每个扩展查询独立执行) │ CompletableFuture.supplyAsync(() -> retriever.retrieve(query), taskExecutor) ▼ [Step 4] DocumentJoiner 合并文档 │ documents = documentJoiner.join(documentsForQuery) ▼ [Step 5] DocumentPostProcessor 后处理 │ for (processor : documentPostProcessors) │ documents = processor.process(originalQuery, documents) ▼ [Step 6] QueryAugmenter 增强查询 │ augmentedQuery = queryAugmenter.augment(originalQuery, documents) ▼ [Step 7] 更新 ChatClientRequest │ - prompt.augmentUserMessage(augmentedQuery.text()) │ - context.put(DOCUMENT_CONTEXT, documents) ▼ ChatClientRequest(增强后)
after(...) 方法
将检索到的文档上下文附加到 ChatResponse 的 metadata 中,键名为 rag_document_context,便于调用方追溯 RAG 所使用的原始文档。
4.2 ContextualQueryAugmenter — 上下文增强实现
源码位置:org.springframework.ai.rag.generation.augmentation.ContextualQueryAugmenter
默认的 QueryAugmenter 实现,将文档内容格式化后嵌入 Prompt Template:
Context information is below.
---------------------
{context}
---------------------
Given the context information and no prior knowledge, answer the query.
Follow these rules:
1. If the answer is not in the context, just say that you don't know.
2. Avoid statements like "Based on the context..." or "The provided information...".
Query: {query}
Answer:
支持自定义:
-
promptTemplate:替换默认提示词模板。 -
emptyContextPromptTemplate:无检索结果时的兜底提示。 -
allowEmptyContext:是否允许空上下文直接返回原查询。 -
documentFormatter:自定义文档格式化逻辑(默认按换行拼接文档文本)。
4.3 VectorStoreDocumentRetriever — 向量库检索实现
源码位置:org.springframework.ai.rag.retrieval.search.VectorStoreDocumentRetriever
基于 VectorStore 的默认检索实现,支持以下检索参数:
| 参数 | 说明 |
|---|---|
similarityThreshold |
相似度阈值,低于此值的文档被过滤 |
topK |
返回最相关的 K 个文档 |
filterExpression |
元数据过滤表达式(支持静态配置或动态从 Query.context 获取) |
动态过滤特性:通过在 Query.context 中放入键 vector_store_filter_expression(支持字符串或 Filter.Expression 对象),可在每次请求时动态指定过滤条件,适用于多租户、权限隔离等场景。
4.4 ConcatenationDocumentJoiner — 拼接合并实现
源码位置:org.springframework.ai.rag.retrieval.join.ConcatenationDocumentJoiner
默认的 DocumentJoiner 实现,合并逻辑如下:
-
将所有子查询、所有数据源的文档扁平化。
-
按
Document.id去重(保留首次出现)。 -
按
Document.score降序排序。
该实现简单高效,适用于大多数场景;若需更复杂的排序(如 RRF 倒数排序融合),可自定义 DocumentJoiner。
4.5 查询预处理实现类
RewriteQueryTransformer
使用 LLM 重写查询,去除无关信息,使查询更简洁、适合向量检索。支持自定义 targetSearchSystem(如 "vector store"、"web search")。
TranslationQueryTransformer
使用 LLM 将查询翻译为目标语言(如 "english")。若查询已为目标语言或语言未知,则原样返回。
CompressionQueryTransformer
将对话历史与跟进查询压缩为单一独立查询,适用于多轮对话场景,消除指代和省略歧义。
MultiQueryExpander
使用 LLM 将单个查询扩展为 N 个语义变体,每个变体从不同角度描述同一问题。支持 includeOriginal 控制是否保留原始查询。
5. RAG 完整调用链路
以下以一个典型场景为例,展示从用户输入到大模型响应的完整数据流:
用户提问: "它怎么用?"(多轮对话中的跟进问题)
│
▼
ChatClient.prompt("它怎么用?").call()
│
▼
RetrievalAugmentationAdvisor.before()
│
├─► 构造 Query
│ text="它怎么用?"
│ history=[user: "Spring AI 是什么?", assistant: "..."]
│
├─► CompressionQueryTransformer
│ → 压缩为独立查询: "Spring AI 怎么用?"
│
├─► TranslationQueryTransformer
│ → 翻译为英文: "How to use Spring AI?"
│
├─► MultiQueryExpander (numberOfQueries=3)
│ → 扩展为多个查询变体:
│ 1. "How to use Spring AI?"
│ 2. "Spring AI getting started guide"
│ 3. "Spring AI tutorial and examples"
│
├─► VectorStoreDocumentRetriever (并发执行)
│ → 对每个扩展查询执行 similaritySearch()
│ → 返回各查询对应的 List<Document>
│
├─► ConcatenationDocumentJoiner
│ → 合并、去重、按 score 降序排序
│ → 得到统一文档列表
│
├─► DocumentPostProcessor(若有配置)
│ → 排序调整、截断、压缩等
│
├─► ContextualQueryAugmenter
│ → 将文档内容拼接入 Prompt Template
│ → 生成增强查询文本
│
└─► 更新 ChatClientRequest
→ userMessage 替换为增强后的完整提示
→ context 中保存 rag_document_context
│
▼
ChatModel.call(Prompt) → 大模型生成回复
│
▼
RetrievalAugmentationAdvisor.after()
→ 将 rag_document_context 写入 ChatResponse metadata
│
▼
返回 ChatResponse(包含回复文本与检索文档溯源)
6. 设计亮点与扩展性分析
6.1 函数式接口设计
所有阶段接口均继承自 java.util.function.* 函数式接口(Function、BiFunction),带来以下好处:
-
可直接使用 Lambda 表达式提供轻量级自定义实现。
-
便于与 Spring 的函数式编程风格及 Reactor 等异步框架集成。
-
接口默认方法
apply()委托给业务方法,兼顾可读性与函数式兼容性。
6.2 Builder 模式与默认值
RetrievalAugmentationAdvisor 及所有实现类均采用 Builder 模式,必填项少、配置友好:
-
仅
DocumentRetriever为必填。 -
其余组件均有合理默认值,开发者可渐进式引入高级能力。
6.3 并发检索
Step 3 使用 CompletableFuture.supplyAsync(..., taskExecutor) 并发执行多查询的文档检索,默认线程池配置:
-
核心线程数:4
-
最大线程数:16
-
线程名前缀:
ai-advisor- -
支持上下文传播(
ContextPropagatingTaskDecorator)
6.4 可扩展点总结
| 扩展点 | 实现方式 |
|---|---|
| 自定义查询转换 | 实现 QueryTransformer 接口 |
| 自定义查询扩展 | 实现 QueryExpander 接口 |
| 自定义检索源 | 实现 DocumentRetriever 接口(如 Elasticsearch、Neo4j、Web Search) |
| 自定义合并策略 | 实现 DocumentJoiner 接口(如 RRF、加权融合) |
| 自定义后处理 | 实现 DocumentPostProcessor 接口(如重排序、摘要压缩) |
| 自定义增强方式 | 实现 QueryAugmenter 接口(如多文档引用格式、XML/JSON 结构化注入) |
6.5 与 Spring AI Advisor 机制集成
RetrievalAugmentationAdvisor 作为 ChatClient 的 Advisor,天然享有以下能力:
-
与其他 Advisor(如
MessageChatMemoryAdvisor、QuestionAnswerAdvisor)链式组合。 -
通过
order属性控制执行优先级。 -
利用 Reactor
Scheduler支持响应式异步处理。
7. 总结
spring-ai-rag 模块以 Modular RAG Architecture 为指导,将检索增强生成流程解耦为七个清晰的阶段(查询构造 → 转换 → 扩展 → 检索 → 合并 → 后处理 → 增强),并通过 RetrievalAugmentationAdvisor 提供统一的编排能力。其接口设计简洁、扩展点丰富、与 Spring AI 的 Advisor 机制深度融合,为开发者构建生产级 RAG 应用提供了坚实、灵活的基础设施。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)