6个RAG进阶优化方案,对应论文案例解析

(1)根据问题进行优化

问题意图关键信息提取, 问题细化 : 在检索阶段筛选query表达的真实意图,提取query最相关信息,见Shortwave ; 对比较粗粒度的query拆解成更详细具体的子问题,来提升检索质量, 见RA-ISF

LLM对问题初步回答,提供线索支撑: 对问题先让LLM生成可能回答 ,再将该回到传递给检索器, 检索会比较真实文档和GPT回答内容的差异, 来增加检索内容与问题的相关性, 见HyDE ; 根据问题, 一个负责存储记忆的LLM利用内存和数据库记忆存储, 提供跟问题相关的线索,再让检索器根据线索指导去检索, 见MemoRAG

(2)混合检索

混合向量检索和传统的检索方式,如BM25检索见Standard RAG、全文检索见Shortwave,以及一些更传统的搜索来弥补向量检索的模糊性。

(3)Chunk独立分词导致的缺乏上下文理解

针对Chunk的目前常见优化一是重叠的chunk切割方案;

二是先对整个文档进行总结归纳,基于总结构建一级索引,文档的 Chunk 构建二级索引,检索时先从总结索引中检索。与此有些类似的技术是提示词压缩(Prompt Compression)可以重点压缩不相干的上下文,突出关键段落,减少整体上下文长度。

而其他更灵活的解决方法有:

像GraphRAG, HippoRAG, HybridRAG,GNN,DALK增加知识图谱,解决分词独立编码导致缺少上下文背景, 很难回答需要跨段落总结的问题; RAPTOR则利用知识树让文本对上下文有更多理解;

Anthropic的Standard RAG让Claude先对chunk生成解释性上下文, 让LLM再检索时不仅检索chunk, 也检索这段GPT生成的解释性context,让检索器更好理解这段文本 ;

Late Chunking通过先嵌入再分割让注意力层先学习理解相应内容后再分割, 让LLM理解"它"等代词;

RAPTOR对文本块chunk进行聚类,并生成这些聚类的文本摘要,自下而上地构建出一个结构化的树形模型

这里额外多说一句, Chunk大小和上下文窗口大小的关系:

Chunk 太大时:如果每个 Chunk 包含过多信息,可能会超出大语言模型的上下文窗口大小限制。大部分 LLM 有一个固定的上下文窗口,也就是一次可以处理的最大文本长度。如果 Chunk 太大,模型可能无法一次读取和理解所有信息,这会导致重要的信息丢失或无法进行完整的推理。有时还需要考虑 prompt 占据的长度,为 prompt 留下足够空间

Chunk 太小时:如果每个 Chunk 过小,虽然不会超过上下文窗口的限制,但可能会把本该连在一起的相关信息分割开来。例如,一段话中的上下文信息可能被分成不同的 Chunk,导致模型无法看到完整的信息来做出正确的理解或推理,影响检索的质量,最终降低模型的准确性和效果

因此, 也出现像LongRAG, GLM4 Long这样的项目来扩大检索器, 阅读器和分词单元的长度。

(4)迭代、递归检索

迭代检索允许模型参与多个检索周期,从而增强获得信息的深度和相关性,为 LLM 生成提供更全面的知识库。

这里没必要对迭代和递归做区分 ,我理解的就是迭代, 一般都是设计的迭代

FunSearch在生成提示、模型生成程序、评估、存储的不断循环中保持生成程序总是最好的

EfficientRAG会结合原始查询生成一个新的、更具体的查询,以用于下一轮检索。

递归检索是指可以将之前的检索输出作为后续的检索输入。递归检索通常用于需要渐进式收敛到最终答案的场景 ,比如学术研究、法律案例分析等。针对多级索引(比如摘要索引,Chunk 索引),可以使用递归检索;此外,针对具有图结构的数据源,使用递归检索也可以检索更全面的信息。

(5)自适应检索

RA-ISF的文章相关性模块PRM跟下面介绍的re rank重排序思想类似, 但不需要非得排序, 找不到相关内容可以直接不检索, 让LLM直接回答。像这种需要LLM自己判断是否使用检索内容的, 就是自适应检索

Self RAG也是, 检索到的内容会比较相关性、支持有用性或完整性, 检索到的内容谁最相关 ,最有用, 最完整, 该内容就排在前面, 实在没有相关内容直接不检索, 用LLM训练时学会的内容回答

(6) rerank重排序

传统排序是根据相似度大小排序,排序还可以考虑知识密度, 知识颗粒度, 多样性, LLM对内容的敏感度等考量因素。

OP-RAG也计算了相识度但是按照原文顺序排序;还有更复杂的重排序, 如Shortwave的MiniLM排序还考虑了回答和问题的匹配性, 并且能对索引到的内容进行boost or penalize , Self RAG跟Shortwave类似, 检索到的内容会比较相关性、支持有用性或完整性, 检索到的内容谁最相关 ,最有用, 最完整, 该内容就排在前面。

  • Search Module :这里的 Search 模块专指针对特定应用场景的模块。这种能力可以通过 LLM 的代码能力来获得,比如直接让 LLM 生成对应的 SQL 代码。
  • Memory Module :通常是指存储之前的历史记录,然后在当前的任务中根据 query 的相似性比对等检索历史数据,并辅助当前的生成。Memlong,
  • Routing :用户任务可能比较复杂,此时往往需要多个步骤完成,Routing 模块就是负责任务拆解和分流,比如有多个检索数据源,Routing 负责挑选对应的数据源。
  • Task Adapter :是指将 RAG 适配为特定的下游任务,比如从预先构建好的数据池中检索 zero-shot 任务的输入以扩展 prompt,从而增强任务的通用性。

而针对embedding模型,也可以专门出一个话题,这里只做简要介绍。本文所有内容跟embedding模型有关联的只有Late Chunking技术, 它是jina的向量嵌入模型的机制。

Embedding 优化主要包括:

  • 挑选合适的 embedding 模型 :检索任务通常是判断 两段内容 是否 相关 ,相似任务是判断两段内容是否 相似 ,相关的内容不一定相似。因此随意挑选一个文本模型用于提取 embedding 不一定合适,学习的目标也不一定相同。
  • 针对任务进行微调 :embedding 模型的训练预料和实际检索的语料分布可能并不相同,此时在对应语料上进行 finetuning 可以显著提升检索到的内容的相关性。比如 OpenAI 也提供了代码相关的 code embedding 模型。
  • Adapter :如下图所示,也有研究者引入 Adapter,在提取 query embedding 后进一步让 embedding 经过 Adapter,以便实现与索引更好的对齐。
上一篇:LeetCode 18.四数之和


下一篇:OpenCV基本操作(python开发)——(5)轮廓处理