构建生产级的 RAG 系统

news2024/11/28 6:53:55

对 RAG 应用程序进行原型设计很容易,但要使其高性能、健壮且可扩展到大型知识语料库却很困难。

本指南包含各种提示和技巧,以提高 RAG 工作流程的性能。我们首先概述一些通用技术 - 它们按照简单到复杂的顺序进行排列。然后,我们将更深入地研究每种技术、该技术解决的用例,以及如何使用 LlamaIndex 实现它!

RAG 系统的终极目标是:优化系统的检索和生成性能,让 LLMs 能够准确回答来自更复杂的数据集的更多 query,而不会产生幻觉。

构建生产级 RAG 系统的通用技术总结

以下是构建生产级 RAG 的一些主要注意事项:

1️⃣ 用于检索的文本块不一定要与用于LLM生成的文本块相同

在信息检索阶段,通常将文档分割成较小的文本块,以提高检索的准确性和效率。然而,在让 LLM 生成回答时,可能需要更大的文本块来提供充分的上下文信息。因此,针对检索和生成过程,应采用不同的文本分块策略,以优化各自的效果。

2️⃣ 嵌入应存在于不同的潜在空间中,而不是直接使用原始文本的嵌入

原始文本可能包含无关的填充词或噪音,直接对其进行 embedding 可能会引入偏差。为了获得更准确的文本表示,可以考虑对文本进行预处理,如去除停用词、提取关键信息,或者对 embedding 模型进行微调,以生成更有意义的 embedding 向量。

3️⃣ 如果检索未能返回正确的上下文,可能需要动态加载或更新数据本身

当检索结果不理想时,问题可能出在数据源本身过时或不完整。此时,动态地加载新数据或更新现有数据可以改善检索效果,确保LLM使用最新且相关的信息来生成回答。

4️⃣ 设计具有可扩展性的处理流程

原型阶段的系统延迟可能较高,这在生产环境中是不可接受的。应从易于使用但延迟较高的模块开始,逐步优化各个组件以降低延迟,提升系统的性能和可扩展性,满足生产级应用的需求。

5️⃣ 以层次化的方式存储数据

为每个文档存储摘要和具体的文本块,可以构建一个层次化的数据结构。这种方法允许在需要快速概览时获取摘要信息,而在需要深入细节时访问具体的文本块,提高了数据检索和处理的效率。

6️⃣ 在生产环境中,健壮的数据管道尤为重要,尤其是当源数据不断变化时

如果数据仅需加载一次,数据管道的稳定性影响较小。然而,当源数据频繁更新时,必须确保数据管道的可靠性和稳定性,以防止数据不一致或系统故障。

7️⃣ RAG不仅适用于问答,还可用于摘要等其他任务;应根据用例调整文本块大小

在生成摘要时,可能需要处理所有相关的文本块以涵盖完整的信息;而在问答场景中,只需检索特定的文本块即可。因此,应根据具体的应用场景和需求,调整文本块的大小和分割方式。

8️⃣ 基于嵌入的检索对实体查找效果不佳;混合搜索可结合关键词查找的优势和额外的上下文

对于查找特定实体(如人名、地名)等精确匹配的需求,纯粹依赖嵌入可能无法获得最佳结果。混合搜索方法将关键词匹配与嵌入检索相结合,既利用了精确匹配的优势,又提供了上下文信息,从而提高了检索效果。

将用于检索的 chunk 与用于 synthesis 的 chunk 分离

更好地检索的关键技术是将用于检索的 chunk 与用于 synthesis 的 chunk 分离。

检索到的质量最好的 chunk 可能与最适合用于 synthesis 的 chunk 不同。例如,原始文本块可能包含 LLM 给定查询的更详细答案所需的详细信息。但是,它可能包含冗余的词或信息,这可能会使 embedding 表示产生偏差,或者它可能缺少全局上下文,并且在相关查询出现时根本无法检索。

解决方案:

1. 嵌入文档摘要,该摘要链接到与文档关联的数据块。

这有助于在检索 chunk 之前整合更多相关的文档,而不是直接检索 chunks(可能在不相关的文档中)。

相关资源:Table Recursive Retrieval、Document Summary Index

2. 嵌入一个句子,然后扩展到句子周围的内容。

这允许更细粒度地检索相关上下文(embedding 巨大的 chunk 会导致 LLM“迷失在长文本中”),但也确保了 LLM 能看到足够长的上下文。

相关资源:Metadata Replacement Postprocessor

大型文档集的结构化检索

标准 RAG 流程(top-k 检索 + 基础的文本拆分)的一个大问题是,随着文档数量的增加,它表现不佳 - 如果您有 100 个不同的 PDF。在这种情况下中,给定一个 query,你可能希望使用结构化信息来帮助进行更精确的检索;例如,如果您提出一个仅与两个 PDF 相关的问题,请使用结构化信息来确保返回的内容来自这两个 PDF。

解决方案:

有几种方法可以为生产质量的 RAG 系统执行更结构化的标记和检索,每种方法都有自己的优点/缺点。

1. 元数据过滤器 + 自动检索:用元数据标记每个文档,然后存储在向量数据库中。在推理期间,使用 LLM 筛选符合条件的元数据,然后再查询向量数据库。

✅ 优点 : 主流向量数据库支持。可以通过多个维度过滤文档。

🚫 缺点 : 可能很难定义正确的标签。标签可能不包含足够的相关信息,无法进行更精确的检索。此外,使用标签进行搜索主要基于关键词匹配,无法理解词语的深层含义或上下文关系,因此无法进行语义层面的查找。

2. 存储文档的层级结构(摘要 -> 原始文本块)+ 递归检索 : 首先嵌入文档摘要,并为每个文档建立一个摘要与分块的映射。在检索时,先在文档级别找到相关内容,然后再深入到更细的文本块层次。

✅ 优点 :支持文档级别的语义查找,通过摘要嵌入,系统可以进行语义匹配,而不仅仅依赖于关键词,从而获得更有深度和关联的搜索结果。

🚫 缺点 : 无法通过结构化标签进行关键词查找(关键词匹配有时能更精准地找到特定信息,而语义查找较为泛化,可能无法替代关键词的精确性);自动生成摘要的成本较高(要为大量文档生成和维护准确的摘要非常耗时、昂贵,尤其在处理大型数据集时更为明显)

根据任务动态检索数据块

RAG(检索增强生成)不仅适用于回答特定事实问题(通常通过 top-k 相似度检索优化),还广泛涵盖了多种查询需求。用户可能提出各种类型的问题,例如关于具体事实的问答(如“这家公司2023年的多元与包容计划是什么?”或“叙述者在Google的经历是什么?”);还可能需要对整个文档进行总结(如“能给我一个这篇文档的高层次概述吗?”),甚至进行比较(如“你能对比X和Y吗?”)。这些不同的查询需求表明,RAG应用不仅仅局限于事实问答,而是扩展到了更多的检索和生成任务。构建 RAG 系统时,为适应多样化的需求,可能需要灵活配置不同的检索和生成方法,以确保在各种场景下都能提供最佳的回答。

解决方案:

LlamaIndex 提供了一些抽象的 core 来帮助完成基于特定任务的检索,包括 router 模块以及 data agent 模块。这还包括一些高级查询引擎模块。这还包括链接结构化和非结构化数据的其他模块。你可以使用这些模块进行联合问答和总结,甚至可以将结构化查询与非结构化查询相结合。

Core Module Resources

  • Query engine
  • Agents
  • Router

Detailed Guide Resources

  • Sub-Question Query Engine
  • Joint QA-Summary
  • Recursive Retriever Agents
  • Router Query Engine
  • OpenAI Agent Cookbook
  • OpenAIAgent Query Planning

优化上下文嵌入

这与上面“Decoupling chunks used for retrieval vs. synthesis” 中描述的动机有关。我们希望确保 embedding 的内容经过优化,以便更好地检索到正确数据语料。基于通用场景预训练的模型可能无法捕获实际应用案例中数据的显著特征。

解决方案:

除了上面列出的一些技术之外,我们还可以尝试微调 embedding 模型。我们可以使用无标签的非结构化文本语料进行微调。

在此处查看相关指南:Embedding Fine-tuning Guide

参考内容:

Building Performant RAG Applications for Production - LlamaIndex

https://www.youtube.com/watch?v=Zj5RCweUHIk

https://x.com/jerryjliu0/status/1692931028963221929?s=20

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

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

相关文章

【移动应用开发】Android持久化技术

目录 一、实现一个“我的图书馆” 1. 用户登陆界面 1.1 运行截图 1.2 源代码 ① 布局文件activity_login.xml ② res/values/strings.xml ③ LoginActivity.kt ④ 在AndroidManifest.xml注册LoginActivity.kt 2. 图书信息数据库和显示界面 2.1 功能实现截图 2.2 源…

二百七十一、Kettle——ClickHouse增量导入数据清洗记录表

一、目的 在完成错误数据表任务后,需要对每条错误数据的错误字段及其字段值进行分析 Hive中原有SQL语句和ClickHouse现有SQL语句很大不同 二、Hive中原有代码 2.1 表结构 --31、静态排队数据清洗记录表 create table if not exists hurys_db.dwd_data_clean_…

kubernetes——part2-3 使用RKE构建企业生产级Kubernetes集群

使用RKE构建企业生产级Kubernetes集群 一、RKE工具介绍 RKE是一款经过CNCF认证的开源Kubernetes发行版,可以在Docker容器内运行。 它通过删除大部分主机依赖项,并为部署、升级和回滚提供一个稳定的路径,从而解决了Kubernetes最常见的安装复杂…

软件测试学习笔记丨Selenium学习笔记:css定位

本文转自测试人社区,原文链接:https://ceshiren.com/t/topic/22511 本文为霍格沃兹测试开发学社的学习经历分享,写出来分享给大家,希望有志同道合的小伙伴可以一起交流技术,一起进步~ 说明:本篇博客基于sel…

【瑞吉外卖】-day01

目录 前言 第一天项目启动 获取资料 创建项目 ​编辑 连接本地数据库 连接数据库 修改用户名和密码 ​编辑创建表 创建启动类来进行测试 导入前端页面 创建项目所需目录 检查登录功能 登录界面 登录成功 登录失败 代码 退出功能 易错点 前言 尝试一下企业级项…

【论文阅读】ESRGAN

学习资料 论文题目:增强型超分辨率生成对抗网络(ESRGAN: Enhanced Super-Resolution Generative Adversarial Networks)论文地址:[1809.00219] ESRGAN:增强型超分辨率生成对抗网络代码:xinntao / ESRGAN&am…

【HarmonyOS】判断应用是否已安装

【HarmonyOS】判断应用是否已安装 前言 在鸿蒙中判断应用是否已安全,只是通过包名是无法判断应用安装与否。在鸿蒙里新增了一种判断应用安装的工具方法,即:canOpenLink。 使用该工具函数的前提是,本应用配置了查询标签querySch…

Linux内核-tmpfs虚拟文件系统

作者介绍:简历上没有一个精通的运维工程师。希望大家多多关注作者,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 我们的Linux进阶部分,到目前为止,已经讲过:硬件,日常运维,基础软…

机器视觉运动控制一体机在DELTA并联机械手视觉上下料应用

市场应用背景 DELTA并联机械手是由三个相同的支链所组成,每个支链包含一个转动关节和一个移动关节,具有结构紧凑、占地面积小、高速高灵活性等特点,可在有限的空间内进行高效的作业,广泛应用于柔性上下料、包装、分拣、装配等需要…

基于SSM+小程序的购物管理系统1

👉文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 基于SSM小程序的购物管理系统1,可以实现首页、个人中心、商品分类管理、商品信息管理、特价商品管理、用户管理、留言板管理、系统管理、订单管理等功能。方便用户对首页、商品…

Redis 事务 总结

前言 相关系列 《Redis & 目录》(持续更新)《Redis & 事务 & 源码》(学习过程/多有漏误/仅作参考/不再更新)《Redis & 事务 & 总结》(学习总结/最新最准/持续更新)《Redis & 事务…

正点原子阿尔法ARM开发板-IMX6ULL(十一)——IIC协议和SPI协议--AP3216C环境光传感器和ICM20608六轴传感器

文章目录 一、前言二、 IIC协议2.1 协议解读2.1.1 起始位、停止位、数据传输2.1.2 写时序2.1.3 读时序 2.2 代码分析2.3 AP3216C环境光传感器的代码分析 三、SPI协议3.1 协议解读3.2 代码分析3.3 ICM-20608六轴传感器代码分析 一、前言 看了IIC,我之前毕设用过这个…

Vmware虚拟机解决摄像头无效,相机失效

问题: 使用vmware虚拟机,打开windows的虚拟机,发现找不到摄像头,打开自带的相机软件报错: 解决方法如下,依次点击vmware状态栏的 虚拟机-可移动设备-chicony integrated camera-连接(断开与主…

MySQL用户权限管理属于SQL语句中的DCL语句

1.用户授权 语法:grant 权限,权限,on 库名,表名 to 用户名 [identified by 密码] MySQL5的版本,如果这个用户事先不存在,这个grant命令去给用户授权的时候,会将用户一起创建出来&#xff0…

已解决 django.db.utils.OperationalError: (1051, “Unknown table

报错信息: django.db.utils.OperationalError: (1051, "Unknown table bjybolg.tool_submission")python manage.py migrate --fake 命令用于告诉 Django 假装已经应用某个迁移,而不实际执行该迁移的操作。这通常在以下情况下非常有用&#x…

Linux shell编程学习笔记87:blkid命令——获取块设备信息

0 引言 在进行系统安全检测时,我们需要收集块设备的信息,这些可以通过blkid命令来获取。 1 blkid命令的安装 blkid命令是基于libblkid库的命令行工具,可以在大多数Linux发行版中使用。 如果你的Linux系统中没有安装blkid命令,…

堆的应用——堆排序和TOP-K问题

1.堆排序 想法⼀&#xff1a; 基于已有数组建堆、取堆顶元素完成排序。也就是利用写好的堆数据结构&#xff08;之前的文章有讲解&#xff09;&#xff0c;去实现排序。 void HeapSort(int* a, int n){HP hp;for(int i 0; i < n; i){HPPush(&hp,a[i]);}int i 0;whi…

HexForge:一款用于扩展安全汇编和十六进制视图的IDA插件

关于HexForge HexForge是一款用于扩展安全汇编和十六进制视图的IDA插件&#xff0c;在该工具的帮助下&#xff0c;广大研究人员可以方便地直接从 IDA Pro 界面数据解码、解密或执行安全数据审计任务。 功能介绍 1、从 IDA 的反汇编或十六进制视图复制原始十六进制&#xff1b;…

00 DSA-- 入门、实现动态数组、实现链表、栈和队列、环形数组、哈希表

两种代码模式 核心代码模式 核心代码模式&#xff1a;就是给你一个函数框架&#xff0c;你需要实现函数逻辑&#xff0c;这种模式一般称之为。 目前大部分刷题平台和技术面试/笔试场景都是核心代码模式。 比如力扣第一题两数之和&#xff0c;就是给出 twoSum 函数的框架如下…

Jmeter压力测试简单教程(包括服务器状态监控)

前段时间公司需要对服务器进行压力测试&#xff0c;包括登录前的页面和登录后的页面&#xff0c;主要目的是测试负载均衡的实现效果。不知道是不是因为Jmeter不如loadRunner火爆还是什么&#xff0c;网上关于Jmeter的资料有很多但是大多千篇一律&#xff0c;要么简单弄个页面测…