原文:https://zhuanlan.zhihu.com/p/682253496

整理:青稞AI

1. 背景介绍

RAG(Retrieval Augmented Generation,检索增强生成 )方法是指结合了基于检索的模型和生成模型的能力,以提高生成文本的质量和相关性。该方法是Meta在2020年发表的文章《Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks》[1]中提出的,该方法让LM(Language Model,语言模型)能够获取内化知识之外的信息,并允许LM在专业知识库的基础上,以更准确的方式回答问题。而在大模型时代,它更是用于解决幻觉问题、知识时效问题、超长文本问题等各种大模型本身制约或不足的必要技术。

2. RAG的挑战

RAG主要面临三个方面的挑战:检索质量、增强过程和生成质量。

2.1 检索质量

  • 语义歧义:向量表示(例如词嵌入)可能无法捕捉概念之间的细微差别。例如,“苹果”一词可能指的是水果或科技公司。嵌入可能会混淆这些含义,导致不相关的结果。

  • 用户输入变复杂:与传统关键词或者短语搜索逻辑不太一致,用户输入问题不再是词或者短句,而是转变成自然对话声知识多轮对话数据,问题形式更加多元,紧密关联上下文,输入风格更加口语化。

  • 文档切分:文档切分主要有两种方式:一种是基于形式的切分,比如利用标点和段落的结束;另一种是基于文档内容的意义进行切分。如何将这些文档块转换成电脑能够理解和比较的形式(即“嵌入”),进而影响这些块与用户搜索内容的匹配程度。

  • 多模内容的提取及表征(例如表格、图表、公式等):如何对多模内容进行提取及动态表征,是目前面临的现实问题,尤其是处理那些含糊或负面的查询,对 RAG 系统的性能有显著影响。

2.2 增强过程
  • 上下文的集成:这里的挑战是将检索到的段落的上下文与当前的生成任务顺利地集成。如果做得不好,输出可能会显得脱节或缺乏连贯性。

  • 冗余和重复:如果多个检索到的段落包含相似的信息,则生成步骤可能会产生重复的内容。

  • 排名和优先级:确定多个检索到的段落对于生成任务的重要性或相关性可能具有挑战性。增强过程必须适当权衡每个段落的价值。

2.3 生成质量
  • 过度依赖检索内容:生成模型可能过于依赖增强信息,导致幻觉问题突出,而不是增加价值或提供合成。

  • 无关性:这是另一个令人担忧的问题,即模型生成的答案无法解决查询问题。

  • 毒性或偏见:这也是另一个问题,即模型生成的答案有害或令人反感。

3. 整体架构 3.1 产品架构
打开网易新闻 查看更多图片

从图上可以清晰的看出,整个产品架构包含如下四层:

  • • 最底层是模型层。在模型层屏蔽掉了模型的差异,不仅可以支持自研的序列猴子,也可以支持开源的大模型,第三方的模型。此外,为了优化embedding的效果,提出一种跨语言Embedding模型,有效的解决跨语言检索问题,同时提高了模型的效果。

  • 离线理解层。在该层,主要围绕智能知识库和搜索增强两个模块设计的。关于智能知识库主要负责将非结构化的文本进行处理,从而转化为检索知识库,主要包括文本解析,表格识别,OCR识别等。搜索增强通过引入问句改写、重排等模块,保证检索的精准度。

  • 在线问答层,为了满足产品设计需要,这里支持多文档、多轮次、多模态及安全性与拒识等,在一定程度上提高了产品的竞争力,同时也满足了不同场景的用户需求。

  • 场景层,针对不同行业的特点,预制多种场景类角色,降低产品使用门槛。

3.2 技术架构

为了理解检索增强生成框架,我们将其分为三个主要组成部分:query理解、检索模型和生成模型。

  • • query理解:该模块旨在对用户的query进行理解或者将用户的query生成结构化的查询,既可以查询结构化的数据库也可以查询非结构化的数据,进而提高召回率。该模块包括四部分,他们分别是query改写,query扩写和意图识别等。各个模块的介绍我们将在之后的章节进行详细介绍。

  • • 检索模型:该模型旨在从给定的文档集或知识库中检索相关信息。他们通常使用信息检索或语义搜索等技术来根据给定的查询识别最相关的信息。基于检索的模型擅长查找准确且具体的信息,但缺乏生成创意或新颖内容的能力。从技术上来讲, 检索模型主要包括文档加载、文本转换、Embedding等模块。我们将在之后的章节中详细介绍。

  • • 生成模型:该模型旨在根据给定的Prompt或上下文生成新内容。目前,生成模型可以生成富有创意且连贯的文本,但它们可能会在事实准确性或与特定上下文的相关性方面遇到困难。在RAG框架中,生成模型主要包括chat系统(长期记忆和短期记忆)、Prompt优化等。这些内容在之后的章节中也会介绍。

总之,检索增强生成结合了检索模型和生成模型优势,克服它们各自的局限性。在此框架中,基于检索的模型用于根据给定的查询或上下文从知识库或一组文档中检索相关信息。然后,检索到的信息将用作生成模型的输入或附加上下文。通过整合检索到的信息,生成模型可以利用基于检索的模型的准确性和特异性来生成更相关、更准确的文本。这有助于生成模型立足于现有知识,生成与检索信息一致的文本。

4. Query理解

目前,RAG系统可能会遇到从知识库中检索到与用户query不相关的内容。这是由于如下问题:(1)用户问题的措辞可能不利于检索,(2)可能需要从用户问题生成结构化查询。为了解决上述问题,我们引入query理解模块。

4.1 意图识别

意图识别是指接收用户的query和一组"选择"(由元数据定义)并返回一个或多个选定的"选择模块"。它既可以单独使用(作为 "选择器模块"),也可以作为查询引擎或检索器使用(例如,在其他查询引擎/检索器之上)。它是原理简单但功能强大的模块,目前主要利用 LLM 实现决策功能。

它可以应用于如下场景:

  • • 在各种数据源中选择正确的数据源;

  • • 决定是进行摘要(如使用摘要索引查询引擎)还是进行语义搜索(如使用矢量索引查询引擎);

  • • 决定是否一次 "尝试 "多种选择并将结果合并(使用多路由功能)。

核心模块有以下几种形式:

  • • LLM 选择器将选择作为文本转储到提示中,并使用 LLM 做出决定;

  • • 构建传统的分类模型,包括基于语义匹配的分类模型、Bert意图分类模型等。

4.2 Query改写

该模块主要利用LLM重新措辞用户query,而不是直接使用原始的用户query进行检索。这是因为对于RAG系统来说,在现实世界中原始query不可能总是最佳的检索条件。

4.2.1 HyDE[2]

Hypothetical Document Embeddings(HyDE)是一种生成文档嵌入以检索相关文档而不需要实际训练数据的技术。首先,LLM创建一个假设答案来响应query。虽然这个答案反映了与query相关的模式,但它包含的信息可能在事实上并不准确。接下来,query和生成的答案都被转换为嵌入。然后,系统从预定义的数据库中识别并检索在向量空间中最接近这些嵌入的实际文档。

打开网易新闻 查看更多图片

4.2.2 Rewrite-Retrieve-Read[3]

这项工作引入了一个新的框架--Rewrite-Retrieve-Read,从query改写的角度改进了检索增强方法。之前的研究主要是调整检索器或LLM。与之不同的是,该方法注重query的适应性。因为对于 LLM 来说,原始query并不总是最佳检索结果,尤其是在现实世界中。首先利用LLM 进行改写query,然后进行检索增强。同时,为了进一步提高改写的效果,应用小语言模型(T5)作为可训练的改写器,改写搜索query以满足冻结检索器和 LLM的需要。为了对改写器进行微调,该方法还使用伪数据进行有监督的热身训练。然后,将 "先检索后生成 "管道建模为强化学习环境。通过最大化管道性能的奖励,改写器被进一步训练为策略模型。

4.3 Query扩写

该模块主要是为了将复杂问题拆解为子问题。该技术使用分而治之的方法来处理复杂的问题。它首先分析问题,并将其分解为更简单的子问题,每个子问题会从提供部分答案的相关文件检索答案。然后,收集这些中间结果,并将所有部分结果合成为最终响应。

4.3.1 Step-Back Prompting[4]

该工作探索了LLM如何通过抽象和推理两个步骤来处理涉及许多低级细节的复杂任务。第一步先是使用 LLM "后退一步"生成高层次的抽象概念,将推理建立在抽象概念的基础上,以减少在中间推理步骤中出错的概率。这种方法即可以在有检索的情况下使用,也可以在无检索的情况下使用。当在有检索情况下使用时,抽象的概念和原始问题都用来进行检索,然后这两个结果都用来作为LLM响应的基础。

4.3.2 CoVe[5]

Chain of Verification (CoVe) 旨在通过系统地验证和完善回答以尽量减少不准确性,从而提高大型语言模型所提供答案的可靠性,特别是在事实性问题和回答场景中。它背后的概念是基于这样一种理念,即大型语言模型(LLM)生成的响应可以用来验证自身。这种自我验证过程可用于评估初始响应的准确性,并使其更加精确。

在RAG系统中,针对用户实际场景中日益复杂的问题,借鉴了 CoVe技术,将复杂 Prompt 拆分为多个独立且能并行检索的搜索友好型query,让LLM对每个子查询进行定向知识库搜索,最终提供更准确详实答案的同时减少幻觉输出。

打开网易新闻 查看更多图片

4.3.3 RAG-Fusion[6]

在这种方法中,原始query经过LLM 生成多个query。然后可以并行执行这些搜索查询,并将检索到的结果一并传递。当一个问题可能依赖于多个子问题时,这种方法就非常有用。RAG-Fusion便是这种方法的代表,它是一种搜索方法,旨在弥合传统搜索范式与人类查询的多面性之间的差距。这种方法先是采用LLM生成多重查询,之后使用倒数排名融合(Reciprocal Rank Fusion,RRF)来重新排序。

4.3.4 ReAct[7]

最近,在RAG系统中,使用ReAct思想,将复杂查询分解成更简单的"子查询",知识库的不同部分可能会围绕整个查询回答不同的 "子查询"。这对组合图尤其有用。在组成图中,一个查询可以路由到多个子索引,每个子索引代表整个知识语料库的一个子集。通过查询分解,我们可以在任何给定的索引中将查询转化为更合适的问题。

ReAct的模式如上图所示,它是将思维链提示(Chain of Thoughts,简写为CoT)和Action计划生成结合起来,相互补充增强,提升大模型解决问题的能力。其中CoT的Reasoning推理跟踪有助于模型诱导、跟踪和更新行动计划以及处理异常。Action操作允许它与知识库或环境等外部来源接口并收集其他信息。

4.4 Query重构

考虑Query理解模块整体pipeline的效率,参考Query改写和Query扩写核心思想,自研了Query重构模块,该模块强调了通过一次请求,实现对原始用户输入的复杂问题进行改写、拆解和拓展,挖掘用户更深层次的子问题,从而借助子问题检索效果更高的特点来解决复杂问题检索质量偏差的问题,旨在提高查询的准确性和效率。

5. 检索模型 5.1 检索模型的挑战

  • • 依赖于Embedding模型的向量化是否准确

  • • 依赖于外部数据是否有合理的分割(不能所有的知识转化成一个向量,而是需要分割数据后转化再存入向量数据库)

  • • 依赖于Prompt拼接,当我们将返回的最相似的文档进行排序后,与用户的问题一起送给大模型,实际上是想让大模型在长上下文中准确识别定位到合适的内容进行回答。

《Lost in the Middle: How Language Models Use Long Contexts》[8]文章指出,当相关信息出现在输入上下文的开头或结尾时,性能往往最高,而当模型必须在长上下文中间获取相关信息时,性能会明显下降,即使对于明确的长上下文模型也是如此。

注:图片来源于langchain。 5.3 文档加载器

文档加载器提供了一种 "加载 "方法,用于从配置源加载文档数据。文档数据是一段文本和相关元数据。文档加载器可从多种不同来源加载文档。例如,有一些文档加载器可以加载简单的 .txt 文件或者加载任何网页的文本内容,甚至加载 YouTube 视频的副本。此外,文档加载器还可以选择实现 "懒加载",以便将数据懒加载到内存中。

5.4 文本转换器

检索的一个关键部分是只获取文档的相关部分。当加载文档后,通常需要对其进行转换,以便更好地适应应用程序。这涉及几个转换步骤,以便为检索文档做好准备。其中一个主要步骤是将大型文档分割(或分块)成较小的块,即文本转换器。最简单的例子是,当需要处理长篇文本时,有必要将文本分割成若干块,以便能放入模型的上下文窗口中。理想情况下,希望将语义相关的文本片段放在一起。这听起来很简单,但潜在的复杂性却很大。

5.4.1 工作原理

  • • 将文本分割成语义上有意义的小块(通常是句子)。

  • • 开始将这些小块组合成一个大块,直到达到一定的大小(用某个函数来衡量)。

  • • 一旦达到一定大小,就将该语块作为自己的文本,然后开始创建有一定重叠的新语块(以保持语块之间的上下文)。

5.4.2 常见如下文本转换器类型

Name Splits On Adds Metadata Description Recursive A list of user defined characters
Recursively splits text. Splitting text recursively serves the purpose of trying to keep related pieces of text next to each other. This is the recommended way to start splitting text. HTML HTML specific characters ✅ Splits text based on HTML-specific characters. Notably, this adds in relevant information about where that chunk came from (based on the HTML) Markdown Markdown specific characters ✅ Splits text based on Markdown-specific characters. Notably, this adds in relevant information about where that chunk came from (based on the Markdown) Code Code (Python, JS) specific characters
Splits text based on characters specific to coding languages. 15 different languages are available to choose from. Token Tokens
Splits text on tokens. There exist a few different ways to measure tokens. Character A user defined character
Splits text based on a user defined character. One of the simpler methods. [Experimental] Semantic Chunker Sentences
First splits on sentences. Then combines ones next to each other if they are semantically similar enough. Taken from Greg Kamradt

5.4.3 评估文本转换器

你可以使用 Greg Kamradt 创建的 Chunkviz 工具来评估文本转换器。Chunkviz 是可视化文本转换器工作情况的工具。它可以向你展示文本的分割情况,并帮助你调整分割参数。

5.5 文本嵌入模型

检索的另一个关键部分是文档嵌入模型。文档嵌入模型会创建一段文本的向量表示。它可以捕捉文本的语义,让你快速有效地找到文本中相似的其他片段。这非常有用,因为它意味着我们可以在向量空间中思考文本,并进行语义搜索等操作。

理想情况下,检索器应该具备将不同语种的翻译文本做关联的能力(跨语种检索能力),具备将长原文和短摘要进行关联的能力,具备将不同表述但相同语义的文本做关联的能力,具备将不同问题但相同意图的问题进行关联的能力,具备将问题和可能的答案文本进行关联的能力。此外,为了给大模型尽可能高质量的知识片段,检索器还应该给出尽可能多的相关片段,并且真正有用的片段应该在更靠前的位置,可以过滤掉低质量文本片段。最后,期望我们的模型可以覆盖尽可能多的领域和场景,可以实现一个模型打通多个业务场景,让用户获得开箱即用的模型,不需要再做微调。

5.6 向量数据库

随着嵌入式的兴起,人们开始需要向量数据库来支持这些嵌入式的高效存储和搜索。存储和搜索非结构化数据的最常见方法之一是嵌入数据并存储由此产生的嵌入向量,然后在查询时嵌入非结构化查询并检索与嵌入查询 "最相似 "的嵌入向量。向量数据库负责存储嵌入数据并执行向量搜索。

打开网易新闻 查看更多图片
5.7 索引

经过前面的数据读取和文本分块操作后,接着就需要对处理好的数据进行索引。索引是一种数据结构,用于快速检索出与用户查询相关的文本内容。它是检索增强 LLM 的核心基础组件之一。

下面介绍几种常见的索引结构。为了说明不同的索引结构,引入节点(Node)的概念。在这里,节点就是前面步骤中对文档切分后生成的文本块(Chunk)。下面的索引结构图来自 LlamaIndex 的《 How Each Index Works》[9]。

5.7.1 摘要索引(以前称为链式索引)

摘要索引只是将节点存储为顺序链。在后续的检索和生成阶段,可以简单地顺序遍历所有节点,也可以基于关键词进行过滤。

5.7.2 树索引

树索引将一组节点 ( 文本块 ) 构建成具有层级的树状索引结构,其从叶节点 (原始文本块) 向上构建,每个父节点都是子节点的摘要。在检索阶段,既可以从根节点向下进行遍历,也可以直接利用根节点的信息。树索引提供了一种更高效地查询长文本块的方式,它还可以用于从文本的不同部分提取信息。与链式索引不同,树索引无需按顺序查询。

5.7.3 关键词表索引

关键词表索引从每个节点中提取关键词,构建了每个关键词到相应节点的多对多映射,意味着每个关键词可能指向多个节点,每个节点也可能包含多个关键词。在检索阶段,可以基于用户查询中的关键词对节点进行筛选。

5.7.4 向量索引

向量索引是当前最流行的一种索引方法。这种方法一般利用文本嵌入模型将文本块映射成一个固定长度的向量,然后存储在向量数据库中。检索的时候,对用户查询文本采用同样的Embedding模型映射成向量,然后基于向量相似度计算获取最相似的一个或者多个节点。

5.8 排序和后处理

经过前面的检索过程可能会得到很多相关文档,就需要进行筛选和排序。常用的筛选和排序策略包括:

  • • 基于相似度分数进行过滤和排序

  • • 基于关键词进行过滤,比如限定包含或者不包含某些关键词

  • • 让 LLM 基于返回的相关文档及其相关性得分来重新排序

  • • 基于时间进行过滤和排序,比如只筛选最新的相关文档

  • • 基于时间对相似度进行加权,然后进行排序和筛选

6. 生成模型 6.1 回复生成策略

检索模块基于用户查询检索出相关的文本块,回复生成模块让 LLM 利用检索出的相关信息来生成对原始查询的回复。这里给出一些不同的回复生成策略。

  • • 一种策略是依次结合每个检索出的相关文本块,每次不断修正生成的回复。这样的话,有多少个独立的相关文本块,就会产生多少次的 LLM 调用。

  • • 一种策略是在每次 LLM 调用时,尽可能多地在 Prompt 中填充文本块。如果一个 Prompt 中填充不下,则采用类似的操作构建多个 Prompt,多个 Prompt 的调用可以采用和前一种相同的回复修正策略。

6.2 prompt拼接策略

用于将提示的不同部分组合在一起。您可以使用字符串提示或聊天提示来执行此操作。以这种方式构建提示可以轻松地重用组件。

6.2.1 字符串提示

使用字符串提示时,每个模板都会连接在一起。您可以直接使用提示或字符串(列表中的第一个元素必须是提示)。例如,langchain提供的prompttemplate[10]。

6.2.2 聊天提示

聊天提示由消息列表组成。纯粹为了开发人员体验,我们添加了一种便捷的方式来创建这些提示。在此管道中,每个新元素都是最终提示中的一条新消息。例如,langchain提供的AIMessage, HumanMessage, SystemMessage[11]。

7. 插件(Demonstration Retriever for In-Context Learning,基于演示检索的上下文学习)

上下文学习(In-Context learning)是一种新兴的范式,它是指通过给定一些示范性的输入-输出对(示例),在不更新模型参数的情况下实现对给定测试输入的预测。它独特的无需更新参数能力使得上下文学习的方法可以通过一个语言模型的推理,来统一各种自然语言处理任务,这使其成为监督式微调的一个有前途的替代方案。

虽然,这种方法在各种自然语言处理的任务中都表现不错,但它的表现依赖给定的示范性输入-输出对。在模型的prompt中为每个任务都指定示范性示例会影响prompt的长度,这导致每次调用大语言模型的成本增加,甚至超出模型的输入长度。因此,这带来一个全新的研究方向——基于演示检索的上下文学习。这类方法主要是通过文本(或语义)检索与测试输入在文本或语义上相似的候选示范性示例,将用户的输入与获得相似的示范性示例加入到模型prompt中作为模型的输入,则模型就可以给出正确的预测结果。然而,上述单一的检索策略使得召回率不高,造成示范性示例无法精准召回,致使模型的效果不佳。

为了解决上述问题,我们提出了一种基于混合演示检索的上下文学习方法。该方法充分考虑不同检索模型的优劣,提出一种融合算法,通过利用文本检索(例如,BM25和TF-IDF)和语义检索(例如,OpenAI embedding-ada和sentence-bert)进行多路召回,解决单路召回率不高的问题。然而,这带来全新的挑战,即如何将不同的召回结果进行融合。这是由于不同检索算法分数范围不匹配,例如,文本检索分数通常在 0 和某个最大值之间(这具体取决于查询的相关性);而语义搜索(例如,余弦相似度)生成 0 到 1 之间的分数,这使得直接对召回结果进行排序变得很棘手。因此,我们又提出一种基于倒序排序融合算法(Reciprocal Rank fusion)的重排方法,该算法在不需要调整模型的情况下,利用位置来组合不同检索算法的结果,同时,考虑到大模型对相关信息出现在输入上下文的开头或结尾时,性能往往最高,设计重排算法,从获得高质量的融合结果。

具体的模型架构如下图所示,它包括检索模块、重排模块和生成模块。

7.1 检索模块

检索模块又分为文本检索和语义检索。

语义检索采用双塔模型,用OpenAI的embedding-ada作为表征模型,分别对用户的输入和每个任务的候选示例进行表征,获取语义向量,之后利用k-近邻算法(K-Nearest Neighbor,KNN)计算语义相似度,并依据相似度对候选结果进行排序。其中,对于每个任务的候选示例我们采用离线表征,并将其存入向量数据库中,这是因为一旦任务确认,每个任务的候选示例是固定不变的。而对于用户的输入,我们采用实时表征,提高计算效率,这是因为用户的输入是多样的、不固定的。

文本检索,我们先是对每个任务的候选示例进行文本预处理,去除掉停用词、特殊符号等。同时,在文本检索中采用倒排索引的技术加速查询,并利用BM25计算文本相似度,最后按相似度进行排序。

7.2 重排模块

对于重排模块,我们提出了一种基于倒序排序融合的重排算法。该方法先是为了解决不同召回算法的分数范围不匹配的问题,我们引入倒序排序融合算法,对多路的召回结果进行融合排序。虽然倒序排序融合算法可以很好将多路召回进行融合排序,但是这种排序无法满足大模型具有对相关信息出现在输入上下文的开头或结尾时性能最高的特性。这使得简简单单的利用倒序排序融合进行输出,效果不好。因此,我们在此基础之上对融合排序后的结果进行重排,排序策略是依据融合排序后的结果进行两端填充排序。例如,原本的顺序为[1,2,3,4,5],进行重排后的顺序为[1,3,5,4,2]。

7.3 生成模块

生成模块可以生成富有创意且连贯的文本,它旨在根据给定的Prompt或上下文生成新内容,这里我们设计了prompt组装模块,通过将系统prompt与检索到相关信息进行组合。此外,还在组装模块中融入长期对话记录和短期对话记录进行prompt封装。

8. 引用或归因(attribution)生成 8.1 什么是引用或归因

在RAG 的知识问答场景下,随着越来越多的文档、网页等信息被注入应用中,越来越多开发者意识到信息来源的重要性,它可以让模型生成的内容能够与参考信息的内容作出对齐,提供证据来源,确保信息准确性,使得大模型的回答更加真实。

8.2 归因的作用

  • • 用户角度:能够验证模型的回答是否靠谱。

  • • 模型角度:提高准确性并减少幻觉。

8.3 如何实现归因

8.3.1 模型生成

直接让模型生成归因信息。可在Prompt 添加类似“每个生成的证据都需在参考信息中进行引用”的话。这种方法最简单,但也对模型的指令遵循能力要求较高,一般会采用GPT-4 回答,或者微调模型让模型学习在生成时附带引用的回答方式。缺点也很明显,极度依赖模型的能力(甚至可能引用也是编的),且针对实际场景中出现的badcase 修复周期长,干预能力弱。

8.3.2 动态计算

在模型生成的过程中进行引用信息的附加。具体的操作为在流式生成的场景下,对生成的文本进行语义单元的判断(比如句号,换行段落等),当出现一个完整的语义单元时,将该语义单元和参考信息中的每个参考源进行匹配(关键字,embedding等),通过卡阈值的办法找到Top-N 的参考源,从而将参考源进行附加返回。这种方法的实现相比方法一简单了很多,badcase 修复周期也短,但受限于匹配方式和阈值,且存在一个前提假设:模型的生成文本来源于参考信息。

更多关于归因研究的工作可以参考:A Survey of Large Language Models Attribution[12]

9. 评估

做开发的同学不管用没用过,对 TDD(Test-Driven Development)的大名总归是听过的,类似的,开发大模型应用的时候也应该有个对应的 MDD(Metrics-Driven Development) 的概念,最舒服的姿势肯定是预先定义好业务的场景、用到的数据、设定的指标以及需要达到的分值,然后按部就班的实现既定目标,员工士气高老板也开心!

但理想和现实之间总是如此纠缠,对大部分的大模型开发任务来讲,更常见的情况是场景定义不清楚,数据光清洗就累死三军,至于需要的指标和目标?想都没想过!这一次,我们来补上本应该在最最开始的就考虑的,大模型应用如何量化业务指标,具体的,如何量化的证明,你的 RAG 就是比隔壁老王他们组的牛?到底该拿哪些量化的指标去说服同行?

影响RAG系统性能的几个方面:

  • • 位置偏见:LLMs 有可能对文本中特定位置的内容给予更高的关注,比如位于段落开头和结尾的内容更容易被采纳。

  • • 检索内容相关性:由于query的表达多样性,使得RAG系统可能检索到不相关的内容,这种不相关的内容为LLMs理解带来噪音,增加模型的负担。

9.1 评测指标
  • • Faithfulness是指用于评测生成的回答是否忠实于contexts,这对于避免幻觉并确保检索到的上下文可以作为生成答案的理由非常重要。

  • • Answer Relevance是指的生成的答案应解决所提供的实际问题。

  • • Context Relevance是指检索的上下文应重点突出,尽可能少地包含无关信息。理想情况下,检索到的上下文应该只包含处理所提供查询的基本信息。包含的冗余信息越少,context_relevancy越高。

9.2 评测方法

9.2.1 RGB(Benchmarking Large Language Models in Retrieval-Augmented Generation)[13]

这一工作系统地研究了检索增强生成对大型语言模型的影响。它分析了不同大型语言模型在RAG所需的4项基本能力方面的表现,包括噪声鲁棒性、拒答、信息整合和反事实鲁棒性,并建立了检索增强生成基准。此外,现在做RAG都是做的pipeline,涉及到切块、相关性召回、拒答等多个环节,每个环节都可以单独做评测,文中提到的4个能力其实可以影射到每个环节当中。

9.2.2 RAGAS(RAGAS: Automated Evaluation of Retrieval Augmented Generation)[14]

该工作提出了一种对检索增强生成(RAG)pipeline进行无参考评估的框架。该框架考虑检索系统识别相关和重点上下文段落的能力, LLM以忠实方式利用这些段落的能力,以及生成本身的质量。目前,该方法已经开源,具体可以参见github:GitHub - exploding gradients/ragas: Evaluation framework for your Retrieval Augmented Generation (RAG) pipelines

9.2.3 Llamalindex-Evaluating[15]

LlamaIndex提供了衡量生成结果质量的关键模块。同时,还提供关键模块来衡量检索质量。

10. 总结

LLM这一波,催生的技术真的很多,每一个环节,要真正做好,符合企业应用,都可以让我们研究好长一段时间,并需要不断去实践,才能打磨出精品。本文总结了过去一年在RAG实践的关键模块,希望本文总结对大家有一定的帮助。

引用链接

[1]: https://arxiv.org/abs/2005.11401v4
[2]: https://boston.lti.cs.cmu.edu/luyug/HyDE/HyDE.pdf
[3]: https://arxiv.org/pdf/2305.14283.pdf?ref=blog.langchain.dev
[4]: https://arxiv.org/pdf/2310.06117.pdf?ref=blog.langchain.dev
[5]: https://arxiv.org/pdf/2309.11495.pdf
[6]: https://github.com/Raudaschl/rag-fusion
[7]: https://arxiv.org/pdf/2210.03629.pdf
[8]: https://arxiv.org/pdf/2307.03172.pdf
[9]: https://docs.llamaindex.ai/en/latest/module_guides/indexing/index_guide.html
[10]: https://python.langchain.com/docs/modules/model_io/prompts/composition
[11]: https://python.langchain.com/docs/modules/model_io/prompts/composition
[12]: https://arxiv.org/pdf/2311.03731.pdf
[13]: https://arxiv.org/pdf/2309.01431.pdf
[14]: https://arxiv.org/pdf/2309.15217.pdf
[15]: https://docs.llamaindex.ai/en/latest/module_guides/evaluating/root.html