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

news2024/10/7 6:42:49

目录

概述

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1697783.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Kafka SASL_SSL集群认证

背景 公司需要对kafka环境进行安全验证,目前考虑到的方案有Kerberos和SSL和SASL_SSL,最终考虑到安全和功能的丰富度,我们最终选择了SASL_SSL方案。处于知识积累的角度,记录一下kafka SASL_SSL安装部署的步骤。 机器规划 目前测试环境公搭建了三台kafka主机服务,现在将详…

iOS--锁的学习

iOS--锁的学习 锁的介绍线程安全 锁的分类自旋锁和互斥锁OSSpinLockos_unfair_lockpthread_mutexpthread_mutex的属性 NSLockNSRecursiveLockNSConditionNSConditionLockdispatch_semaphoredispatch_queuesynchronizedatomicpthread_rwlock:读写锁dispatch_barrier_…

react【框架原理详解】JSX 的本质、SyntheticEvent 合成事件机制、组件渲染过程、组件更新过程

JSX 的本质 JSX 代码本身并不是 HTML,也不是 Javascript,在渲染页面前,需先通过解析工具(如babel)解析之后才能在浏览器中运行。 babel官网可查看 JSX 解析后的效果 更早之前,Babel 会把 JSX 转译成一个 R…

Linux 内核

查看内核的发行版 $ uname -r 5.4.0-150-genericcd /lib/modules/5.4.0-150-generic, 内核源码所在的位置:/usr/src 这里的内核源码路径(–kernel-source-path)即为: cd /usr/src/linux-headers-5.4.0-150-generic/ 临时生效: …

自建公式,VBA在Excel中轻松获取反义词

自建公式,VBA在Excel中轻松获取反义词 文章目录 前言一、爬取网站数据二、代码1.创建数据发送及返回方法2.汉字转UTF8编码2.获取反义词 三、运行效果截图 前言 小学语文中,近义词、反义词是必考内容之一。家长不能随时辅导怎么办?有VBA&…

dsPIC单片机buck-boost拓扑双向DC-DC电源变换器设计

为实现电池储能装置的双向DC-DC变换器,本系统以buck-boost拓扑电路为核心,通过DSPICFJ256GP710单片机最小系统控制拓扑的切换,从而进行buck恒流充电和boost恒压放电。充电时效率≥94%,放电时效率≥95.5%,具有过压保护及…

引流500+创业粉,抖音口播工具

在抖音平台运营一个专注于口播的工具号,旨在集结超过500位热衷于创业的粉丝,这需要精心筹划的内容策略和周到的运营计划。首先,明确你的口播工具号所专注的领域,无论是分享创业经验、财务管理技巧还是案例分析,确保你所…

springboot错误

错误总结 1、使用IDEA 的 initialalzer显示2、IDEA 新建文件 没有 java class3、java: 错误: 不支持发行版本 22解决方法4、IDEA-SpringBoot项目yml配置文件不自动提示解决办法 1、使用IDEA 的 initialalzer显示 IDEA创建SpringBoot项目时出现:Initialization fail…

秋招突击——算法——模板题——区间DP(1)——加分二叉树

文章目录 题目描述思路分析实现代码分析总结 题目描述 思路分析 实现代码 不过我的代码写的真的不够简洁&#xff0c;逻辑不够清晰&#xff0c;后续多练练吧。 // 组合数问题 #include <iostream> #include <algorithm>using namespace std;const int N 35; int…

JDBC使用QreryRunner简化SQL查询注意事项

QreryRunner是Dbutils的核心类之一&#xff0c;它显著的简化了SQL查询&#xff0c;并与ResultSetHandler协同工作将使编码量大为减少。 注意事项 1. 使用QreryRunner必须保证实体类的变量名&#xff0c;和sql语句中要查找的字段名必须相同&#xff0c;否则查询 不到数据,会出…

视频号小店去哪里找货源?最全货源渠道分享!

大家好&#xff0c;我是电商糖果 视频号小店因为是这两年电商行业新出来的黑马&#xff0c;吸引着不少商家入驻。 入驻了商家中很多都没有自己的货源渠道。 他们基本都是从无货源开始起步&#xff0c;后期通过积累资源&#xff0c;慢慢搭建属于自己的货源渠道。 可是渐渐的…

FreeRTOS中断中释放信号量

串口接收&#xff1a;中断程序中逆序打印字符串 串口接收&#xff1a;逆序回环实验思路 注&#xff1a;任务优先级较高会自动的切换上下文进行运行 FreeRTOS中的顶半操作和底半操作 顶半操作和底半操作“这种叫法源自与Linux”在嵌入式开发中&#xff0c;为了和Linux操作系统做…

leetcode 1631. 最小体力消耗路径 二分+BFS、并查集、Dijkstra算法

最小体力消耗路径 题目与水位上升的泳池中游泳类似 二分查找BFS 首先&#xff0c;采用二分查找&#xff0c;确定一个体力值&#xff0c;再从左上角&#xff0c;进行BFS&#xff0c;查看能否到达右下角&#xff0c;如果不行&#xff0c;二分查找就往大的数字进行查找&#xff…

终端安全管理系统、天锐DLP(数据泄露防护系统)| 数据透明加密保护,防止外泄!

终端作为企业员工日常办公、数据处理和信息交流的关键工具&#xff0c;承载着企业运营的核心信息资产。一旦终端安全受到威胁&#xff0c;企业的敏感数据将面临泄露风险&#xff0c;业务流程可能遭受中断&#xff0c;甚至整个企业的运营稳定性都会受到严重影响。 因此&#xff…

Java——认识Java

一、介绍 1、起源 Java 是由 Sun Microsystems 于 1995 年推出的一种面向对象的编程语言和计算平台。由詹姆斯高斯林&#xff08;James Gosling&#xff0c;后来被称为Java之父&#xff09;和他的同事们共同研发。后来&#xff0c;Sun 公司被 Oracle&#xff08;甲骨文&#…

【list】list库介绍 + 简化模拟实现

本节博客先对list进行用法介绍&#xff0c;再在库的基础上简化其内容和形式&#xff0c;简单进行模拟实现&#xff0c;有需要借鉴即可。 目录 1.list介绍1.1 list概述1.2相关接口的介绍 2.简化模拟实现3.各部分的细节详述3.1结点3.2迭代器细节1&#xff1a;迭代器用原生指针还是…

【动态规划】斐波那契数列模型(C++)

目录 1137.第N个泰波那契数 解法&#xff08;动态规划&#xff09; 算法流程 1. 状态表⽰&#xff1a; 2. 状态转移⽅程&#xff1a; 3. 初始化&#xff1a; 4. 填表顺序&#xff1a; 5. 返回值&#xff1a; C算法代码 优化&#xff1a; 滚动数组 测试&#xff1a; …

电脑提示请重新安装软件MSVCP140.dll的几种解决方法分享

在日常使用电脑的过程中&#xff0c;我们常常会遇到一些错误提示&#xff0c;其中之一就是找不到msvcp140.dll文件&#xff0c;导致软件无法正常启动运行。这个问题可能是由于缺少相应的依赖库或者版本不匹配引起的。下面我将介绍5种解决方法&#xff0c;帮助大家解决这个问题。…

0524_网络编程8

思维导图&#xff1a;

Java基础的语法---StringBuilder

StringBuilder 构造方法 StringBuilder()&#xff1a;创建一个空的StringBuilder实例。 StringBuilder(String str)&#xff1a;创建一个StringBuilder实例&#xff0c;并将其初始化为指定的字符串内容。 StringBuilder(int a): 创建一个StringBuilder实例…