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 实现,合并逻辑如下:

  1. 将所有子查询、所有数据源的文档扁平化。

  2. Document.id 去重(保留首次出现)。

  3. 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.* 函数式接口(FunctionBiFunction),带来以下好处:

  • 可直接使用 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(如 MessageChatMemoryAdvisorQuestionAnswerAdvisor)链式组合。

  • 通过 order 属性控制执行优先级。

  • 利用 Reactor Scheduler 支持响应式异步处理。


7. 总结

spring-ai-rag 模块以 Modular RAG Architecture 为指导,将检索增强生成流程解耦为七个清晰的阶段(查询构造 → 转换 → 扩展 → 检索 → 合并 → 后处理 → 增强),并通过 RetrievalAugmentationAdvisor 提供统一的编排能力。其接口设计简洁、扩展点丰富、与 Spring AI 的 Advisor 机制深度融合,为开发者构建生产级 RAG 应用提供了坚实、灵活的基础设施。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐