文章目录
-
- [一、进阶 RAG 配置:RetrievalAugmentationAdvisor](#一、进阶 RAG 配置:RetrievalAugmentationAdvisor)
-
- [1. 查询空时扩展策略(Query Augmenter)](#1. 查询空时扩展策略(Query Augmenter))
- [2. 查询检索器与提示词重写(Query Transformers)](#2. 查询检索器与提示词重写(Query Transformers))
- [3. 后置处理器(Document Post Processors)](#3. 后置处理器(Document Post Processors))
- [4. 完整复杂流水线示例](#4. 完整复杂流水线示例)
- 二、提升检索精度------重排序(Rerank)
-
- 为什么需要重排序?
- 重排序方案(二阶段架构)
- [代码示例(使用 DashScopeRerankModel)](#代码示例(使用 DashScopeRerankModel))
- 重排序的核心价值
- [系列总结:Spring AI RAG 实战要点回顾](#系列总结:Spring AI RAG 实战要点回顾)
本文整理自公众号「攻城狮学习营」原创文章《SpringAI快速入门(9) RAG 实战(三):检索增强配置与重排序实战》(原文链接),聚焦进阶 RAG 配置与重排序(Rerank)实战。

本文是「Spring AI 向量检索与重排序全解析」系列的第三篇。在第一篇中我们了解了 RAG 基础概念和快速入门,在第二篇中深入了 ETL 全流程。本篇将聚焦于进阶的 RAG 配置------使用
RetrievalAugmentationAdvisor实现精细化控制,并引入重排序(Rerank)技术来显著提升检索结果的排序质量。
一、进阶 RAG 配置:RetrievalAugmentationAdvisor
RetrievalAugmentationAdvisor 是 Spring AI 提供的更强大、更灵活的检索增强顾问,它允许开发者对 RAG 流程的各个环节进行精细化控制。相比于前面介绍的 QuestionAnswerAdvisor,它支持查询改写、空结果处理、文档后处理等高级功能。
下面逐一介绍其核心配置项,并给出一个完整的复杂流水线示例。
1. 查询空时扩展策略(Query Augmenter)
当向量检索返回的结果为空(即没有找到相似文档)时,可以通过 queryAugmenter 配置自定义的降级策略,避免将空上下文发送给模型导致错误回答。
java
.queryAugmenter(ContextualQueryAugmenter.builder()
.allowEmptyContext(false) // 不允许空上下文
.emptyContextPromptTemplate(PromptTemplate.builder()
.template("用户查询位于知识库之外。礼貌地告知用户您无法回答")
.build())
.build())
allowEmptyContext(false):当检索结果为空时,不将空上下文传给模型,而是使用自定义提示模板。emptyContextPromptTemplate:定义在无检索结果时,向模型发送的提示内容,可引导模型礼貌地拒绝回答。
2. 查询检索器与提示词重写(Query Transformers)
用户原始查询可能存在表述模糊、语义不完整、关键词缺失等问题。通过 queryTransformers 可以对查询进行改写,优化检索效果。Spring AI 提供了多种内置转换器:
(1)检索提示词重写(RewriteQueryTransformer)
使用大模型将用户查询改写为更适合向量检索的表述,提升召回精度。
java
.queryTransformers(RewriteQueryTransformer.builder()
.chatClientBuilder(ChatClient.builder(dashScopeChatModel))
.targetSearchSystem("航空票务助手") // 目标检索系统的名称,用于指导改写
.build())
(2)翻译重写(TranslationQueryTransformer)
如果用户使用非目标语言提问,可先翻译成系统支持的语言,再进行检索。
java
.queryTransformers(TranslationQueryTransformer.builder()
.chatClientBuilder(ChatClient.builder(dashScopeChatModel))
.targetLanguage("中文") // 将用户查询翻译为中文
.build())
多个转换器可以组合使用,按顺序执行。
3. 后置处理器(Document Post Processors)
检索到的文档列表在返回给模型之前,可以进行额外的处理,例如过滤、排序、截断、日志监控等。通过 documentPostProcessors 添加自定义处理逻辑。
java
.documentPostProcessors((query, documents) -> {
System.out.println("Original query: " + query.text());
System.out.println("Retrieved documents: " + documents.size());
// 可在此对 documents 进行过滤、重排等操作
return documents;
})
该处理器接收当前查询和检索到的文档列表,并返回处理后的文档列表(可修改)。
4. 完整复杂流水线示例
下面的示例综合了上述所有配置,并结合 SimpleLoggerAdvisor 打印日志,演示了如何构建一个完整的 RAG 流水线:
java
@Test
public void testRag3(@Autowired VectorStore vectorStore,
@Autowired DashScopeChatModel dashScopeChatModel) {
ChatClient chatClient = ChatClient.builder(dashScopeChatModel)
.defaultAdvisors(SimpleLoggerAdvisor.builder().build())
.build();
// 构建 RetrievalAugmentationAdvisor
Advisor retrievalAugmentationAdvisor = RetrievalAugmentationAdvisor.builder()
// 1. 配置文档检索器(相当于 QuestionAnswerAdvisor 的检索部分)
.documentRetriever(VectorStoreDocumentRetriever.builder()
.similarityThreshold(0.50)
.vectorStore(vectorStore)
.build())
// 2. 检索为空时的扩展策略(可选,此处注释掉)
/*.queryAugmenter(ContextualQueryAugmenter.builder()
.allowEmptyContext(false)
.emptyContextPromptTemplate(PromptTemplate.builder()
.template("用户查询位于知识库之外。礼貌地告知用户您无法回答")
.build())
.build())*/
// 3. 查询改写(可选,此处注释掉)
/*.queryTransformers(RewriteQueryTransformer.builder()
.chatClientBuilder(ChatClient.builder(dashScopeChatModel))
.targetSearchSystem("航空票务助手")
.build())*/
// 4. 检索后文档监控与操作(可选)
.documentPostProcessors((query, documents) -> {
System.out.println("Original query: " + query.text());
System.out.println("Retrieved documents: " + documents.size());
return documents;
})
.build();
String answer = chatClient.prompt()
.advisors(retrievalAugmentationAdvisor)
.user("退一张票大概要多少费用?希望别扣太多啊")
.call()
.content();
System.out.println(answer);
}
// 配置类(用于提供 VectorStore Bean)
@TestConfiguration
static class TestConfig {
@Bean
public VectorStore vectorStore(DashScopeEmbeddingModel embeddingModel) {
return SimpleVectorStore.builder(embeddingModel).build();
}
}
代码说明:
documentRetriever:指定了向量存储和相似度阈值,是检索的核心。queryAugmenter:可配置空结果时的降级提示,本例中注释掉以便演示其他功能。queryTransformers:可配置一个或多个查询改写器,本例注释掉,实际可开启。documentPostProcessors:添加了一个简单的日志处理器,打印查询内容和召回文档数量,便于调试。- 最终通过
chatClient.prompt().advisors(retrievalAugmentationAdvisor).user(...).call().content()执行完整流程。
该配置方式比 QuestionAnswerAdvisor 更加灵活,适合复杂业务场景下的 RAG 定制。
二、提升检索精度------重排序(Rerank)
为什么需要重排序?
在实际应用中,单纯依赖向量相似度排序存在以下问题:
- 语义相似度局限:向量相似不等于内容绝对相关。两个文档可能在向量空间中距离很近,但实际内容却并不匹配用户意图。
- 排序质量不佳:初始检索排序非最优,尤其当向量模型性能较差时,排序结果往往不够理想。
- 上下文理解缺失:向量检索缺乏对查询和文档完整上下文的深度理解,无法精确判断文档与查询之间的真实相关性。

重排序方案(二阶段架构)
推荐采用"粗排 + 精排"的二阶段架构:
- 粗排(第一阶段):向量检索快速召回 Top-K(如 200)候选文档,保证召回率。
- 精排(第二阶段) :使用专用重排序模型(如
gte-rerank-hybrid)对候选文档重新评分,并按相关性降序输出,可设置分数阈值过滤低质量文档。

代码示例(使用 DashScopeRerankModel)
在 Spring AI 中,重排序通过 RetrievalRerankAdvisor 实现。以下是一个完整的端到端示例:
测试配置(使用 Ollama 较低性能向量模型,凸显 rerank 效果):
java
@TestConfiguration
static class TestConfig {
@Bean
public VectorStore vectorStore(OllamaEmbeddingModel embeddingModel) {
return SimpleVectorStore.builder(embeddingModel).build();
}
}
重排序测试:
java
@SpringBootTest
public class RerankTest {
@BeforeEach
public void init(@Autowired VectorStore vectorStore,
@Value("classpath:rag/terms-of-service.txt") Resource resource) {
TextReader reader = new TextReader(resource);
reader.getCustomMetadata().put("filename", resource.getFilename());
List<Document> docs = reader.read();
ChineseTokenTextSplitter splitter = new ChineseTokenTextSplitter(80, 10, 5, 10000, true);
List<Document> chunks = splitter.apply(docs);
vectorStore.add(chunks);
}
@Test
public void testRerank(@Autowired DashScopeChatModel chatModel,
@Autowired VectorStore vectorStore,
@Autowired DashScopeRerankModel rerankModel) {
ChatClient chatClient = ChatClient.builder(chatModel).build();
// 粗排 TopK=200,精排默认 TopN=5
RetrievalRerankAdvisor advisor = new RetrievalRerankAdvisor(
vectorStore, rerankModel,
SearchRequest.builder().topK(200).build()
);
String content = chatClient.prompt()
.user("退票费用")
.advisors(advisor)
.call()
.content();
System.out.println(content);
}
}
效果对比:
- 重排前,排名第一的文档与"退费"无关(如预订航班说明)。
- 重排后,排名第一的文档直接包含取消预订费用信息(经济舱 75 美元等)。

重排序的核心价值
重排序技术为 RAG 系统带来了以下关键收益:
- 弥补向量模型不足:即使使用较低性能的向量模型(如 Ollama 的 nomic-embed-text),通过重排序仍能获得高质量的检索结果。
- 提升 Top-K 精确率:粗排阶段可以设置较大的 TopK(如 200),保证召回率;精排阶段从这 200 条中选出最相关的 Top-N(默认 5),保证精确率。
- 降低 Token 消耗:通过精排筛选出最相关的文档,减少发送给大模型的无关上下文,降低 Token 消耗和费用。
- 灵活可配置:可以根据业务场景独立调整粗排和精排的参数,实现检索质量与性能的最佳平衡。
系列总结:Spring AI RAG 实战要点回顾
- 向量模型 决定语义表征质量,建议选择
text-embedding-v4等高性能模型 - 分块策略需结合业务场景,可尝试语义分块或递归分块,并配合重叠(overlap)机制
- ETL 流程是 RAG 的数据底座,涵盖读取、分块、格式转换、元数据增强、向量化存储全链路
- RetrievalAugmentationAdvisor 提供比 QuestionAnswerAdvisor 更灵活的精细化控制
- 重排序能显著改善检索排序,尤其当向量模型较弱时效果明显,采用"粗排+精排"二阶段架构
- 始终以**"业务召回效果"**为最终标准,而非追求固定阈值