前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >实用指南 | 如何提升 RAG Pipeline 效果?

实用指南 | 如何提升 RAG Pipeline 效果?

作者头像
Zilliz RDS
发布2024-07-10 19:18:31
1800
发布2024-07-10 19:18:31
举报
文章被收录于专栏:Reinvent Data Science
01.背景介绍

随着RAG应用逐渐的普及,如何提高RAG应用的回答效果正在被越来越多的人关注。本文列出了各类优化RAG pipeline的方法和对应的图例说明,以帮助你快速了解目前主流的RAG优化策略。

最简单的RAG流程如下图所示,首先将文档块导入到向量数据库(如Milvus, Zilliz cloud)中去,然后通过向量数据库的向量检索功能,检索出top k 个与query相关的文档块。这些relevant chunks然后作为“参考信息”被注入到LLM的context prompt中去进行提问,最后LLM返回最终的回答。

你可以记住这一最简化的流程图,我们在后面的内容里将会介绍各类优化的pipeline版本,你可以与这一基础版本进行比较。

02.增强RAG的各类方法

对于各种各样的RAG增强方法,我们按照它们在RAG pipeline中起作用的位置来归类,可分为下面这些:

  • 查询增强(Query Enhancement):对RAG输入的query部分进行一些变换和操作,使用查询的意图更好地表达或处理。对应Vanilla RAG pipeline图中的第②步。
  • 索引增强(Indexing Enhancement):对块索引的建立时进行一些优化,如分块,分步,多路等建立索引的方式。对应Vanilla RAG pipeline图中的第①步,或者可能包括一些②,③步的合并操作。
  • 检索器增强(Retriever Enhancement):涉及在检索过程中的一些优化技巧和策略。对应Vanilla RAG pipeline图中的第③步。
  • 生成器增强(Generator Enhancement):在组装prompt准备注入到LLM时,为了让LLM有更好的回答,会涉及到一些prompt的调整和优化。对应Vanilla RAG pipeline图中的第④⑤步。
  • RAG pipeline增强(RAG pipeline Enhancement):在整个RAG pipeline中,有一些流程可以是动态变换的,一般会涉及到一些智能体中的agent的思想和tool的使用等技术,来优化整个RAG pipeline中的一些关键步骤。

下面分别介绍这些分类下的具体方法。

查询增强

1.假设性问题

这一方法首先使用LLM为每一条文档块生成一些假设问题,这些文档块可以回答与之对应的假设问题。在RAG阶段,进行一个query-to-query的搜索,先搜索到相关的假设问题,然后找到对应的文档块,再通过它们生成最后的回答。

这里的query-to-query指的是embedding模型的训练方式,训练一个query-to-query模型实际就是训练比较句子的相似性,而不是训练Q-A pair的相似性。所以它是一种对称的“域内(in-domain)”的训练模式,这种方式比不对称的“跨域(out-of-domain)”训练方式会稍微容易且直观一点。

这一方法绕过了在embedding搜索过程中的跨域不对称性,使用query-to-query的直接搜索,减轻了对embedding搜索的要求。但也引入了额外的生成假设问题的开销和不确定性。

额外的开销包括LLM生成假设问题的经济成本,时间成本。不确定性就是和可能的生成的不匹配的问题,或LLM的幻觉导致不懂装懂生成了错误的问题,或系统问题(如LLM网络访问出错)。

2.HyDE

HyDE 这篇论文里提出的方法:首先,LLM创建一个fake answer来响应query。虽然这个answer可能在模式上去query对应,但它包含的信息可能在事实上并不准确。然后query和生成的fake answer都被转换为embedding。最后,系统从vector store中检索在向量空间中最接近这些embedding的实际文档并借助LLM生成回答。

fake answer就是zero-shot llm answer,可能是对的回答,也可能是错误的幻觉回答,这和假设问题是一个意思,假设问题就是zero-shot fake question。

这一方法和假设性问题方法很有点类似,都是缓解了embedding搜索中的跨域不对称性。它们的缺点也很相似,就是会引入额外的生成fake answer的开销和不确定性。

3.子查询

如果查询是复杂的,LLM可以将其分解为几个子查询。例如,

代码语言:javascript
复制
What are the differences in features between Milvus and Zilliz Cloud?

对于这类问题,也许不太可能在语料库中的某些文本中找到直接的比较,于是将这个问题分解为两个子查询:

代码语言:javascript
复制
Sub query1: What are the features of Milvus?
Sub query2: What are the features of Zilliz Cloud?

这些查询将并行执行,然后将检索到的上下文一并提供给LLM综合出对初始查询的最终答案。

子查询一般可以由LLM-based agent来自动判断是否要进行拆分子问题。

4.退后一步提示词

有时候,将一些复杂的问题,抽象为一个“退后一步的问题(Stepback question)”,然后再对其进行回答,会比对原问题进行回答效果更好。比如

代码语言:javascript
复制
Original Question: I have a dataset with 10 billion records, and I want to store it in Milvus for querying. Is it possible?

这个问题不一定容易直接搜索到对应的文档块,使用LLM对其进行后退一步提问,得到

代码语言:javascript
复制
Stepback Question: What is the dataset size limit that Milvus can handle?

使用stepback question进行搜索,更容易得到能回答这个问题的文档块。

这一方法适用于一些相对复杂逻辑的提问,或者是描述非常具体场景的提问。

索引增强

1.自动合并块

在建立索引时,分两个粒度搭建,一个是chunk本身,另一个是chunk所在的parent chunk。先搜索更细粒度的chunks,接着采用一种合并的策略——如果前k个子chunk中超过n个chunk属于同一个parent chunk,那么就将这个parent chunk提供给LLM。

2.分层索引

我们可以对数据创建两层索引:一个是摘要索引,另一个是文档chunk索引。然后分两步进行搜索:首先根据摘要过滤出相关的文档,然后仅在这个文档相关组内进行搜索相应的chunks。

这种方法适用于大量的数据,或者数据的分层结构比较明显的情况,如图书馆藏书内容检索。

3.混合检索,重排序

混合检索是在vector相似性召回的基础上,多增加一路或多路召回,然后将这些从多路召回的结果rerank。这种方法同时使用多种类型的检索方法来提高检索质量,以弥补向量召回偶发的遗漏。

除了vector相似性召回之外,一般采用基于词频的召回算法来作为补充召回,比如BM25等,或一些sparse embedding的模型,如splade等。

Rerank操作可以是一些简单的算法(如RRF)或一些小模型(如Cross-Encoder)。

检索器增强

1.句子窗口检索

这个方案将embedding检索的chunk和提供给LLM的chunk解耦开,通常提供给LLM的chunk是包含embedding检索到的chunk的一个更大的窗口大小。这样可以保证提供给LLM的知识覆盖更多的上下文信息,减少信息遗漏丢失。

当然,这种扩展的窗口大小可能也带来了干扰信息的增多,通常可以根据业务场景需要调整窗口扩展的大小。

2.元数据过滤

使用元数据(如时间、类别等)过滤检索到的文档,以获得更好的结果。比如有检索到了多年的财报信息,根据需要的年份过滤,得到最终需要的信息。

这种方法适用于数据量大且元信息丰富的情况,如图书馆藏书内容检索。

生成器增强

1.压缩提示词

检索到的chunks中的噪声信息会对 RAG 最终的回答产生不利影响,而且LLM的prompt有context length的限制,因此我们可以使用一些技术,压缩不相关的上下文信息,突出关键段落,并减少整体上下文长度,比如可以通过训练一些小的模型来进行压缩。这一思路有点类似于上文提到的rerank然后再过滤掉不相关的文档chunks。

2.调整提示词中知识块顺序

在Lost in the middle这篇论文中,发现LLM在RAG推理时,容易遗漏给定documents中间部分的信息,而更倾向参考排在头和尾的一些documents信息。在Needle in a haystack实验中也有类似的观察。这一观察指导我们,当召回多条知识chunks时,可以把置信度相对低的chunk放在中间,置信度相对高的chunks放在两端,然后这样组成prompt的context,提供给LLM,可以增加LLM对于RAG回答的效果。

RAG pipeline增强

1.自我反馈机制

这一方法运用到了agent里的一个思想,就是self-reflection。如初次召回的top k个chunks中,有一些置信度是有歧义的,那么可以对于这些chunks再做一次reflection,以确认是否可以真正回答这个query问题。Reflection的方法有很多种,比如使用一些模型进行NLI(Natural Language Inference)判断,或者额外使用一些其它工具,比如search the Internet来验证。

2.查询路由

有时回答一些简单的问题并不需要RAG,或者使用了RAG反而带来更多的误解信息干扰。这时可以在query处设置一个agent做为路由,它判断这个query是否需要使用RAG,如果需要,则进行后面的RAG流程,如果不需要,则直接使用LLM回答这个query。Agent可以是一个LLM,或一个小的分类模型,或一些规则等。

这一方法在实际生产中可以使用,它可以通过判断用户意图对query进行路由,从而分流一部分查询,加快回答响应时间,同时减少不必要的干扰信息。

Query routing还有更高级的方式,如判断是否需要使用工具(如网络搜索等),是否进行子查询,是否搜索图片等。总之,这是一种查询的路由思想,具体要如何设计和优化可以灵活处理,以满足业务场景的需求。

总结

普通的RAG流程看似很简单,但实际在业务场景中想要获得较好的效果,就需要更多高级的优化的技巧。

本文对当前常用的RAG增强和优化方法进行了归类和总结,并通过图示进行了说明,希望帮助您快速理解这些具体的概念和方法,以便加快RAG相关应用的实施和优化落地。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-07-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 ZILLIZ 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
向量数据库
腾讯云向量数据库(Tencent Cloud VectorDB)是一款全托管的自研企业级分布式数据库服务,专用于存储、检索、分析多维向量数据。该数据库支持多种索引类型和相似度计算方法,单索引支持千亿级向量规模,可支持百万级 QPS 及毫秒级查询延迟。腾讯云向量数据库不仅能为大模型提供外部知识库,提高大模型回答的准确性,还可广泛应用于推荐系统、自然语言处理等 AI 领域。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档