RAG通过检索现有的大量知识,结合强大的生成模型,为复杂的问答、文本摘要和生成任务带来了全新的解决方案。本文详细的介绍了RAG遇到的挑战、通用范式、工程实践、优化实现策略等。
随着ChatGPT的兴起,大语言模型再次走进人们的视野,其在NLP领域表现出的语言识别、理解以及推理能力令人惊叹。越来越多的行业开始探索大语言模型的应用,比如政务、医疗、交通、导购等行业。
通义系列、GPT系列、LLama系列等模型,在语言交互场景下表现十分抢眼。以Gemini为代表这类大模型甚至发展出了视觉和听觉,朝着智能体的方向演化。他们在多个指标上展现的能力甚至已经超过了人类。
然而,大型语言模型也存在诸多不足:
为了解决纯参数化模型的局限,语言模型可以采取半参数化方法,将非参数化的语料库数据库与参数化模型相结合。这种方法被称为RAG(Retrieval-Augmented Generation)。
RAG通过检索现有的大量知识,结合强大的生成模型,为复杂的问答、文本摘要和生成任务带来了全新的解决方案。然而,尽管RAG有其独特的优势,但在实践过程中也遭遇了多个挑战。
在RAG模型中,检索阶段的输出直接影响到生成阶段的输入和最终的输出质量。如果RAG数据库中存在大量的错误信息并被检索,这可能引导模型走向错误的方向,即使优化检索阶段做大量的工作,可能对结果的影响也微乎其微。
为了实现高效的文档检索,通常需要将原始的文本数据转化为数值向量,这一过程又称为数据向量化。数据向量化的目的是将文本数据映射到一个低维的向量空间中,使得语义相似的文本在向量空间中的距离较近,而语义不相似的文本在向量空间中的距离较远。然而,数据向量化也会导致一定程度的信息损失,因为文本数据的复杂性和多样性很难用有限的向量来完全表达。因此,数据向量化可能会忽略一些文本数据的细节和特征,从而影响文档检索的准确性。
在RAG中,语义搜索是指根据用户的问题,从文档集合中检索出与问题语义最相关的文档,这一过程又称为数据召回。语义搜索的难点在于如何理解用户的问题和文档的语义,以及如何衡量问题和文档之间的语义相似度。目前,语义搜索的主流方法是基于数据向量化的结果,利用向量空间中的距离或相似度来度量语义相似度。然而,这种方法也存在一些局限性,例如向量空间中的距离或相似度并不一定能反映真实的语义相似度,而且向量空间中的噪声和异常值也会干扰语义搜索的结果。因此,语义搜索的准确率也无法有100%的保证。
原始RAG是最早的研究范式,主要包括以下几个步骤:
建立索引:
这一过程通常在离线状态下进行,数据清洗并分块,将分块后的知识通过embedding模型产出语义向量,并创建索引。
检索:
用户的query问题,使用相同的embedding模型,计算问题嵌入和文档块嵌入之间的相似度,选择相似度最高的前K个文档块作为当前问题的增强上下文信息。
生成:
将给定的问题和相关文档合并为新的提示,然后由大型语言模型基于提供的信息回答问题。如果有历史对话信息,也可以合并到提示中,用于多轮对话。
初级RAG主要在三个方面面临挑战:检索质量低、生成质量差和增强过程难。
要解决上面的问题,需要在检索前和检索后做一些优化,这就衍生出了高级RAG的解决方案。
高级RAG相比于初级RAG,基于初级RAG范式,围绕着知识检索做优化,新增了检索前、检索中以及检索后的优化策略,用于解决索引、检索和生成的问题。
检索前优化
检索前优化集中在知识切分、索引方式和query改写的优化上。
知识切分主要把较长的文本按照语义内聚性的分析切成小块,解决核心知识湮没以及语义截断的问题。
索引方式优化技术通过优化数据索引组织方式提升检索效果。比如去除无效数据或插入某些数据来提高索引覆盖程度,从而达到与用户问题的高匹配度问题。
query改写主要需要理解用户想表达的意图,把用户原始的问题转换成适合知识库检索的问题,从而提高检索的精准程度。
检索优化
检索阶段的目标是召回知识库中最相关知识。
通常,检索基于向量搜索,它计算查询与索引数据之间的语义相似性。因此,大多数检索优化技术都围绕嵌入模型展开:
微调嵌入模型,将嵌入模型定制为特定领域的上下文,特别是对于术语不断演化或罕见的领域。例如,BAAI/bge是一个高性能的嵌入模型,可以进行微调。
动态嵌入根据单词的上下文进行调整,而静态嵌入则为每个单词使用单一向量。例如,OpenAI的embeddings-ada-02是一个复杂的动态嵌入模型,可以捕获上下文理解。
除了向量搜索之外,还有其他检索技术,例如混合搜索,通常是指将向量搜索与基于关键字的搜索相结合的概念。如果您的检索需要精确的关键字匹配,则此检索技术非常有益。
检索后优化
对检索到的上下文进行额外处理可以帮助解决一些问题,例如超出上下文窗口限制或引入噪声,从而阻碍对关键信息的关注。在RAG调查中总结的检索后优化技术包括:
提示压缩:通过删除无关内容并突出重要上下文,减少整体提示长度。
重新排序:使用机器学习模型重新计算检索到的上下文的相关性得分。
随着 RAG 技术的进一步发展和演变,新的技术突破了传统的检索 - 生成框架,基于此催生了模块化RAG 的概念。在结构上它更加自由的和灵活,引入了更多的具体功能模块,例如查询搜索引擎、融合多个回答。技术上将检索与微调、强化学习等技术融合。流程上也对 RAG 模块之间进行设计和编排,出现了多种的 RAG 模式。
然而,模块化RAG并不是突然出现的,三个范式之间是继承与发展的关系。Advanced RAG是Modular RAG的一种特例形式,而Naive RAG则是Advanced RAG的一种特例。
3.3.1 新增模块
-
搜索模块:
与相似度检索不同,这部分可以被应用于特定的场景并在一些特殊语料上进行检索。
一般使用向量、分词、NL2SQL或NL2Cypher等能力进行检索。
-
预测模块:
这个技术减少用户问题中的冗余和噪声,更加突出用户真实的意图。
该模块不是直接进行检索,而是利用LLM来生成必要的上下文。
与通过直接检索获得的内容相比,LLM生成上下文后检索得到的内容更有可能包含相关信息。
-
记忆模块:
多轮对话的留存,以便下次会话时,能知道之前用户问了哪些问题。
-
融合模块:
RAG-Fusion使用LLM将用户查询扩展为多个查询。
这个方法不仅捕捉了用户需要的显示信息,也揭示了更深层次的知识。
融合过程包括对原始查询和扩展查询的并行向量搜索,智能重排序,并得到最佳搜索结果。
这种复杂的方法确保了搜索结果与用户的显式和隐含的意图保持紧密一致,从而能找到更深刻和更相关的信息。
-
路由模块:
RAG系统的检索流程使用了各种来源的内容,包含不同领域、语言、形式。
这些内容都可以根据需要进行修改或合并。
查询路由器还为查询选择适当的数据库,其中可能包括各种来源内容,如向量数据库、图数据库或关系数据库,或层次结构索引。
开发者需要预先定义好查询路由器的决策方式,并通过LLM调用执行,它将查询指向所选的索引。
-
任务适配器模块:
根据任务定制化Adapter。
3.3.2 新增模式
基于上面六大模块,可快速组合出属于自己业务的RAG,每个模块高度可扩展,灵活性极大。
比如:
还可以实现基于检索结果和用户评价的奖惩机制,用户强化和纠正检索器的行为。
我们实践的RAG技术架构主要可分为一底座三中心,分别是数据管理底座、模型中心、多引擎中心、召回策略中心。
在工程架构上,每个子系统按照能力划分子Modular,在上层配置调度策略并统一调度,符合Modular RAG的技术规范;
在检索技术上,围绕着检索做了大量的索引降噪、多路召回、知识去重、重排等操作,符合Advanced RAG的技术规范。
4.1.1 知识库基础数据底座
基础数据底座中包含数据生产和数据加工的能力。
数据生产中有数据版本、血缘管理、引擎同步等能力,
知识加工主要包含数据切片、索引优化等能力
4.1.2 模型中心
模型中心主要包含生成式大模型和理解式小模型。
生成式大模型主要提供:
-
引用式生成的能力,通过检索到的知识和用户的问题,做增强生成;
-
query改写能力,理解用户真实意图,并改写或泛化成适合知识库检索的query;
-
Text2Cypher能力,把知识库元数据和用户的问题,转成图谱语言,支撑上层业务的图谱检索;
-
NL2SQL能力,如果业务中有需要访问数据库来获取具体数据的场景,可提供此能力;
理解式小模型主要提供:
-
-
embedding能力,把知识库元数据和用户的问题转成向量;
-
rerank能力,负责把多路召回的数据;
4.1.3 多引擎中心
多引擎中心包含向量、分词以及图谱引擎,在引擎中心提供多种检索方式,以提高知识的命中率。
4.1.4 召回策略中心
召回策略中心在整个RAG建设中起到调度的作用,在这里去执行query改写、多路召回、检索后置处理以及大模型引用式生成答案。
基于上面的一底座两中心架构,每个子能力模块化,并在上层配置调度策略,符合Modular RAG的技术规范。
RAG整体业务链路主要分为5大步骤:知识生产与加工、query改写、数据召回、后置处理以及大模型生产。
4.2.1 第一阶段-可运行
第一阶段保证系统可用。
知识生产与加工
先按照固定字符切分,预留冗余字符来保证语义不被截断。
query改写
结合上下文,先使用大模型的理解能力,突出用户意图,以便更好的回答用户问题。
数据召回
第一步可以先实现向量召回,多路召回中,向量召回的比重是最大的,也是最关键的一种召回方式,需要找一个和自己业务比较契合的embedding模型和向量数据库。
数据后置处理
因为数据召回只有向量召回,这一步可以只使用向量近似得分做排序,设置符合业务预期的阈值筛选数据。并把筛选后的知识数据提供给大模型,生成答案。
4.2.2 第二阶段-提效果
第二阶段的主要目标是提升RAG的检索效果。
知识生产与加工
-
基于固定字符的知识切分,虽然预留了冗余字符,但还是会出现知识内聚性被破坏的现象,此时需要有一个基于语义切分知识的模型,根据语义切分,上下文联系比较紧密的句子拆分成一条知识。
-
根据数据检索的情况,分析索引噪音,指定降噪措施。
query改写
数据召回
数据后置处理
4.2.3 第三阶段-高扩展
第三阶段的主要目标是在工程上提升可扩展性,各个业务功能做模块化设计,通过召回策略配置中心,配置出业务所需要的RAG流程。
5.1.1 知识切片优化
文档片段过长会给知识检索造成很大影响,主要有两部分的问题:
1)索引混淆:核心关键词被湮没在大量的无效信息中,导致建立的索引,核心知识占的比重比较小,无论时语义匹配、分词匹配还是图谱检索,都很难精准命中关键数据,从而影响生成答案的质量;;
2)token过长导致语义会被截断:知识数据在embedding时,可能会因为token超长导致语义截断;知识检索结束后,知识片段越长,输入给大模型的信息条数就越少,导致大模型也无法获取足够的有价值的输入,从而影响生成答案的质量。
5.1.1.1 按固定字符切分
按固定字符拆分知识,通过设置冗余字符来降低句子截断的问题,使一个完整的句子要么在上文,要么在下文,这种方式能尽量避免在句子中间断开的问题。
这种实现方式成本最低,在业务起步阶段,可以先使用这种方式。
5.1.1.2 按句子语义切分
按固定字符切,有时候会遇到句子含义联系比较紧密的片段被切分成了两条数据,导致数据质量比较差。可以通过语义理解小模型进行句子拆分,使拆分出来的知识片段语义更加完整。
5.1.2 索引优化
5.1.2.1 HyDE
原始的文档和用户问题一对一匹配,会存在匹配容错率低的问题,一旦知识一次没匹配上,那就无法被召回。
优化方案
处理后的知识数据,为了提高知识的覆盖范围,可针对知识数据预先用大模型生成一些有关联的假设性问题,当命中这些假设性问题时,也可搜索到相应的知识数据。
5.1.2.2 索引降噪
索引降噪主要根据业务特点,去除索引数据中的无效成分,突出其核心知识,降低噪音的干扰。针对QA-pair对和文章片段的知识,处理起来的方法也类似。
QA-pair对类型知识
这种数据一般会以Q作为索引列,与用户的问题组成QQ搜索模式,这样数据召回时匹配难度会低。如果使用原始的Q做索引,又会存在无效此干扰的问题,比如:
用户query
|
匹配到的query
|
How can I start to sell on Alibaba?
|
How can I register an account on Alibaba.com?
|
句子中,无效的相似成分超过60%,这就会对索引匹配造成很大的干扰。
优化方案
通过大模型泛化向量索引中的Q,突出核心关键词,并且把对应的Answer的主题利用大模型抽取,Q和A都突出关键词。
How can I register an account on Alibaba.com? --> register an account. + Answer主题。
突出核心主题,降低无效数据的干扰。
文章片段类知识
文章片段类知识,由于篇幅长,且在语义上与问题可能差异较大,导致无法很好的匹配。
优化方案
会通过HyDE生成假设性问题,然后组成QA-pair对的形式,然后再利用大模型抽取核心关键词,用来降噪。
5.1.2.3 多级索引
近似检索和传统数据库检索不同,近似检索通过聚类或HNSW建立索引后,在检索时,会有一定的近似误差,如果在大量的知识库中检索,会产生检索准确度和性能的问题,在大型数据库的情况下,一种有效的方法是创建两个索引——一个由摘要组成,另一个由文档块组成,并分两步搜索,首先通过摘要过滤掉相关文档,然后只在这个相关组内搜索。