AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


关于RAG你不得不了解的17个技巧
发布日期:2025-01-08 05:48:40 浏览次数: 1623 来源:ChallengeHub



最近在写文章,想补上去年RAG(Retrieval-Augmented Generation)遗留的一些坑,希望能分享一些RAG的技巧帮到大家。

还是那句老话:

构建一个大模型的原型很容易,但把它变成一个能真正投入生产的产品却很难。

这篇文章适合那些在过去一个月里刚刚构建了第一个LLM(大语言模型)应用程序,并开始考虑如何将其产品化的朋友们。我们将介绍17种技术,帮助你们避免在RAG开发过程中重复踩坑——毕竟,在同一个坑里跌倒两次,岂不是太浪费时间了?通过这些技巧,你们可以逐步优化大模型的技术方案,提升RAG在实际应用中的效果和稳定性。

生产数据是LLM落地的基石

毫无疑问,LLM变得越来越强大,但如果我们仔细看看,真正完全依赖纯大模型的产品其实并不多。大多数情况下,大模型只是扮演一个辅助角色。那么,提升RAG性能的关键因素是什么呢?其实还是那些不那么炫酷的东西:

数据质量——数据准备——数据处理。

无论是在应用程序运行期间,还是在准备原始数据时,我们都需要对数据进行处理、分类,并从中提取有用的信息,以确保结果朝着正确的方向发展。

如果我们只是坐等越来越大的模型,指望它们能解决所有难题,而不去处理数据和流程,那显然是不现实的。

也许有一天,我们可以把所有乱七八糟的原始数据直接丢给模型,然后神奇地得到有用的结果。但即使到了那一天,从成本和性能的角度来看,这种做法是否合理和适用,仍然值得怀疑。

在深入探讨RAG的高级技术之前,我们先简单回顾一下Naive RAG(最简单的RAG系统),并在此基础上进行扩展。如果你对Naive RAG已经非常熟悉,可以直接跳过这部分。

Naive RAG — 简要回顾

RAG的核心思想是站在巨人的肩膀上,利用现有的概念和技术,并以合适的方式将它们结合起来。很多技术其实都源自搜索引擎领域。我们的目标是围绕LLM构建一个流程,为模型提供正确的数据,帮助它做出决策或总结信息。

下图展示了我们在构建这样一个系统时所使用的一系列技术。

除了 Transformer 模型之外,我们还使用了许多技术,例如:

  • 语义搜索技术
  • 准备和处理文本数据的技术
  • 知识图谱、较小的分类/回归/NLP 模型等。

所有这些技术都已经存在多年了。向量搜索库 FAISS 于 2019 年发布。此外,文本向量化并不是什么新鲜事。

RAG 只是连接这些组件来解决特定的问题。

例如,Bing Search正在将他们的传统“BING”网页搜索与 LLM 的功能相结合。这使得他们的聊天机器人能够回答“真实”生活数据的问题,下面是一个示例问题:

“谷歌今天的股价是多少?”

下图是标准的 RAG 流程,当用户提出问题时,Naive RAG 会直接将用户的问题与我们向量库中的任意内容进行对比。

我们感关心的是寻找与查询问的相似内容。相似内容是在我们的向量空间中彼此接近的内容,距离可以通过计算余弦相似度来测量。

例如问题:

问题:“汤姆·布雷迪踢过什么位置?”

假设我们的矢量数据库中有两个主要数据源:

  1. 汤姆布雷迪的维基百科文章。

  2. 来自烹饪书籍的文章。

在下面的例子中,来自维基百科的内容应该更相关,从而更接近用户的问题。

但“相似”到什么程度才算足够“相似”呢?

我们很难设置一个相似度得分的阈值来明确区分相关和不相关的内容。你可以自己试试,但可能会发现这种方法并不太实用。

找到相关内容了吗?那我们来构建提示吧!

现在,我们已经找到了一些与用户问题相似的内容,接下来需要把它们打包成一个有意义的提示。通常,这个提示至少包含3个部分:

  1. 系统提示:告诉LLM如何回答问题。
  2. 用户问题:用户实际提出的问题。
  3. 上下文:通过相似性搜索找到的相关文档。

一个合适的提示模板可能是这样的:

系统提示中的“…仅使用提供的信息”这部分,实际上是将LLM变成了一个处理和解释信息的工具。在这种情况下,我们并没有直接利用模型自身的知识来回答问题,而是依赖于提供的内容。

你看,就是这么简单。一个向量存储、一个嵌入模型、一个LLM、几行Python代码,再加上一些文档,就能搭建一个基础的原型。

然而,当我们试图扩展这些系统,并将它们从原型转变为真正有效的解决方案时,现实问题就开始出现了。

在这个过程中,我们很可能会遇到各种各样的陷阱,比如:

  • 有价值的内容 vs. 干扰项:虽然最近邻搜索总能找到一些相关内容,但这些内容到底有多相关呢?我们把那些与回答用户问题无关的数据点称为“干扰项”。它们可能会让结果变得混乱,甚至误导模型。
  • 块优化:每个内容片段应该多大,才能既足够具体,又包含足够的上下文?
  • 监控/评估:我们如何在系统运行中监控和评估解决方案的表现?(LLMOps)
  • 代理/多重提示:对于更复杂的查询,我们如何通过多重提示或代理机制来解决,而不是依赖单一提示?

如何应对RAG的潜在陷阱?

正如前面提到的,RAG系统由多个相互交互的组件组成。这为我们提供了多种方法来提升整个系统的性能。

简单来说,我们可以从以下5个流程步骤入手,尝试进行优化:

  1. 预检索:将嵌入数据导入向量存储。
  2. 检索:查找与问题相关的内容。
  3. 后期检索:在将结果发送给LLM之前,对检索到的内容进行预处理。
  4. 生成:利用提供的上下文来解决用户的问题。
  5. 路由:处理请求的整体路由,比如使用代理方法将问题分解,并与模型进行多次交互。

通过在这些步骤中寻找优化点,我们可以更好地应对RAG系统中的潜在问题,从而提升整体性能。如果我们仔细思考RAG流程,就会大致得到下面的图片。

让我们一步一步来看。

首先,我们从最明显、最简单的方法开始——数据质量。对于大多数RAG用例来说,数据通常是文本形式的,比如一些维基文章。

1. 原始数据创建/准备

我们并不总是只能依赖已有的内容。很多时候,我们可以主动影响文档的创建过程。

随着LLM和RAG应用程序的出现,我们突然需要构建自己的知识库。在Naive RAG中,我们会搜索与用户问题有一定相似性的信息片段。

这样一来,模型就看不到整个维基的上下文,而只能看到零散的文本片段。当文档包含以下内容时,问题就出现了:

  • 特定领域甚至特定文档的缩写
  • 链接到维基其他部分的文本段落

如果一个没有背景知识的人都难以理解文本片段的全部含义,那么LLM也会遇到同样的困难。

在本文的后面部分,你会发现一些尝试在检索步骤之后或期间解决这些问题的技术。

在理想情况下,我们根本不需要这些技术。

我们的维基中的每个部分都应该尽可能易于理解,这不仅对人类读者有帮助,也能提升RAG应用程序的性能。这是一个双赢的局面。

以下示例展示了如何通过正确的方式设置内容,让我们的RAG应用程序更轻松地工作。

技巧1:以文本块不言自明的方式准备数据

在下图中,你可以看到一个类似于教程和技术文档中常见的例子。如果我们没有纯粹的LLM或者多模态模型,LLM将很难完全理解左侧版本1中的内容。而版本2至少给了它更好的机会去理解。

RAG流程的下一步是以一种有意义的方式对数据进行分块,将其转换为嵌入(embedding),然后进行索引。

2. 索引/分块——分块优化

Transformer模型有一个固定的输入序列长度,所以我们发送给LLM和Embedding模型的提示(prompt)的token数量是有限制的。不过,在我看来,这其实并不是一个真正的限制。

相反,考虑文本片段和提示的最佳长度是非常有意义的,因为这会对性能产生重大影响,比如:

  • 响应时间(以及成本)
  • 相似性搜索的准确率
  • 等等

有多种文本分割器可以用来对文本进行分块。

技巧2:块优化——滑动窗口、递归结构感知拆分、结构感知拆分、内容感知拆分

块的大小是一个需要仔细考虑的参数——它取决于你使用的嵌入模型及其处理token的能力。标准的Transformer编码器模型(比如基于BERT的句子转换器)最多只能处理512个token,而一些嵌入模型能够处理更长的序列,比如8191个token。

但记住,越大并不总是越好。我宁愿在书中找到包含最关键信息的两句话,也不愿意翻遍五页书去寻找答案。换句话说,分块的目标是找到既能提供足够上下文,又不会过于冗长的平衡点。

这里的核心挑战在于找到一个平衡点:

既要提供足够的上下文供LLM进行推理,又要确保文本嵌入足够具体,以便能够高效地执行搜索。

解决这个块大小选择问题的方法有很多。在LlamaIndex中,NodeParser类就专门处理这个问题,并且提供了一些高级选项,比如自定义文本分割器、添加元数据、定义节点/块之间的关系等等。

最简单的方法是使用滑动窗口来确保所有信息都被正确捕获,而不会遗漏任何部分。具体来说,就是让文本块之间有一定的重叠——就是这么简单!这样一来,每个块都能包含足够的上下文信息,同时也能保持足够的特异性,方便后续的搜索和处理。

除了之前提到的技巧,你还可以尝试其他多种分块技术来优化分块过程。比如:

  • 递归结构感知拆分:这种方法可以根据文档的结构进行递归拆分,确保每个块都保持逻辑上的连贯性。
  • 结构感知拆分(按句子、段落):通过识别句子或段落的边界来进行拆分,确保每个块都是一个完整的语义单元。
  • 内容感知分割(Markdown、LaTeX、HTML):针对特定格式的文档(如Markdown、LaTeX、HTML),可以根据其特有的标记进行分割。
  • 使用NLP进行分块:跟踪主题变化:利用自然语言处理技术,识别文本中的主题变化,从而在主题转换的地方进行分块。

技巧3:提高数据质量——缩写、技术术语、链接

数据清理技术可以帮助你删除不相关的信息,或者将文本部分放入上下文中,使其更易于理解。有时候,如果你了解文章的上下文,长篇文章中的某一段落的意思就会变得非常清晰。但如果缺少上下文,理解起来就会变得困难。

比如:

  • 一个缩写、特定技术术语或公司内部术语可能会让模型难以理解其完整含义。
  • 如果你对篮球一无所知,你可能永远不会将“MJ”与“迈克尔·乔丹”联系起来。
  • 如果你不知道某个句子描述的是供应链环境中的内容,你可能会认为“PO”指的是“邮局”或其他以P和O开头的词组合。

这些例子都说明了上下文的重要性。通过提高数据质量,我们可以让模型更好地理解文本内容,从而提高整体性能。

为了缓解这个问题,我们可以尝试在处理数据时提取必要的附加上下文。比如,使用缩写翻译表将缩写替换为全文。这在处理文本到SQL相关的用例时尤其重要。很多数据库中的字段名称通常都很奇怪,通常只有开发人员和上帝才知道这些字段名称背后的真正含义。

以SAP(企业资源规划解决方案)为例,它经常使用德语单词的缩写形式来标记字段。比如,字段“WERKS”其实是德语单词“Werkstoff”的缩写,用来描述零件的原材料。虽然这对定义数据库结构的团队来说可能很有意义,但对其他人来说,理解这些缩写就相当困难了,包括我们的模型。

技巧4:添加元数据

你可以在所有矢量数据库中向矢量数据添加元数据。这些元数据稍后可以帮助我们在执行矢量搜索之前预先过滤整个矢量数据库。举个例子,假设我们的向量存储中有一半数据是针对欧洲用户的,另一半是针对美国用户的。如果我们知道用户的位置,我们就不想搜索整个数据库,而是希望能够直接搜索相关部分。如果我们将这些信息作为元数据字段添加进去,大多数向量存储都允许我们在执行相似性搜索之前预先过滤数据库。

技巧5:优化索引结构——全搜索与近似最近邻、HNSW 与 IVFPQ

虽然我不认为相似性搜索是大多数RAG系统的弱点——至少从响应时间来看不是——但我还是想提一下。大多数向量数据库中的相似性搜索都非常快,即使我们有数百万个条目,因为它使用了近似最近邻技术,比如FAISS、NMSLIB、ANNOY等。这些技术使得搜索变得非常高效。

如果你的数据量只有几千条,通常没必要搞得太复杂。无论是用 ANN(近似最近邻)还是完整的最近邻搜索,对 RAG 系统的响应时间影响都不会太大。

不过,如果你想构建一个可扩展的系统,那优化速度还是很有必要的。

技巧6:选对嵌入模型
嵌入文本块有很多选择。如果你不确定该用哪个模型,可以参考一些现有的性能基准,比如 MTEB(海量文本嵌入基准),它能帮你评估不同模型的表现。

说到嵌入,还得考虑嵌入的维度。维度越高,能捕捉到的语义信息就越多,但代价是需要更多的存储空间和计算时间。所以,选维度的时候得权衡一下,别一味追求高维度哦!

我们会把所有内容都转换成嵌入(embeddings),然后存到向量数据库里。现在市面上有很多不同厂商提供的模型,选择还挺多的。如果你想看看有哪些模型可以用,可以去瞅瞅langchain.embeddings模块支持的模型列表。在langchain模块的源代码里,你会发现一个超长的列表:

__all__ = [ 
    “OpenAIEmbeddings”,
    “AzureOpenAIEmbeddings”,
    “CacheBackedEmbeddings”,
    “ClarifaiEmbeddings”,
    “CohereEmbeddings”,
   ... 
    “QianfanEmbeddingsEndpoint”,
    “JohnSnowLabsEmbeddings”,
    “VoyageEmbeddings”,
    “BookendEmbeddings”
 ]

3. 检索优化——查询翻译/查询重写/查询扩展

无论是查询扩展、查询重写还是查询翻译,它们的核心目标都是一样的:用 LLM 的力量来优化原始查询,然后再交给向量搜索去处理。

简单来说,就是让 LLM 帮我们把用户的查询“升级”一下,让它更适合搜索。具体怎么做呢?有几种常见的方法:

  • 方法一:用 LLM 生成一些相关的文档或信息,来扩展用户的查询。
  • 方法二:让 LLM 稍微改述用户的查询,然后发送不同的提示给模型,最后整合模型的反馈。

我们先从第一种方法开始聊。

技巧7:用生成的答案进行查询扩展——比如 HyDE
我们可以先让 LLM 生成一个答案,然后再用这个答案去做相似性搜索。举个例子,如果某个问题只能用我们的内部知识来回答,我们可以“诱导”模型生成一个假设性的答案(即使这个答案可能是编的),然后用这个假设答案去搜索相似的内容,而不是直接用用户的原始查询。

这种方法虽然有点“曲线救国”,但效果往往不错!

有几种技术,如 HyDE(假设文档嵌入)、重写-检索-读取、后退提示、Query2Doc、ITER-RETGEN 等。

在 HyDE 中,我们让 LLM 首先在没有上下文的情况下为用户的查询创建答案,然后使用该答案在我们的矢量数据库中搜索相关信息。

与 HyDE 和公司的方法不同,我们可以通过使用多个系统提示来扩展用户的查询。

技巧8:多种系统提示

这个想法其实很简单:我们可以生成 4 个不同的提示,然后得到 4 个不同的回答。

你可以尽情发挥创意,提示之间的差异可以是任何形式的。比如:

  • 如果我们有一篇长文章需要总结,可以用不同的提示去抓取文章的不同方面,最后把这些发现整合成一个完整的答案。
  • 或者,我们可以用 4 个基本相同的提示,上下文也差不多,但系统提示稍微调整一下。这样,我们就能让 LLM 以稍微不同的方式处理问题,或者用不同的风格来表述答案。

总之,灵活调整提示,就能让模型给出更多样化的结果!

这种思路在数据科学里其实很常见。比如在 Boosting 算法中,我们通常会用到一堆简单的模型,每个模型都稍微有点不同,各自做一个小决策。最后,我们再把这些结果整合起来。这种方法效果通常很强。

我们现在做的也是类似的事情,只不过是用模型来整合不同的预测结果。当然,这么做的缺点就是计算时间或者响应时间会变长一些。

技巧9:查询路由

在查询路由(Query Routing)中,我们可以利用 LLM 的决策能力来灵活决定下一步该怎么做。

举个例子,假设我们的向量存储里存了来自不同领域的数据。为了让搜索更有针对性,我们可以先让模型判断一下:应该从哪个数据池里找答案最合适。

比如,下图中的向量存储里就存了来自世界各地的新闻,包括体育和足球、烹饪趋势,还有政治新闻。当用户向聊天机器人提问时,我们肯定不希望把这些数据混在一起。

你想啊,国家之间的体育竞争和政治完全是两码事,不能混为一谈。如果用户想查的是政治新闻,那给他推荐烹饪相关内容显然没啥用,对吧?所以,先让模型帮忙“分个类”,再去找答案,效率会高很多!这样,我们可以显著提高性能。我们还可以让最终用户选择用于回答问题的主题。

技巧10:混合搜索

其实,RAG 管道的检索步骤本质上就是一个搜索引擎。可以说,这是整个 RAG 系统里最关键的部分了。

如果我们想提升相似性搜索的效果,不妨借鉴一下搜索领域的经验。比如,混合搜索就是一个很好的例子。它的思路是同时进行向量搜索和词汇(关键词)搜索,然后把两者的结果结合起来。这样一来,既能捕捉语义上的相似性,又能抓住关键词的精准匹配,效果自然会更好。

在机器学习领域,这种做法其实挺常见的。就是用不同的技术、不同的模型,去预测同一个目标,然后把结果综合起来。背后的思路其实很简单:

一群专家一起想办法,互相妥协,最终得出的结论,通常比单个专家单独做的决定要更好。

说白了,就是“人多力量大”嘛!

4. 检索后:如何改进检索步骤?

上下文丰富——以句子窗口检索为例
通常,我们会尽量把文本块切得小一点,这样更容易找到我们需要的内容,同时也能保证搜索的质量。

但问题是,光看最匹配的那句话可能还不够,有时候它的上下文信息才是帮助我们给出正确答案的关键。

举个例子吧:

假设我们有一堆文本块,内容来自一篇关于德国足球俱乐部拜仁慕尼黑的维基百科文章。虽然我没实际测试过,但我猜第一个文本块的相似度得分可能是最高的。

不过,第二个文本块里的信息可能更重要,我们也不想漏掉它。这时候,上下文丰富就派上用场了!通过把前后相关的句子加进来,我们就能更全面地理解内容,找到真正有用的信息。

丰富上下文的方法有很多,这里我简单介绍两种常用的方式:

  1. 句子窗口检索器
  2. 自动合并检索器

技巧11:句子窗口检索
当我们通过相似度搜索找到得分最高的文本块时,这个块通常是最匹配的内容。但在把它交给 LLM 处理之前,我们会在它的前后各加上 k 个句子。这样做是有道理的,因为相关信息很可能分布在中间文本块的周围,而单独的文本块可能信息不完整,缺乏上下文。

技巧12:自动合并检索器(也叫父文档检索器)
自动合并检索器的思路和句子窗口检索类似,但它的做法不太一样。它会为每个小文本块分配一个特定的“父”块,这个父块不一定是前后相邻的块,而是根据内容相关性来确定的。

你可以根据自己的需求,灵活定义文本块之间的关系。比如,在处理技术文档或法律合同时,经常会发现某些段落或章节引用了文档的其他部分。这时候,挑战就在于如何将这些被引用的部分与当前段落关联起来,从而丰富上下文信息。我们需要能够识别文本中这些引用关系,并把它们整合到一起。

这两种方法都能帮助我们更好地理解和使用文本内容,具体选择哪种方式,可以根据你的实际需求来决定!

我们可以基于这个概念构建一个完整的层次结构,比如决策树。这个结构可以包含不同层级的父节点、子节点和叶节点。举个例子,我们可以设计一个三层结构,每一层都有不同的块大小(参考自 [LlamaIndex, 2024]):

  • 第一层:块大小为 2048
  • 第二层:块大小为 512
  • 第三层:块大小为 128(叶节点)

当我们对数据进行索引并执行相似性搜索时,会从最小的块——也就是叶节点——开始搜索。找到匹配的叶节点后,我们再向上追溯,找到对应的父节点。

检索完成后,我们需要对找到的内容进行解释,并用它来回答用户的查询。这时候,大型语言模型(LLM)就派上用场了。不过,问题来了:哪种模型最适合我们的需求呢?

5. 生成/代理大模型

技巧13:如何挑选合适的大模型和服务商——开源还是闭源?服务还是自托管?小型还是大型?

选对模型可不是件简单的事,得看你的具体需求和流程。

有人可能会说:

直接上最强大的模型不就得了!

但别忘了,更小、更便宜、更快的模型也有它们的独特优势。

比如在RAG流程中,某些环节的精度可能稍低,但响应速度会更快。特别是当我们采用基于代理的方法时,管道中需要频繁做出简单决策,这时候速度和效率就显得尤为重要了。

工具就像是代理的得力助手,确保它总能挑选出最合适的工具来用。

而且呢,如果小一点的模型已经足够应对我们的需求,那就没必要非得用最顶尖的模型不可。这样一来,你不仅能省下一笔运营成本,用户们也会因为系统反应更快而对你赞不绝口。

那么,我们该怎么挑选模型呢?

现在市面上有不少基准测试,可以从各个维度来比较这些大模型。但说到底,最靠谱的办法还是得亲自上手,针对我们的RAG解决方案试一试才知道哪个最合适。

技巧14:代理

代理就像是一个聪明的拼图高手,它把各个组件巧妙地拼接在一起,然后按照既定的规则一步步来。

这个过程中,代理运用了一个叫做“思路推理链”的妙招,这个过程大概是这样循环往复的:

  • 先抛出一个问题,
  • 然后请大模型(LLM)出马,解读收到的答案,
  • 接着根据解读结果,决定下一步怎么走,
  • 最后,再次启动这个过程。

想象一下,有些问题就像一团乱麻,复杂得让人无从下手,因为答案可能散落在各处,没有现成的。这时候,我们人类会怎么做呢?我们会把大问题拆解成一个个小问题,逐个击破,最后拼凑出完整的答案。代理也是这样,它模仿我们的思维方式,一步步逼近真相。

采用基于代理的策略,我们能够大幅提升准确率。当然,天下没有免费的午餐,这种方法需要在计算资源和响应时间上做出一些牺牲,与一次性提示相比,它要求更多的计算力,响应也会稍慢一些。但这一切的代价,换来的是准确率的显著提升。

有趣的是,通过这种策略,我们甚至可以让小巧敏捷的模型在准确率上超越那些庞然大物般的大模型。长远来看,这或许能为你的问题提供一个更优的解决方案。

这完全取决于你的具体需求。当我们开发一个专门用于信息检索的机器人时,我们总是要和搜索引擎的超快响应速度较劲。

速度就是一切。

等上几秒甚至几分钟才能看到结果,真的让人抓狂。

6.评估——评估我们的 RAG 系统

基于 RAG 的系统表现如何,很大程度上取决于两个关键点:一是你喂给它的数据质量,二是大模型从这些数据里提取有用信息的能力。为了让整个系统跑得好,咱们得确保各个组件都能各司其职,协同工作。所以,当我们评估系统时,不仅要看整体表现,还得拆开看看每个组件是不是在好好干活。

和之前一样,我们可以把评估分成两块:检索器(Retriever)生成器(Generator)

对于检索部分,我们可以用一些经典的搜索指标来评估,比如DCG(折损累积增益)和nDCG(归一化折损累积增益)。这些指标主要是看检索到的内容排名靠不靠谱——是不是真正相关的信息被排在了前面。

总结来说,就是检查系统能不能把好东西挑出来,而不是把垃圾推到前面。“理想排名”与真实排名:NDCG 作为评估排名质量的指标

评估模型生成的答案确实是个头疼的问题。

我们该怎么判断一个回答好不好呢?语言这东西本来就挺模糊的,怎么才能给它打个分呢?

最简单的办法就是找一堆人来打分——比如让 1000 个人来评价大模型的回答有没有帮助。这样你就能大概知道它的表现如何了。但说实话,这种方法太不现实了,根本没法长期用。

而且,每次稍微调整一下 RAG 系统,结果可能就不一样了。我知道,想让领域专家来测试你的系统有多难。可能测试一两次还行,但总不能每次改点东西都去找专家吧?

所以,咱们得想个更聪明的办法。其中一个思路就是:不用人,而是用另一个大模型来评估结果——这就是“让大模型当裁判”的方法。这样一来,既省时又省力,还能随时测试,多方便!

技巧15:大模型作为判断模型

生成部分的评估可以用“LLM-as-Judge”的方法来做。这个思路其实挺简单的,分三步走:

  1. 先搞个评估数据集:就是准备一些问题和答案,用来测试模型的表现。
  2. 定义个“裁判代理”:其实就是选一个大模型,让它根据咱们定的标准(比如答案的准确性、专业性啥的)来打分。
  3. 搭个自动化测试流程:让系统根据定义的标准,自动评估大模型的回答,不用每次都手动操作。

第一步:生成综合评估数据集

这个数据集通常包括三部分:(1) 上下文、(2) 问题、(3) 答案。不过,咱们手头不一定有现成的完整数据集。没关系,我们可以自己动手造一个!方法很简单:给大模型提供一段上下文,让它猜猜可能会问什么问题。这样一步步来,就能慢慢构建出一个合成的数据集。

第二步:设置“裁判代理”

这个“裁判代理”其实就是另一个大模型(通常更强大),咱们用它来根据一些标准评估系统的回答。比如:

  • 专业性:答案是不是用专业的语气写的?

举个例子,我们可以这样定义“专业性”的评分标准:

definition=( 
    "专业性指的是使用正式、尊重且适合具体场景和受众的沟通风格。通常要避免太随意的语言、俚语或者口语,而是用清晰、简洁、尊重的表达方式。"
 ), 
grading_prompt=( 
    "专业性评分标准如下:" 
    "- 1 分:语言非常随意,甚至可能带俚语或口语,完全不适合专业场合。" 
    "- 2 分:语言比较随意,但还算尊重人,没有太多俚语。在一些不那么正式的专业场合还能接受。" 
    "- 3 分:语言总体正式,但偶尔会冒出一两个随意的词。算是专业场合的底线了。" 
    "- 4 分:语言平衡,既不太随意也不太正式。适合大多数专业场合。" 
    "- 5 分:语言非常正式、尊重,完全没有随意的成分。适合正式的商务或学术场合。"
 )

第三步:测试 RAG 系统

用刚刚创建的评估数据集来测试系统。对于每个想测试的指标(比如专业性),我们都会定义一个详细的评分标准(比如从 1 到 5 分),然后让“裁判代理”来打分。虽然这不算是一门精确的科学,模型的打分可能会有点波动,但它能帮我们大致了解系统的表现如何。

简单来说,就是让大模型当裁判,给系统的回答打个分,看看它到底靠不靠谱!

我们可以在Prometheus 的提示模板Databricks 的 MLFlow 教程中找到此评分提示的一些示例

技巧16:RAGAs

RAGAs(检索增强生成评估)是一个专门用来评估 RAG 系统各个组件的框架。它的核心思想之一就是“让大模型当裁判”,也就是用大模型来辅助评估。不过,Ragas 的功能可不止这些,它还提供了各种工具和技术,帮助咱们不断优化 RAG 应用。

这里有个关键点叫“组件评估”,Ragas 提供了一些预定义的指标,可以单独评估 RAG 流程的每个环节。比如:

生成部分:

  • 忠诚度:生成的答案到底有多准?是不是跟事实对得上?
  • 答案相关性:生成的答案跟问题搭不搭?是不是答非所问?

检索部分:

  • 上下文精度:检索到的内容里,有用信息和噪音的比例怎么样?
  • 上下文回忆:它能不能把回答问题需要的所有相关信息都找出来?

除此之外,Ragas 还有一些指标是用来评估整个 RAG 流程的效果的,比如:

  • 答案语义相似度:生成的答案和标准答案在意思上有多接近?
  • 答案正确性:答案到底对不对?

总之,Ragas 就像是个“体检工具”,帮咱们把 RAG 系统的每个环节都检查一遍,找出问题,然后对症下药。

技巧17:持续从应用程序和用户收集数据

RAG收集数据可是个关键活儿,它能帮我们看清流程里哪儿有漏洞,然后及时补上。很多时候啊,咱们给系统喂的知识库数据其实并不够好,但光靠我们自己可能发现不了。所以呢,得想点办法,让用户能轻松地给我们反馈,这样我们才能知道问题在哪儿,然后改进。

除了基本数据,我们还可以收集一些更有意思的信息,比如:

  • 每次响应的时间点,以及 RAG 流程中每个步骤花了多长时间(比如矢量化、相似性搜索、大模型生成答案这些环节)
  • 具体用了哪个提示模板
  • 找到了哪些相关文档,文档版本是什么
  • 大模型给出的最终答案
  • ……

这些数据不仅能帮我们分析性能,还能让我们更清楚系统是怎么运作的,挺有意思的吧?

RAG 系统其实是由好几个环节组成的。要想让它跑得更快、更好用,咱们得先搞清楚哪个环节拖了后腿。所以啊,我们得盯着每个环节的表现,这样才能找到问题,让整个系统发挥出最大的潜力。

RAG 流程收集数据

结论

说白了,RAG这事儿还真没啥固定套路可走,得靠咱们一遍遍试错、摸索。就跟搞数据科学的其他项目一样,咱们手头是有不少工具能用,但具体怎么解决,还得看情况来。


53AI,企业落地应用大模型首选服务商

产品:大模型应用平台+智能体定制开发+落地咨询服务

承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

与创始人交个朋友

回到顶部

 
扫码咨询