Retrieval Augmented Generation
Retrieval Augmented Generation (RAG) 是一种有用的技术,用于克服大型语言模型的局限性,这些模型在处理长文本内容、事实准确性和上下文感知方面存在困难。
Spring AI 通过提供模块化架构支持 RAG,允许您自己构建自定义 RAG 流程,或使用 Advisor API 使用开箱即用的 RAG 流程。
注意:在 概念 部分了解更多关于 Retrieval Augmented Generation 的信息。
Advisors
Spring AI 使用 Advisor API 为常见的 RAG 流程提供开箱即用的支持。
要使用 QuestionAnswerAdvisor 或 VectorStoreChatMemoryAdvisor,您需要将 spring-ai-advisors-vector-store 依赖项添加到您的项目:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-advisors-vector-store</artifactId>
</dependency>
QuestionAnswerAdvisor
向量数据库存储 AI 模型不知道的数据。当用户问题发送到 AI 模型时,QuestionAnswerAdvisor 会查询向量数据库以查找与用户问题相关的文档。
向量数据库的响应会附加到用户文本,为 AI 模型提供上下文以生成响应。
假设您已经将数据加载到 VectorStore 中,您可以通过向 ChatClient 提供 QuestionAnswerAdvisor 的实例来执行 Retrieval Augmented Generation (RAG)。
ChatResponse response = ChatClient.builder(chatModel)
.build().prompt()
.advisors(QuestionAnswerAdvisor.builder(vectorStore).build())
.user(userText)
.call()
.chatResponse();
在此示例中,QuestionAnswerAdvisor 将对 Vector Database 中的所有文档执行相似性搜索。要限制搜索的文档类型,SearchRequest 接受一个类似 SQL 的过滤表达式,该表达式可在所有 VectorStores 之间移植。
此过滤表达式可以在创建 QuestionAnswerAdvisor 时配置,因此将始终应用于所有 ChatClient 请求,或者可以在运行时按请求提供。
以下是如何创建 QuestionAnswerAdvisor 的实例,其中阈值为 0.8 并返回前 6 个结果。
var qaAdvisor = QuestionAnswerAdvisor.builder(vectorStore)
.searchRequest(SearchRequest.builder().similarityThreshold(0.8d).topK(6).build())
.build();
动态过滤表达式
使用 FILTER_EXPRESSION advisor 上下文参数在运行时更新 SearchRequest 过滤表达式:
ChatClient chatClient = ChatClient.builder(chatModel)
.defaultAdvisors(QuestionAnswerAdvisor.builder(vectorStore)
.searchRequest(SearchRequest.builder().build())
.build())
.build();
// Update filter expression at runtime
String content = this.chatClient.prompt()
.user("Please answer my question XYZ")
.advisors(a -> a.param(QuestionAnswerAdvisor.FILTER_EXPRESSION, "type == 'Spring'"))
.call()
.content();
FILTER_EXPRESSION 参数允许您根据提供的表达式动态过滤搜索结果。
自定义模板
QuestionAnswerAdvisor 使用默认模板来增强用户问题与检索到的文档。您可以通过 .promptTemplate() builder 方法提供自己的 PromptTemplate 对象来自定义此行为。
注意:这里提供的 PromptTemplate 自定义 advisor 如何将检索到的上下文与用户查询合并。这与在 ChatClient 本身上配置 TemplateRenderer(使用 .templateRenderer())不同,后者影响 advisor 运行之前初始用户/系统提示内容的渲染。有关客户端级模板渲染的更多详细信息,请参阅 ChatClient Prompt Templates。
自定义 PromptTemplate 可以使用任何 TemplateRenderer 实现(默认情况下,它使用基于 https://www.stringtemplate.org/[StringTemplate] 引擎的 StPromptTemplate)。重要要求是模板必须包含以下两个占位符:
- 一个
query占位符来接收用户问题。 - 一个
question_answer_context占位符来接收检索到的上下文。
PromptTemplate customPromptTemplate = PromptTemplate.builder()
.renderer(StTemplateRenderer.builder().startDelimiterToken('<').endDelimiterToken('>').build())
.template("""
<query>
Context information is below.
---------------------
<question_answer_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...".
""")
.build();
String question = "Where does the adventure of Anacletus and Birba take place?";
QuestionAnswerAdvisor qaAdvisor = QuestionAnswerAdvisor.builder(vectorStore)
.promptTemplate(customPromptTemplate)
.build();
String response = ChatClient.builder(chatModel).build()
.prompt(question)
.advisors(qaAdvisor)
.call()
.content();
注意:QuestionAnswerAdvisor.Builder.userTextAdvise() 方法已弃用,建议使用 .promptTemplate() 以获得更灵活的自定义。
RetrievalAugmentationAdvisor
Spring AI 包含一个 RAG 模块库,您可以使用它来构建自己的 RAG 流程。
RetrievalAugmentationAdvisor 是一个 Advisor,为最常见的 RAG 流程提供开箱即用的实现,基于模块化架构。