SpringAI框架中的RAG模块详解及应用示例
SpringAI框架中的RAG模块详解及应用示例
RAG(Retrieval-Augmented Generation)可以通过检索知识库,克服大模型训练完成后参数冻结的局限性,携带知识让大模型根据知识进行回答。SpringAI框架提供了模块化的API来支持RAG,主要包括QuestionAnswerAdvisor
和RetrievalArgumentAdvisor
。
QuestionAnswerAdvisor
QuestionAnswerAdvisor
主要提供便捷简单的RAG流功能,只需指定一些简单的参数即可。例如,假设数据已加载到vectorStore
中,可以通过以下方法进行RAG知识库检索:
QuestionAnswerAdvisor questionAnswerAdvisor = QuestionAnswerAdvisor.builder(vectorStore).searchRequest(SearchRequest.builder().similarityThreshold(0.5) // 只返回相似度高于0.5的结果.topK(3) // 只返回前三个结果.filterExpression(newFilterExpressionBuilder().eq("a", "b").build()) // 只检索 a==b 的文档.build()).build();ChatClient chatClient = ChatClient.builder(openAiChatModel).defaultOptions(OpenAiChatOptions.builder().model("gpt-3.5-turbo").build()).build();ChatResponse response = chatClient.prompt().advisors(questionAnswerAdvisor).user(u -> u.text("你好")).call().chatResponse();
如果构造advisor时未指定过滤条件,构建请求时也能动态添加:
chatClient.prompt().user(u -> u.text("hello")).advisors(a -> a.param(QuestionAnswerAdvisor.FILTER_EXPRESSION, "a==b")).call().chatResponse();
这里的lambda表达式中的a
是一个AdvisorContext.Builder
实例,param()
用于向AdvisorContext
中添加参数,这些参数在advisor链中共享,advisor会自动调用相应方法完成知识库检索和拼接。
RetrievalArgumentAdvisor
RetrievalArgumentAdvisor
提供了更丰富的功能,允许程序员定义整个RAG过程的操作,包括检索前预处理、检索、检索后处理以及生成。
简单RAG实现示例
Advisor retrievalAugmentationAdvisor = RetrievalAugmentationAdvisor.builder().documentRetriever(VectorStoreDocumentRetriever.builder().similarityThreshold(0.50).vectorStore(vectorStore).build()).build();String answer = chatClient.prompt().advisors(retrievalAugmentationAdvisor).user(question).call().content();
高级RAG流程
检索前预处理
- CompressionQueryTransformer:对用户提问进行压缩,适用于对话历史较长且当前问题基于上下文的场景。示例:
Query query = Query.builder().text("And what is its second largest city?").history(newUserMessage("What is the capital of Denmark?"),newAssistantMessage("Copenhagen is the capital of Denmark.")).build();QueryTransformer transformer = CompressionQueryTransformer.builder().chatClientBuilder(chatClientBuilder).build();Query transformedQuery = transformer.transform(query);
也可由advisor自动完成:
CompressionQueryTransformer compressionQueryTransformer = CompressionQueryTransformer.builder().chatClientBuilder(ChatClient.builder(openAiChatModel)).build();RetrievalAugmentationAdvisor retrievalAugmentationAdvisor = RetrievalAugmentationAdvisor.builder().documentRetriever(VectorStoreDocumentRetriever.builder().build()).queryTransformers(compressionQueryTransformer).build();ChatClient.builder(openAiChatModel).build().prompt().user(u -> u.text("中国第二大的城市是哪里")).messages(newUserMessage("中国首都城市是哪里")).messages(newAssistantMessage("北京")).advisors(retrievalAugmentationAdvisor).call().chatResponse();
- RewriteQueryTransformer:使用大语言模型重写用户输入,适合语义模糊或冗长的查询。
QueryTransformer queryTransformer = RewriteQueryTransformer.builder().chatClientBuilder(chatClientBuilder).build();
- TranslationQueryTransformer:翻译用户查询为目标语言(通常为嵌入模型支持的语言)。
QueryTransformer transformer = TranslationQueryTransformer.builder().chatClientBuilder(chatClientBuilder).targetLanguage("english").build();
- MultiQueryExpander:多查询扩展器,将原始查询扩展为多个不同形式的查询以获取更多相关结果。
MultiQueryExpander expander = MultiQueryExpander.builder().chatClientBuilder(chatClientBuilder).numberOfQueries(3) // 生成三个查询.includeOriginal(false) // 不包含原始查询.build();
检索
负责从数据库中检索最相关文档。
VectorStoreDocumentRetriever vectorStoreDocumentRetriever = VectorStoreDocumentRetriever.builder().vectorStore(vectorStore).topK(4) // 返回最相关的4个.filterExpression(newFilterExpressionBuilder().eq("a", "b").build()) // 过滤条件:a==b.similarityThreshold(0.4) // 只返回相关度大于0.4的文档.build();List<Document> documents = vectorStoreDocumentRetriever.retrieve(newQuery("What is the main character of the story?"));
同样可以交由advisor自动完成并最终展示结果。
检索后处理
解决文档内容过多导致的信息丢失、模型上下文长度限制、内容噪声或重复问题。常见操作包括根据相关性重新排序文档、删除无关或重复文档、压缩文档内容以减少干扰。
生成
根据用户输入和最终检索到的文档生成回答。
ContextualQueryAugmenter
将检索到的相关内容拼接到用户提问中,示例:
ContextualQueryAugmenter contextualQueryAugmenter = ContextualQueryAugmenter.builder().allowEmptyContext(false) // 是否允许检索提供空内容.build();
- 当
.allowEmptyContext(false)
时,若无检索内容,模型通常不会回答或回答不知道。 - 当
.allowEmptyContext(true)
时,即使检索内容为空,也会尝试回答。
ContextualQueryAugmenter
主要做以下工作:
- 检查检索结果是否为空
- 非空时,拼接检索结果字符串并注入提示词模板变量(如
{{retrievedDocs}}
) - 为空且
.allowEmptyContext(false)
时,设置空变量并指示模型“不要根据已有知识回答” - 为空且
.allowEmptyContext(true)
时,放行不插入上下文内容
以上即为SpringAI框架中RAG模块的详细介绍及使用示例,涵盖从简单到复杂的多种应用场景,帮助开发者灵活构建基于知识库的问答系统。