SpringAI框架中的RAG模块详解及应用示例

SpringAI框架中的RAG模块详解及应用示例

RAG(Retrieval-Augmented Generation)可以通过检索知识库,克服大模型训练完成后参数冻结的局限性,携带知识让大模型根据知识进行回答。SpringAI框架提供了模块化的API来支持RAG,主要包括QuestionAnswerAdvisorRetrievalArgumentAdvisor

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流程

检索前预处理
  1. 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();
  1. RewriteQueryTransformer:使用大语言模型重写用户输入,适合语义模糊或冗长的查询。
QueryTransformer queryTransformer = RewriteQueryTransformer.builder()
    .chatClientBuilder(chatClientBuilder)
    .build();
  1. TranslationQueryTransformer:翻译用户查询为目标语言(通常为嵌入模型支持的语言)。
QueryTransformer transformer = TranslationQueryTransformer.builder()
    .chatClientBuilder(chatClientBuilder)
    .targetLanguage("english")
    .build();
  1. 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模块的详细介绍及使用示例,涵盖从简单到复杂的多种应用场景,帮助开发者灵活构建基于知识库的问答系统。

torch()是一个PyTorch函数,用于找出张量中最大值所在的索引位置。它可以用于任意维度的输入张量。torch.argmax()的输出结果是一个LongTensor类型的张量,表示最大值的索引位置。 下面是使用torch.argmax()函数的示例代码: ```python import torch x = torch.randn(3, 4) y = torch.argmax(x) ``` 在这个例子中,x是一个形状为(3, 4)的张量,torch.argmax(x)会返回x中最大元素的索引值。 如果你想在指定的维度上求最大值的索引,可以使用torch.argmax(input, dim)函数。dim参数指定了在哪个维度上进行最大值索引的计算。例如,如果你希望在第1维度上求最大值的索引,可以使用: ```python import torch x = torch.randn(3, 4) y = torch.argmax(x, dim=1) ``` 这样会返回一个形状为(3,)的张量,其中每个元素表示对应行的最大值索引。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Pytorch中torch.argmax()函数解析](https://blog.youkuaiyun.com/flyingluohaipeng/article/details/125099214)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [【Pytorch】torch.argmax 函数详解](https://blog.youkuaiyun.com/weixin_44211968/article/details/128216020)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值