当前位置: 首页 > news >正文

RAG-Fusion 实战:检索召回率提升新方案

前言

       在此之前,基于LangChain0.3集成Milvu2.5向量数据库构建的智能问答系统,做检索召回率提升的探究,并未知道检索前处理所涉及的方法也是 RAG-Fusion 的实现。又是一次 “先实践,后知觉” 的体会。

什么是 RAG-Fusion

       RAG-Fusion 是一种扩展了传统 RAG 技术的方法,旨在通过结合多查询检索结果融合来提升生成模型的效果。它通过生成多个与原始问题语义相关的查询变体,也可以是同一问题的不同提问方式,还可以是基于原始查询进行扩展等,然后并行地从知识库中检索信息,并将这些检索到的结果进行融合与重排序,从而增强生成答案的准确性和丰富性。

RAG-Fusion 实现

方案一:基于 LangChain 工具类 MultiQueryRetriever

MultiQueryRetriever 介绍

       LangChain 提供的工具类:MultiQueryRetriever。它的实现过程:通过提示词把输入问题,利用大语言模型(LLM)生成多个查询变体,然后根据传入的检索器,对查询变体逐个检索,并将检索结果合并去重后返回。

MultiQueryRetriever 源码默认的 prompt:

# Default prompt
DEFAULT_QUERY_PROMPT = PromptTemplate(input_variables=["question"],template="""You are an AI language model assistant. Your task is to generate 3 different versions of the given user question to retrieve relevant documents from a vector  database. By generating multiple perspectives on the user question, your goal is to help the user overcome some of the limitations of distance-based similarity search. Provide these alternative questions separated by newlines. Original question: {question}""",
)

MultiQueryRetriever 源码的检索过程:

    def _get_relevant_documents(self,query: str,*,run_manager: CallbackManagerForRetrieverRun,) -> List[Document]:"""Get relevant documents given a user query.Args:query: user queryReturns:Unique union of relevant documents from all generated queries"""queries = self.generate_queries(query, run_manager)if self.include_original:queries.append(query)documents = self.retrieve_documents(queries, run_manager)return self.unique_union(documents)def generate_queries(self, question: str, run_manager: CallbackManagerForRetrieverRun) -> List[str]:"""Generate queries based upon user input.Args:question: user queryReturns:List of LLM generated queries that are similar to the user input"""response = self.llm_chain.invoke({"question": question}, config={"callbacks": run_manager.get_child()})if isinstance(self.llm_chain, LLMChain):lines = response["text"]else:lines = responseif self.verbose:logger.info(f"Generated queries: {lines}")return linesdef retrieve_documents(self, queries: List[str], run_manager: CallbackManagerForRetrieverRun) -> List[Document]:"""Run all LLM generated queries.Args:queries: query listReturns:List of retrieved Documents"""documents = []for query in queries:docs = self.retriever.invoke(query, config={"callbacks": run_manager.get_child()})documents.extend(docs)return documents

    源码方法实现说明:

    • generate_queries 方法,实现查询变体生成;
    • retrieve_documents 方法,是文档检索的实现,从代码中也可以看到了,是遍历查询变体来逐一检索,并将检索结果汇总返回;
    • _get_relevant_documents 方法,是整个过程:生成查询变体,执行检索,检索结果去重。

    方案探究实现简述

    (1)检索实现流程图如下:

    (2)该方案实现,结合了 RRF 重排

           RRF 会合并来自多个不同检索器的结果列表,为每个结果分配一个融合得分。如果某个文本块在多个结果列表中均排名靠前,那么它的 RRF 总分会更高。这种方法体现了集成学习的思想

    RRF 算法的关键重排序公式如下:

    公式说明:

    • d:代表某个特定文本块
    • RRF(d):是文本块d的融合得分;
    • N:是输入的多个检索结果列表的数量;
    • k:是平滑参数,用于控制排名对得分的影响,通常取值为一个常熟(如60)
    • rank i (d):是文本块d 在第 i 个排序器中的排名(从1 开始计数)。

    (3)方案具体实现及评估,请查看:

    检索召回率优化探究二:基于 LangChain 0.3集成 Milvus 2.5向量数据库构建的智能问答系统-CSDN博客

    方案二:基于 LangChain 工具类 RePhraseQueryRetriever

    RePhraseQueryRetriever 介绍

    RePhraseQueryRetriever 实现文本检索的源码如下:

        def _get_relevant_documents(self,query: str,*,run_manager: CallbackManagerForRetrieverRun,) -> List[Document]:"""Get relevant documents given a user question.Args:query: user questionReturns:Relevant documents for re-phrased question"""re_phrased_question = self.llm_chain.invoke(query, {"callbacks": run_manager.get_child()})logger.info(f"Re-phrased question: {re_phrased_question}")docs = self.retriever.invoke(re_phrased_question, config={"callbacks": run_manager.get_child()})return docs

    源码默认提示词:

    # Default template
    DEFAULT_TEMPLATE = """You are an assistant tasked with taking a natural language \
    query from a user and converting it into a query for a vectorstore. \
    In this process, you strip out information that is not relevant for \
    the retrieval task. Here is the user query: {question}"""

    从中可知,它的实现流程是:依据提示词将原始查询进行重写,之后就调用检索器执行检索,最后将检索结果返回。

    方案探究实现简述

    (1)方案实现流程图如下:

    从上图可知,在使用 RePhraseQueryRetriever 上进行了巧用或者说是创新吧。

    • 自定义提示词,实现原始查询的重写,要求重写为 3个不同问法;
    • 检索器适配性处理,将重写结果切分并逐一检索;
    • 自定义去重方法,依据检索结果返回的 Hits 对象的 id进行去重。

    (2)方案具体实现及评估,请查看:

    检索召回率优化探究三:基于LangChain0.3集成Milvu2.5向量数据库构建的智能问答系统-CSDN博客

    方案三:借鉴 HyDE 思想

    HyDE 介绍

           HyDE,全称为:Hypothetical Docunment Embeddings,翻译为:假设性文档嵌入。它的思想是源于论文《Precise Zero-Shot Dense Retrieval without Relevance Labels》。

           论文探讨解决的问题是:零样本密集检索中的学习问题。传统的密集检索方法需要大量的标记数据来进行训练,而HyDE 则不需要任何标记数据或相关性判断,仅需要使用一些简单的文本示例即可完成学习任务。

     方案探究实现简述

    (1)方案实现流程图如下:

          这个流程图,和工具类 RePhraseQueryRetriever 的实现过程基本一样的,唯一不同的就是 prompt 的定义和所使用的 LLM。

           也就是因为这两者的不同,它们最终的检索召回率是有差别的,HyDE 这种方式检索召回率要高出一些。这样也是可以理解的,HyDE 对原始查询进行了扩展,会使得语义更丰富、清晰,从而就能更准确地检索到相关的文档片段。

    (2)方案具体实现及评估,请查看:

    检索召回率优化探究四:基于LangChain0.3集成Milvu2.5向量数据库构建的智能问答系统_langchain 与 fastgpt 召回率-CSDN博客

    不同实现方式的评估结果

    指标实现方案传统 RAGRAG-Fusion召回率提升幅度
    召回@2方案一79.52%74.70%-6.06%
    召回@3方案一79.52%83.13%4.54%
    召回@2方案二79.52%82.05%3.18%
    召回@3方案二79.52%87.50%10.04%
    召回@3方案三79.52%87.65%10.22%

    上述表格说明:

    • @2,@3:是指检索最终返回的最相似向量个数;
    • 实现方案一、二、三:就是上述 RAG-Fusion 实现章节的方案一、二、三。

    RAG-Fusion 总结

    使用 RAG-Fusion 的好处

    1. 提高召回率:通过生成多个语义相关的查询变体,可以覆盖用户意图的更多方面,从而增加找到相关文档片段的概率。
    2. 增强鲁棒性:多个查询减少了对原始查询表述的依赖,有助于避免由于查询表述偏差导致的检索失败,尤其是在用户输入模糊或不准确的情况下。
    3. 适应复杂查询:对于复杂或多方面的查询来说,RAG-Fusion 可以将其分解成若干子问题,并分别进行处理,最后将结果整合起来,提供一个全面的回答。
       

    使用 RAG-Fusion 带来的问题

    1. 计算成本较高:由于需要生成多个查询并执行多次检索,RAG-Fusion 相比传统方法会消耗更多的计算资源和时间。
    2. 系统复杂度增加:实现 RAG-Fusion 需要集成多个组件(如查询生成模块、向量数据库、大型语言模型),增加了系统的复杂度和维护成本。
    3. 响应延迟问题:额外的检索步骤可能导致响应时间延长,对于实时性要求高的应用场景来说可能是一个挑战。
    4. 结果稀释风险:如果不恰当地生成过多查询,可能会导致原本明确的用户意图被稀释,反而影响到最终答案的相关性。


    最后汇总一下文章引用:

    检索召回率优化探究二:基于 LangChain 0.3集成 Milvus 2.5向量数据库构建的智能问答系统-CSDN博客

    检索召回率优化探究三:基于LangChain0.3集成Milvu2.5向量数据库构建的智能问答系统-CSDN博客

    检索召回率优化探究四:基于LangChain0.3集成Milvu2.5向量数据库构建的智能问答系统_langchain 与 fastgpt 召回率-CSDN博客

    http://www.dtcms.com/a/329905.html

    相关文章:

  • 数据分析小白训练营:基于python编程语言的Numpy库介绍(第三方库)(下篇)
  • 智能制造数字孪生最佳交付实践:打造数据融合×场景适配×持续迭代的数字孪生框架
  • 计算机二级 Web —— HTML 全面精讲(含真题实战)
  • 2020/12 JLPT听力原文 问题一 5番
  • Unity3d UGUI图片按钮只有非透明区域(透明阈值)可以点击功能实现(含源码)
  • OSG —— Windows11下Vs2017完美编译Osg3.6.5+osgQt(附:Osg+osgQt测试用例)
  • GLSL学习
  • IPO辅导四年半,马上消费何时“马到成功”?
  • 深度解析:DCF估值模型实战指南 ——以Kappa Pi Therapeutics为例的完整估值建模过程
  • 万字长文全解析:五种主流归一化方法深入讲解(BN/LN/IN/GN/WN)
  • html img标签设置默认图片,防止图片路径不存在导致图片不展示影响页面美观
  • 微服务单元测试组件
  • 二分|回溯
  • 了解 Linux 中的 /usr 目录以及 bin、sbin 和 lib 的演变
  • C++算法·递推递归
  • 基于.Net Framework4.5 Web API 引用Swagger
  • HCIP——OSPF综合实验
  • 药房智能盘库系统:基于CV与时间序列预测的库存革命
  • 蓝蜂网关在雄安新区物联网建设中的关键应用
  • Vue内置组件全解析:从入门到面试通关
  • 用 OPC UA C# WinForm 的单节点订阅方法
  • 【个人项目】跑者天地—测试用例
  • AI搜索的极限优化、新兴技术、硬件加速、特定行业解决方案
  • [QtADS]解析demo.pro
  • 利用 Makefile 高效启动 VIVADO 软件:深入解析与实践
  • 十,算法-动态规划
  • 深入理解 Cookie 与 Session —— Web 状态保持详解与实战
  • 目标检测公开数据集全解析:从经典到前沿
  • Linux软件编程3.(文件IO和目录IO)
  • windows设置相对路径的快捷方式