模块化RAG
Spring AI其实也提供了Modular RAG的支持,他的核心组件就是RetrievalAugmentationAdvisor
RetrievalAugmentationAdvisor 封装了完整的 RAG 流程,包括:
- 查询预处理(查询重写、查询扩展等)
- 文档检索(从向量数据库做检索)
- 上下文后处理(如文档合并等)
- 提示增强(将检索结果与用户问题合并)
RetrievalAugmentationAdvisor也是一个Advisor,他的用法和其他Advisor一样。
包含以下组件:
DocumentRetriever
DocumentRetriever作用是从外部知识源(如向量数据库、全文搜索引擎等)中根据用户查询语义检索出最相关的文档片段(chunks),为大语言模型(LLM)提供上下文支持,从而提升回答的准确性与事实性。
他的主要实现是VectorStoreDocumentRetriever,基于向量相似度从 VectorStore 中检索文档
QueryTransformer
问题改写增强转换组件,spring ai 默认有三种实现
- CompressionQueryTransformer:问题压缩富化
- RewriteQueryTransformer:问题改写
- TranslationQueryTransformer: 问题翻译
QueryExpander
多元化查询 ,生成多个问题,默认实现 MultiQueryExpander
QueryAugmenter
QueryAugmenter 的作用是在检索完成后、模型生成回答之前,对原始查询进行"上下文增强"。它会根据当前对话内容、历史记录,为查询构建新的提示词,使模型在生成最终回答时理解更充分
与上面介绍的 QueryTransformer 不同,QueryTransformer是作用于检索前,QueryAugmenter 更专注于在生成前增强上下文,确保回答更加准确
DocumentJoiner
DocumentJoiner 是 RAG 流程中的"文档合并器"。当检索到多个文本块的时候,它负责将这些检索返回的文本块简单拼接成一个统一的文档列表,并做基本的去重与按相似度分数排序,最终输出供大模型生成回答的上下文内容
java
@RestController
@RequestMapping("/rag/modular")
public class ModularRagController implements InitializingBean {
@Autowired
private DashScopeChatModel dashScopeChatModel;
@Autowired
private VectorStore vectorStore;
private ChatClient chatClient;
@GetMapping("retriever")
public String retriever(String question) {
// DocumentRetriever 文档检索器,用于从向量存储中检索最相关的文档
DocumentRetriever retriever = VectorStoreDocumentRetriever.builder()
.vectorStore(vectorStore)
.topK(5)
.similarityThreshold(0.8)
.build();
//当用户有多轮对话时,把当前问题"压缩成一个完整且独立的查询",避免丢失上下文。类比的话,其实这就是我们前面问题重写的富化功能,也就是说将历史对话,以及用户当前问题,进行总结输出一个丰富完整的、补充好代词主语的新Query
ChatClient.Builder builder = ChatClient.builder(dashScopeChatModel);
QueryTransformer queryTransformer = CompressionQueryTransformer.builder().chatClientBuilder(builder).build();
//这个其实就是把用户原始问题"改写成更利于检索的关键词问法"。可能会去除掉一些冗余的表达、口语化的连接词、介词等等,使得问题更加具体。但是他是没有上下文关联的,也就是说对于多轮会话,他无法替换一些代词
QueryTransformer rewriteQueryTransformer = RewriteQueryTransformer.builder()
.chatClientBuilder(builder)
.build();
// 翻译问题
QueryTransformer translationQueryTransformer = TranslationQueryTransformer.builder()
.chatClientBuilder(builder)
.build();
// 多元化查询 ,生成多个问题
QueryExpander queryExpander = MultiQueryExpander.builder()
.chatClientBuilder(builder)
.numberOfQueries(2)
.includeOriginal(true)
.build();
//QueryAugmenter 的作用是在检索完成后、模型生成回答之前,对原始查询进行"上下文增强"。它会根据当前对话内容、历史记录,为查询构建新的提示词,使模型在生成最终回答时理解更充分。
//
//与上面介绍的 QueryTransformer 不同,QueryTransformer是作用于检索前,QueryAugmenter 更专注于在生成前增强上下文,确保回答更加准确
QueryAugmenter queryAugmenter = ContextualQueryAugmenter.builder()
.allowEmptyContext(true)
.build();
//DocumentJoiner 是 RAG 流程中的"文档合并器"。当检索到多个文本块的时候,它负责将这些检索返回的文本块简单拼接成一个统一的文档列表,并做基本的去重与按相似度分数排序,最终输出供大模型生成回答的上下文内容
DocumentJoiner documentJoiner = new ConcatenationDocumentJoiner();
RetrievalAugmentationAdvisor advisor = RetrievalAugmentationAdvisor.builder()
.documentRetriever(retriever)
.queryTransformers(List.of(queryTransformer, rewriteQueryTransformer, translationQueryTransformer))
.queryAugmenter(queryAugmenter)
.queryExpander(queryExpander)
.documentJoiner(documentJoiner)
.build();
return chatClient.prompt(question).advisors(advisor).call().content();
}
@Override
public void afterPropertiesSet() throws Exception {
chatClient = ChatClient.builder(dashScopeChatModel).defaultAdvisors(new SimpleLoggerAdvisor()).build()
}
}