收录于我的专栏:AI修炼之路
二、RAG概览
RAG研究范式不断演变,可以为三个阶段:原始RAG、进阶RAG和模块化RAG。
2.1 原始RAG
Naive RAG(检索增强生成的初级形式) 是RAG研究的最早期范式,它的研究方法在ChatGPT广泛应用后得到了广泛关注。Naive RAG基于传统的 "检索-阅读"框架 ,由三个主要步骤组成:索引(Indexing) 、检索(Retrieval)和生成(Generation)。
1. Naive RAG的工作流程
a. 索引(Indexing)
- 数据预处理:首先,系统需要处理来自不同格式的原始数据,比如PDF、HTML、Word和Markdown。这些数据会被转换为统一的纯文本格式,以便后续处理。
- 文本分块:由于大语言模型的上下文处理能力有限,文本被分割成更小的、便于处理的片段(chunks)。
- 向量化 :然后,使用嵌入模型(embedding model)将这些文本片段编码成向量表示,并存储在向量数据库中。这一步是为了在检索阶段能有效地进行相似度搜索。
b. 检索(Retrieval)
- 查询向量化:当用户提出一个查询时,RAG系统会使用与索引阶段相同的编码模型,将用户的查询转换为向量表示。
- 相似度计算:然后,系统计算查询向量和索引文本片段向量之间的相似度,优先选择与查询最相似的前K个片段。这些片段作为扩展上下文,提供给生成模型使用。
c. 生成(Generation)
- 构建提示(Prompt):用户的查询和选定的文档片段被组合成一个完整的提示,交给大语言模型生成回答。生成的方式可能因任务的不同而有所调整,模型可以依赖自身的参数知识(LLM本身的训练数据)或者仅依赖检索到的文档片段。
- 多轮对话:在持续对话的情况下,之前的对话历史也可以被纳入提示中,帮助模型进行多轮对话。
2. Naive RAG面临的挑战
尽管Naive RAG在技术上能超越原生LLM的能力,但它仍然存在一些显著的缺点:
a. 检索挑战
- 精度与召回问题 :检索阶段经常面临精度和召回 问题,导致选择到不相关或不准确 的文本片段,而遗漏关键信息。这是由于相似度计算不能始终完美地匹配查询和上下文的相关性。
b. 生成挑战
- 幻觉问题 :生成阶段有时会遇到所谓的幻觉现象,即模型生成了与检索到的上下文不符的内容。这可能会导致输出不相关、有偏见或产生不适当的内容,从而影响生成结果的质量和可靠性。
c. 增强过程的难题
- 信息整合困难 :将检索到的信息与具体任务进行有效整合并不是一件简单的事情。有时系统生成的内容可能不连贯 或缺乏一致性。此外,来自不同来源的相似信息可能会导致冗余,即输出中出现重复内容。
- 重要性判断 :如何确定不同片段的重要性和相关性也是一个复杂的问题。确保内容风格、语气一致性,防止重复信息等,都为生成过程增加了复杂性。
d. 生成模型依赖性
- 过度依赖检索到的信息 :生成模型可能会过度依赖增强的信息,仅仅重复检索到的内容,而不提供更有见地的回答,缺少对信息的深层次总结和整合。
总结:
Naive RAG通过传统的"检索-阅读"框架帮助LLMs克服了一部分知识盲区和信息不足的问题。然而,它在精度、召回率、生成质量、信息整合等方面仍然存在许多挑战。随着技术的进步,高级RAG(Advanced RAG)和模块化RAG(Modular RAG) 被引入,以解决Naive RAG在检索、生成和信息整合中的这些不足。
图2的解读
这张图展示了RAG在问答系统中的一个具体应用场景,并分为三个主要步骤:
1. 索引(Indexing)
在这个步骤中,文档 被处理并转换为向量(vector) 形式。首先,文档内容被分割成更小的块(chunks),这些文本块通过嵌入模型(embeddings)编码为向量,并存储在一个向量数据库中。这一步骤确保了在检索时,系统可以高效地在文档集合中查找与用户问题最相关的文本片段。
2. 检索(Retrieval)
当用户输入问题(如图中的示例问题:关于OpenAI CEO被解雇和重新聘用的事件),RAG系统通过计算语义相似度来检索与问题相关的文档块。系统会优先选择那些与用户问题最相似的前k个文档块(top-k chunks)。在这个图例中,系统找到了三个与问题相关的文档块,如:
- 文档块1:"Sam Altman重返OpenAI担任CEO,硅谷剧情像《甄嬛传》"
- 文档块2:"这场风波结束了吗?Sam Altman将重返OpenAI CEO职位,董事会进行重组"
- 文档块3:"人员动荡结束:谁赢了,谁输了?"
3. 生成(Generation)
在生成阶段,RAG系统将检索到的文档块与用户的原始问题结合,生成一个综合性的提示语句,供大语言模型(LLM)生成最终的答案。生成的答案可以基于所提供的文档片段,也可以结合模型内置的知识。在此示例中,LLM生成了一个基于检索到的信息的答案,解释了OpenAI内部关于公司未来方向的争议和权力斗争的情况。
图中展示了使用RAG前后的对比:
- Without RAG:系统因为没有实时外部知识的补充,无法提供相关的信息。
- With RAG:通过检索相关文档块,系统能够提供一个更全面、更有事实依据的答案。
2.2 进阶RAG
Advanced RAG 是对 Naive RAG 的改进,旨在克服 Naive RAG 中的一些局限性。
1. Advanced RAG的主要改进
-
改进检索质量 :Advanced RAG通过在检索前和检索后的策略优化,解决了Naive RAG在索引和检索阶段遇到的各种问题。
-
索引技术优化:通过引入滑动窗口法、细粒度分割、元数据等技术来增强索引的质量,从而提高检索效率。
-
优化检索过程:Advanced RAG还采用了多种优化技术,使得检索更加高效,减少了不相关信息的干扰。
2. 检索前阶段(Pre-retrieval process)
-
索引结构优化【8】:
- 滑动窗口法(sliding window approach):为了解决索引过程中数据分块的问题,滑动窗口法用于精确分割长文档,从而确保检索时可以得到更加相关的内容。
- 细粒度分割(fine-grained segmentation):通过对文本进行更精细的分割,使得每个片段包含的信息更加精准,从而提高检索效率。
- 元数据整合(metadata):在文档中加入元数据(如日期、主题等),可以更好地帮助系统理解文档的上下文,提高检索质量。
- 混合检索(mixed retrieval):结合不同的检索技术(如语义检索与关键词检索),进一步提升索引的多样性和准确性。
-
查询优化(【7】,【9】-【11】):
- 查询重写(query rewriting):通过重新表达用户的查询,使得问题更加清晰,便于检索系统理解。
- 查询转换和扩展(query transformation and expansion):利用同义词或相关词来扩展查询,确保系统不会遗漏重要的上下文。
3. 检索后阶段(Post-retrieval process)
-
重新排序片段(Reranking Chunks):
- 检索到的相关文档片段需要重新排序,将最相关的片段优先展示,确保生成模型首先处理最关键的信息。这有助于减少噪音信息,提高回答的准确性。
- 相关框架的应用 :例如,LlamaIndex、LangChain 和 HayStack 框架都实现了类似的重新排序机制,帮助将最相关的信息放在提示的前面【12】。
-
上下文压缩(Context Compressing):
- 直接将所有检索到的文档输入LLM可能导致信息过载 ,生成结果中可能包含大量不相关的信息。因此,需要对检索内容进行压缩 和过滤,重点选择最重要的部分。
- 重点提取:将检索到的文档进行筛选,着重强调关键段落,移除多余内容,确保生成模型关注重要的细节。
4. Advanced RAG的改进效果
通过这些检索前和检索后的优化,Advanced RAG 可以有效提升检索的精度和效率,避免了Naive RAG中的一些常见问题,如检索到的内容不相关、信息过载以及生成模型产生幻觉(即生成无根据的信息)。
- 检索精度提升:Advanced RAG通过更好的索引结构和查询优化,能够更精准地找到相关内容。
- 生成质量提升:通过对检索后的信息重新排序和压缩,使得模型生成的回答更加精准、相关。
总结:
Advanced RAG 通过在检索前后的优化策略,解决了 Naive RAG 中的精度问题,并通过细致的索引优化、查询改进和信息压缩,显著提升了信息检索和生成的质量。通过这些改进,Advanced RAG 能更好地处理复杂任务,并生成更加可靠和准确的回答。
2.3 模块化RAG
模块化RAG通过引入新模块和新模式,进一步提升了RAG系统的适应性和灵活性。
1. 新模块(New Modules):
模块化RAG引入了多个专门的组件,以增强检索和处理能力:
- 搜索模块(Search Module):该模块可以适应不同的场景,支持直接从多个数据源进行搜索,比如搜索引擎、数据库和知识图谱。它利用LLM生成的代码和查询语言进行搜索【15】。
- RAG-Fusion:通过采用多查询策略,将用户查询扩展为多样化的视角,利用并行向量搜索和智能重新排序技术,发掘显性和隐性知识【16】。
- 记忆模块(Memory Module):利用LLM的记忆功能来引导检索,创建一个动态的记忆池,通过自我增强机制,使文本与数据分布更好地对齐【17】【18】。
- 路由模块(Routing Module):该模块能够选择不同的数据源进行导航,帮助选择最佳的查询路径(如生成摘要、特定数据库搜索或合并不同信息源)【19】。
- 预测模块(Predict Module):通过直接生成上下文来减少冗余和噪音,确保生成的内容相关性和准确性【13】。
- 任务适配模块(Task Adapter Module):使RAG能够适应不同的下游任务,自动为零样本输入生成提示,并通过少样本查询生成器来创建任务特定的检索器【20】【21】。
这套综合的方法不仅简化了检索过程,还显著提升了信息检索的质量和相关性,能够处理更多任务和查询,并具有更高的精度和灵活性。
2. 新模式(New Patterns):
模块化RAG通过模块替换 或重新配置 解决特定挑战,超越了Naive RAG和Advanced RAG的固定结构(简单的 "检索-阅读" 机制)。此外,模块化RAG通过集成新模块或调整现有模块的交互流程,进一步增强了其在不同任务中的适用性。例如:
- 重写-检索-阅读(Rewrite-Retrieve-Read):该模式利用LLM的能力通过重写模块和反馈机制优化检索查询,提升任务表现【7】。
- 生成-阅读(Generate-Read):在该模式下,传统的检索被LLM生成的内容取代,提升了效率【13】。
- 背诵-阅读(Recite-Read):该模式强调从模型的权重中检索信息,提升了模型在处理知识密集型任务中的能力【22】。
此外,模块化RAG还支持混合检索策略 ,结合关键词、语义和向量搜索来处理多样化的查询需求。它还通过子查询 和假设文档嵌入(HyDE) 来提升检索的相关性,聚焦于生成答案与真实文档的嵌入相似性【11】。
模块的交互和排列调整也是模块化RAG的亮点,例如演示-搜索-预测(DSP) 【23】框架和迭代检索-阅读-检索-阅读(ITER-RETGEN)【14】,这些模式展示了如何动态使用一个模块的输出来增强另一个模块的功能,从而提升系统的整体性能。
模块化RAG的优势
模块化RAG灵活的架构不仅提升了检索和生成的效率,还使得RAG系统更容易与其他技术(如微调或强化学习)集成。例如,系统可以通过微调检索器来获得更好的检索结果,微调生成器来产生个性化的输出,或进行协作微调【26】【27】。
2.4 RAG与微调的比较
1. 三种优化方法的特点比较
文中提到,优化LLMs的常用方法包括RAG 、微调(Fine-tuning, FT) 和提示工程(Prompt Engineering),这三种方法各有特点:
-
提示工程:依赖模型的固有能力,最少依赖外部知识和模型调整。它通过设计有效的提示(prompts)来激发模型的已有能力,不涉及模型内部的修改。
-
RAG:类似于给模型提供了一本定制的教科书,用于精确的信息检索。RAG特别适合需要准确检索外部知识的任务,尤其是在需要及时更新知识的动态环境中。RAG通过实时检索外部数据库的相关内容来增强生成效果。
-
微调(FT):则类似于一个学生通过学习来内化知识,适用于需要复制特定结构、风格或格式的任务。微调需要对模型进行重新训练,以适应特定需求,尽管能够深度定制模型的行为和风格,但每次更新都需要大量的计算资源。
2. RAG与微调的优势与挑战
-
RAG的优势 :RAG在动态环境 中表现优异,可以提供实时的知识更新,并且能够有效利用外部知识资源。RAG的高解释性使其在许多应用场景中成为强有力的工具。然而,RAG面临着较高的延迟问题,并且在数据检索时需要考虑伦理问题,比如隐私和数据安全。
-
微调的优势 :相比之下,微调是静态的 ,即每次更新都需要对模型进行重新训练。微调允许对模型行为和风格进行深度定制,并且在减少模型"幻觉"(即生成不准确的内容)方面表现良好。然而,微调面临的挑战是它在处理不熟悉的数据时可能表现不佳,并且需要大量的计算资源来准备数据集和进行训练。
3. RAG与微调的比较与协同
-
动态性 vs 静态性:RAG在处理动态、实时更新的信息时表现出色,而微调更适合那些需要复制特定结构或风格的静态任务。
-
计算资源需求:RAG虽然更灵活,但会带来更多的延迟,特别是在进行数据检索时。相比之下,微调虽然需要更多的计算资源,但每次模型更新之后,生成的内容更加个性化、定制化。
-
评估表现:多次评估显示,RAG在处理现有知识和全新知识方面的表现通常优于无监督微调。特别是在学习新事实性信息时,LLMs在无监督微调下表现较弱,而RAG能够更好地适应新的知识。
4. 两者的结合
文中强调,RAG与微调并不互斥,相反,它们可以相互补充。在某些情况下,结合使用RAG和微调可能会产生最优的性能表现。例如,RAG可以用于动态知识更新和实时检索,而微调可以用于对模型行为进行深度定制。二者的结合可以弥补各自的不足,达到更加全面的优化效果。
总之,RAG和微调的选择取决于具体应用场景中的需求,包括数据的动态性、定制化要求以及计算资源的能力。两者结合使用时,通过多次迭代优化可以更好地提升模型的能力。
图3的解读
这张图展示了RAG三种不同范式的对比:Naive RAG 、Advanced RAG 和 Modular RAG,并说明了它们的工作流程和模块构成。
1. Naive RAG
最左边的部分是最基础的Naive RAG范式,主要包含三个步骤:
- Indexing(索引):将文档编码成向量,并存储在向量数据库中。
- Retrieval(检索):根据用户的查询,将与查询最相关的文档块检索出来。
- Generation(生成):将检索到的文档块作为提示词,交给一个冻结的LLM(大语言模型)进行回答生成。
这一范式简单且直接,使用"检索-生成"机制,但它可能面临检索精度和生成质量的问题。
2. Advanced RAG
中间部分是Advanced RAG,它在Naive RAG的基础上进行了一些改进,增加了预检索(Pre-Retrieval) 和 后检索(Post-Retrieval) 阶段:
- Pre-Retrieval(预检索):对用户的查询进行优化处理,包括查询路由(Query Routing)、查询重写(Query Rewriting)、查询扩展(Query Expansion)等技术,以便提高检索的精确度。
- Post-Retrieval(后检索):对检索到的结果进行重新排序(Reranking)、摘要生成(Summary)以及结果融合(Fusion),以确保最终用于生成的文档片段最为相关。
这种方法通过对检索结果的前后处理,提高了系统生成的准确性。
3. Modular RAG
右侧是Modular RAG,它进一步提升了系统的灵活性和模块化:
模块(Modules)
- Modular RAG引入了多个模块(Modules),包括检索(Retrieve)、重排(Rerank)、生成(Generate)、记忆(Memory)、预测(Predict)等。这些模块可以根据任务需求灵活替换或重新组合,从而适应不同的应用场景。
- 这种模块化范式支持更多的策略,例如通过子模块的替换或互动调整流程,使得整个RAG框架可以根据任务进行自适应的迭代检索和生成。
模式(Patterns)
图的下半部分展示了不同模式的组合方式,例如:
- 在Naive RAG中,系统简单地执行"检索-阅读"流程。
- Advanced RAG引入了额外的步骤,如"重写-检索-重排-阅读"。
- Modular RAG通过新的模块和流程实现更复杂的交互,比如"展示-搜索-预测"或循环的"检索-阅读"。
图4的解读
这张图比较了不同的模型优化方法(RAG、Prompt Engineering 和 Fine-tuning)在"外部知识需求"和"模型适应需求"两个维度上的表现。
图中的两个维度:
- 外部知识需求(External Knowledge Required):这是纵轴,表示模型在生成答案时是否依赖于外部知识库。依赖外部知识越多,位置越靠上。
- 模型适应需求(Model Adaptation Required):这是横轴,表示模型需要多大的调整或微调。需要的适应或调整越多,位置越靠右。
方法分类:
-
Prompt Engineering(左下方,低外部知识需求,低模型适应需求):
- Standard Prompt:最基本的提示设计,不依赖外部知识,也不需要对模型进行调整。
- Few-shot Prompt:通过提供几个示例来引导模型回答问题,增加了对上下文的需求,但依然不需要外部知识。
- XoT Prompt(例如Chain of Thought, Tree of Thought):引入了一些推理逻辑来帮助模型理解问题,但主要依赖模型自身的能力。
-
RAG(左上方,高外部知识需求,低模型适应需求)
-
RAG 和 Fine-tuning 结合(右上方,高外部知识需求,高模型适应需求)
-
Fine-tuning(右下方,低外部知识需求,高模型适应需求):