RAG概述(二):Advanced RAG 高级RAG

目录

概述

Advanced RAG

Pre-Retrieval预检索

优化索引

增强数据粒度

粗粒度

细粒度

展开说说

优化索引

Chunk策略

Small2Big方法

元数据

引入假设性问题

对齐优化

混合检索

查询优化

查询扩展

查询转换

Post-Retrieval后检索

参考


概述

Native RAG(基础RAG)体现了RAG开发范式的骨架,也即三段论Indexing-Retrieval-Generation。

Native RAG的不足是,在LLM这种高度不确定的场景下,还是太粗糙了,最终的表现就是效果不够好。

具体表现:

  1. 准确性低:Retrieval阶段查询到的块,和query本身的相关性低。可能导致LLM出现幻觉或空中掉物等问题。
  2. 召回低:Retrieval阶段查询的块,并没有返回足够多的相关块,进一步降低了LLM构建全面回应的可能性。
  3. 组装prompt的问题:这个阶段会将检索到的块和query融合,构建一个prompt给到LLM。若检索到的多个块中包含了相似或重复的内容,可能导致最终LLM生成内容的冗余和重复,也就是表现的婆婆妈妈。
  4. 灵活性问题:若检索阶段拿到了足够丰富的信息,和query一起构建扔给LLM后,LLM的生成完全基于检索出的内容,并没有增加新生成的内容,变成了复读机。

Advanced RAG的目标是对Native RAG的效果做了进一步优化。

Advanced RAG

Advanced RAG重点聚焦在检索增强,也即优化Retrieval阶段。

增加了Pre-Retrieval预检索和Post-Retrieval后检索阶段。

Pre-Retrieval预检索

本阶段关注的重点是:优化索引结构和原始查询。

优化索引

目标是提高被索引内容的质量。这涉及五种主要策略:增强数据粒度、优化索引结构、添加元数据、对齐优化和混合检索。

增强数据粒度
粗粒度

例如文档分块chunk较大。

理论上粗粒度,能包含更多的相关信息。

但这是一把双刃剑,粗粒度也可能包含了很多无关的内容,而这些无关内容可能会给LLM的generation阶段带来额外的困扰。

细粒度

例如文档分块chunk较小。

细粒度会导致分块很多,给检索阶段增加了压力。

同时细粒度也不能保证能提供完整的语义信息。

旁白:

  • 反正一刀切预制一个chunk大小肯定不行
  • 能不能动态优化?不同doc有不同的chunk?
展开说说

【针对文本数据】数据粒度从细到粗包括:

  1. Token
  2. Phrase 短语
  3. Sentence 句子
  4. Proposition 命题
  5. Chunk 分块
  6. Doc 整个文档

以Proposition命题为检索单元。命题被定义为文本中的原子表达式,每个命题都封装了一个独特的事实片段,并以简洁、自包含的自然语言格式呈现。

这种方法目的是提高检索精度和相关性。

【针对知识图谱Knowledge Graph】,数据粒度从细到粗包括:

  1. Entity 实体
  2. Triplet 三元组
  3. sub-Graph 子图
优化索引
Chunk策略

和数据粒度有一定关联性。

chunk可能导致句子截断,这会损坏语义完整性。

优化:

  • 递归拆分split
  • 滑动窗口
  • 分层检索:在多检索基础上合并全局关联信息

(具体怎么做下回分解)

一个关键点:如何在语义完整性和上下文长度之间取得平衡。

Small2Big方法

使用句子做检索单元(这个是small)

使用前句和后句做上下文(这个是big)

元数据

例如chunk的元数据:

  • 页码
  • 文件名
  • 作者
  • 时间
  • 类别

检索时可通过meta data先过滤,例如检索time range内的chunk,确保是新鲜的信息。

除了从原始文档中自动抽取meta data,也可以人工构建meta data,例如:

  • 添加段落摘要
  • 引入假设性问题
引入假设性问题

例如把doc喂给LLM,让LLM生成这个doc可以回答哪些问题。

在Retrieval时,对比原始query和LLM生成的这些假设性问题,可以用于过滤掉不相关的doc。

对齐优化

例如垂直领域,调优embedding模型,可以将领域内的相似知识嵌入到相近的空间(相比于通用embedding模型)。

混合检索
  1. 向量相似性检索
  2. 文本相似性检索
  3. 知识图谱检索

查询优化

查询优化就是让用户的原始问题更清晰,更适合于检索任务。

常见的方法包括查询改写、查询转换、查询扩展等。

查询扩展

将单个查询扩展为多个查询,丰富查询内容,可提供更丰富的上下文信息。

  1. 让LLM针对原始query生成多个查询
  2. 将复杂问题拆分成多个子问题
查询转换

改写用户的原始query

  1. 让LLM优化原始query
  2. 使用专门的较小的语言模型进行改写
  3. 让LLM先生成原始query的答案,然后将答案作为query,去根据相似性检索(而不是直接用原始query去检索)

Post-Retrieval后检索

重点是有效的融合检索到的相关内容和query。

主要方法包括:

  1. 分块chunk重排序
    1. 将检索到的块里,最相关的块优先级提高
  2. 上下文压缩
    1. 一个是避免prompt超长,超过LLM的窗口限制
    2. 另一个是找到基础信息,强调关键信息,将不相关的内容压缩、精简、淡化

参考

  1. RAG概述(一):RAG架构的演进-CSDN博客
  2. https://arxiv.org/pdf/2312.10997
### Naive RAGAdvanced RAG对比 #### 定义与发展历程 Naive RAG代表早期阶段的检索增强生成(Retrieval-Augmented Generation),其主要特点是简单直接地结合预训练的语言模型和信息检索机制来完成特定任务。随着技术的进步,从Naive RAG进化到了更为先进的形式——即所谓的Agentic RAG,在这一过程中实现了质的变化和发展[^1]。 #### 关键特性比较 - **灵活性** Agentic RAG展示了更高的智能化水平以及更强的任务适应能力,能够更好地应对复杂的查询需求并提供精准的结果反馈;而Naive版本则相对固定模式化操作较多。 - **智能程度** 基于代理的方法被引入到高级别的RAG体系里之后,极大地提高了系统的自主决策能力和环境交互效率,使其不仅仅局限于简单的数据匹配过程,而是可以主动探索最优解路径。 - **应用场景广度** 高级形态下的RAG解决方案由于具备上述优势特征,因此能够在更多领域内找到实用价值,比如自然语言理解、机器翻译等方面均展现出良好的潜力和发展空间。 #### 实现方式差异 对于两种不同层次的RAG架构而言,其实现在技术和算法层面也有着明显的区别: - **基础组件集成** 初级版通常依赖较为传统的搜索引擎作为外部知识源接入手段,并采用固定的编码器结构来进行文档表示学习;相比之下,改进型方案会利用最新的研究成果优化各部分设计,如尝试多种嵌入模型以提高召回率和准确性[^3]。 - **参数规模扩展** 当涉及到更大规模的数据集或更高性能的要求时,现代研究趋势表明增加模型参数量有助于保持甚至提升整体表现力[Wang et al., 2023b][^2]。这意味着在构建高效能的RAG系统时,合理调整内部神经网络尺寸成为了一个不可忽视的因素之一。 ```python # 示例代码片段展示如何定义一个基本的RAG类 class BasicRAG: def __init__(self, encoder_model='bert-base'): self.encoder = Encoder(encoder_model) def retrieve(self, query): # 执行简单的检索逻辑 pass def generate_response(self, retrieved_docs): # 结合检索结果生成回复文本 pass # 对应地,这里给出一个更复杂的Agentic RAG实现概览 from transformers import AutoModelForSeq2SeqLM class AdvancedRAG(BasicRAG): def __init__(self, agent_policy=None, large_encoder='t5-large', *args, **kwargs): super().__init__(*args, **kwargs) self.agent_policy = AgentPolicy(agent_policy) if agent_policy else None self.large_encoder = LargeEncoder(large_encoder) def adaptive_retrieve(self, query_context_pair): # 应用策略指导下的动态检索流程 action = self.agent_policy.decide(query_context_pair) docs = self.retrieve_with_action(action) return docs def enhanced_generate(self, doc_list): # 考虑上下文关联性的响应合成方法 response = "" for doc in doc_list: part_resp = self.generate_based_on(doc) response += f"{part_resp} " return response.strip() ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hugo Lei

赏你了,我的一点心意

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值