RAG 的整个流程可概括为如下图所示,主要分成索引检索生成三个部分。

本文提供配套的完整案例,源码可参考:hedon-ai-road/rag-demo,每个 commit 都引入了一个新的技术点,感兴趣的读者可根据 commit 记录一一查探。

文档解析技术

代码示例

PDF

  • 基于规则的开源库
    • pyPDF2
    • PyMuPDF
    • pdfminer
    • pdfplumber
    • papermage
  • 基于深度学习的开源库
    • Layout-parser
    • PP-StructureV2
    • PDF-Extract-Kit
    • pix2text
    • MinerU
    • marker
    • Gptpdf(基于 LLM API)
  • 商业闭源库
    • Textln.com
    • Doc2x
    • mathpix
    • 庖丁 PDFlux
    • 腾讯云文档识别

分块策略

代码示例

分块演示工具

3 个关键部分组成:

  • 大小
  • 重叠
  • 拆分

固定大小分块(Fixed Size Chunking)

适用场景:

  1. 作为分块策略的基准线;
  2. 对大型数据集进行初步分析;
  3. 实现简单且可观测性高,分块便于管理;
  4. 适用于格式和大小相似的同质数据集,如新闻文章或博客文章。

问题:

  1. 不考虑内容上下文,容易导致无意义的文本块;
  2. 缺乏灵活性,无法适应文本的自然结构

重叠分块(Overlap Chunking)

使用场景:

  1. 需要深入理解语义并保持上下文完整性的文档,如法律文档、技术手册或科研论文;
  2. 提升分块内容的连贯性,以提高分析质量。

问题:

  1. 计算复杂度增加,处理效率降低;
  2. 冗余信息的存储和管理成为负担。

递归分块(Recursive Chunking)

  • 通过预定义的文本分隔符(如换行符 、、句号、逗号、感叹号、空格等)迭代地将文本分解为更小的块,以实现段大小的均匀性和语义完整性。
  • 先按较大的逻辑单元分割,再逐步递归到较小单元,确保在分块大小限制内保留最强的语义片段。

使用场景:

  1. 需要逐层分析的文本文档或需要分解成长片段、长段落的长文档,如研究报告、法律文档等。

问题:

  1. 在块边界处模糊语义,容易将完整的语义单元切分开。

文档特定分块(Document Specific Chunking)

  • 根据文档的格式(如 Markdown、Latex、或编程语言如 Python 等)进行定制化分割的技术。此方法依据文档的特定格式和结构规则,例如 Markdown 的标题、列表项,或 Python 代码中的函数和类定义等,来确定分块边界。

适用场景:

  1. 有特定的文档结构,如编程语言、Markdown、Latex 等结构文档。

问题:

  1. 格式依赖性强,不同格式之间的分块策略不通用;
  2. 无法处理格式不规范及混合多种格式的情况。

语义分块(Semantic Chunking)

  • 基于文本的自然语言边界(如句子、段落或主题中断)进行分段的技术,需要使用 NLP 技术根据语义分词分句,旨在确保每个分块都包含语义连贯的信息单元。

适用场景:

  1. 确保每个文档块的信息完整性且语义连贯;
  2. 提高检索结果的相关性和准确性;
  3. 适用于复杂文档和上下文敏感的精细化分析。

问题:

  1. 需要额外的高计算资源,特别是在处理大型或动态变化的文档数据时;
  2. 处理效率降低。

混合分块(Mix Chunking)

  • 在初始阶段使用固定长度分块快速整理大量文档,而在后续阶段使用语义分块进行更精细的分类和主题提取。根据实际业务场景,设计多种分块策略的混合,能够灵活适应各种需求,提供更强大的分块方案。

适用场景:

  1. 适用于多层次的精细化分块场景;
  2. 数据集动态变化,包含多种文档格式与结构;
  3. 平衡处理速度与准确性的场景。

问题:

  1. 实现复杂度高;
  2. 策略调优难度高;
  3. 资源消耗增加。

Embedding 技术

  • Embedding 嵌入是指将文本、图像、音频、视频等形式的信息映射为高维空间中的密集向量表示。这些向量在语义空间中起到坐标的作用,捕捉对象之间的语义关系和隐含的意义。通过在向量空间中进行计算(例如余弦相似度),可以量化和衡量这些对象之间的语义相似性。
  • 向量检索(Vector Retrieval)是一种基于向量表示的搜索技术,通过计算查询向量与已知文本向量的相似度来识别最相关的文本数据。向量检索的高效性在于,它能在大规模数据集中快速、准确地找到与查询最相关的内容,这得益于向量表示中蕴含的丰富语义信息。

评估指标:(MTEB、C-MTEB)

  1. 特定领域的适用性
  2. 检索精度
  3. 支持的语言
  4. 文本块长度
  5. 模型大小
  6. 检索效率

向量数据库

代码示例

  • 向量数据库是一种专门用于存储和检索多维向量的数据库类型,与传统的基于行列结构的数据库不同,它主要处理高维空间中的数据点。
  • 向量数据库的操作逻辑是基于相似性搜索,即在查询时,应用特定的相似性度量(如余弦相似度、欧几里得距离等)来查找与查询向量最相似的向量。

向量数据库的核心在于其高效的索引和搜索机制。为了优化查询性能,它采用了如哈希、量化和基于图形的多种算法。

  • 层次化可导航小世界(HNSW):通过在多层结构中将相似向量连接在一起,快速缩小搜索范围。
  • 产品量化(PQ):通过压缩高维向量,减少内存占用并加速检索。
  • 位置敏感哈希(LSH):通过哈希函数将相似向量聚集在一起,便于快速定位。

向量数据库的工作流程:

  1. 数据处理与向量化
  2. 向量存储
  3. 向量索引
  4. 向量搜索
    • 余弦相似度:主要用于文本处理和信息检索,关注向量之间的角度,以捕捉语义相似性。
    • 欧几里得距离:测量向量之间的实际距离,适用于密集特征集的聚类或分类。
    • 曼哈顿距离:通过计算笛卡尔坐标中的绝对差值之和,适用于稀疏数据的处理。
  5. 数据检索

混合检索

代码示例

  • 混合检索(Hybrid Search)通过结合关键词检索和语义匹配的优势,可以首先利用关键词检索精确定位到“订单 12345”的信息,然后通过语义匹配扩展与该订单相关的其他上下文或客户操作的信息,例如“12 开头的订单、包装破损严重”等。这样不仅能够获取精确的订单详情,还能获得与之相关的额外有用信息。

重排序技术

代码示例

  • 重排序技术(Reranking)通过对初始检索结果进行重新排序,改善检索结果的相关性,为生成模型提供更优质的上下文,从而提升整体 RAG 系统的效果。
  • 重排序模型大多是基于双塔交叉编码架构的模型,在此基础上进一步计算更精确的相关性分数,能够捕捉查询词与文档块之间更细致的相关性,从而在细节层面上提高检索精度。

提示工程

一个提示(prompt)通常包含以下几个元素:

  1. 指令(Instruction):指明模型要执行的特定任务或操作。
  2. 上下文(Context):为模型提供额外信息或背景,可以帮助引导模型生成更准确的响应。
  3. 输入数据(Input Data):我们希望模型回答的问题或感兴趣的输入内容。
  4. 输出指示符(Output Indicator):指定模型的输出类型或格式,例如格式、是否要生成代码、总结文本或回答具体问题。

核心技巧:

  • 具体指令法:具体、细致地告诉大模型要做什么。
  • 示例学习:给出具体详尽的期望示例。
  • 默认回复策略:设定默认回复策略,避免模型产生“幻觉”,让它不知道就说不知道。
  • 任务角色设定:设定身份,可以帮助模型更好地理解任务要求和角色责任,从而输出更加一致、专业的内容。
  • 解释理由法:向模型解释为什么某些任务需要特定的处理方式,帮助其理解任务背景。
  • 文档基础说明:提供文档的背景信息和文本来源。

优化技术

数据清洗和预处理

在 RAG 索引流程中,文档解析之后、文本块切分之前,进行数据清洗和预处理能够有效减少脏数据和噪声,提升文本的整体质量和信息密度。

通过清除冗余信息、统一格式、处理异常字符等手段,数据清洗和预处理过程确保文档更加规范和高质量,从而提高 RAG 系统的检索效果和信息准确性。

  • 处理冗余的模型内容。
  • 消除文档中的额外空白和格式不一致。
  • 去除无用的文档脚注、页眉页脚、版权信息。

查询扩展

查询扩展策略通过大模型从原始查询语句生成多个语义相关的查询,可以覆盖向量空间中的不同区域,从而提高检索的全面性和准确性。

查询扩展的指令模版:

1
2
3
4
你是一个AI语言模型助手。
你的任务是生成五个不同版本的用户问题,以便从向量数据库中检索相关文档。
通过从多个角度生成用户问题,你的目标是帮助用户克服基于距离的相似性搜索的一些局限性。
请将这些替代问题用换行符分隔。原始问题:{查询原文}

假设问题:

1
下面报告中涉及了哪几个行业的案例以及总结各自面临的挑战?

结果示例:

1
2
3
4
5
请问报告中提到的案例涉及了哪些行业?这些行业各自面临的挑战有哪些?
报告中有哪些行业的案例被讨论?每个行业在报告中描述的挑战是什么?
这个报告中具体提到了哪些行业的案例?能否总结一下这些行业当前面临的主要挑战?
该报告中涵盖了哪些行业案例,并对各行业的挑战进行了哪些讨论?
在报告中提到的行业案例有哪些?这些行业分别遇到的主要问题和挑战是什么?

通过这种查询扩展策略,原始问题被分解为多个子查询,每个子查询独立检索相关文档并生成相应的结果。随后,系统将所有子查询的检索结果进行合并和重新排序,效果会更全面更准确。

自查询

自查询策略通过大语言模型自动提取查询中对业务场景至关重要的元数据字段(如标签、作者 ID、评论数量等关键信息),并将这些信息结合到嵌入检索过程中。

自查询的指令模版:

1
2
3
你是一个AI语言模型助手。  
你的任务是从用户问题中提取关键信息,你的回复应仅包含提取的关键信息。
用户问题:{查询原文}

假设问题:

1
下面报告中涉及了哪几个行业的案例以及总结各自面临的挑战?

结果示例:

1
行业,案例,挑战

提示压缩

提示压缩通过精简上下文、过滤掉不相关的信息,确保系统只处理与查询最相关、最重要的内容。

提示压缩的指令模版:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
你是一个AI语言模型助手,负责对检索到的文档进行上下文压缩。
你的目标是从文档中提取与用户查询高度相关的段落,并删除与查询无关或噪声较大的部分。
你应确保保留所有能够直接回答用户查询的问题核心信息。

输入:
用户查询:{用户的原始查询}
检索到的文档:{检索到的文档内容}

输出要求:
提取与用户查询最相关的段落和信息。
删除所有与查询无关的内容,包括噪声、背景信息或扩展讨论。
压缩后的内容应简洁清晰,直指用户的核心问题。

输出格式:
{压缩段落1}
{压缩段落2}
{压缩段落3}

RAG 效果评估

  1. 大模型打分:通过 LLM 对 RAG 的输出进行自动评分。效率高,但是准确性一般。
  2. 人工打分:手工针对 RAG 的输出进行逐一打分。更精确、细致的反馈,成本高。

评估指标:

  1. CR(Context Relevancy)检索相关性:检索到的信息是否偏离了原始查询。
  2. AR(Answer Relevancy)答案相关性:是否能解决用户的问题,且内容是否逻辑连贯。
  3. F(Faithfulness)可信度:是否存在幻觉或不准确之处。

打分标准:

  1. 完美(Perfect)1.0 分
  2. 可接受(Acceptable)0.75 分
  3. 缺失(Missing)0.5 分
  4. 错误(Incorrect)0.25 分

更高级的 RAG

GraphRAG

GraphRAG 通过构建知识图谱,将实体和实体之间的关系结构化地表示出来,克服了传统 RAG 的复杂推理局限性。

有以下优势:

  1. 提高答案的准确性和完整性
  2. 提高数据理解和迭代效率
  3. 提升可解释性和可追溯性

知识图谱的构建步骤:

  1. 实体识别:从文本或数据源中识别出关键实体。
  2. 关系抽取:确定实体之间的关系,可能通过自然语言处理技术实现。
  3. 三元组生成:将实体和关系表示为 (主体,关系,客体) 的形式。
  4. 图谱存储:使用图数据库或专门的存储系统保存知识图谱。

知识图谱的主要成本挑战:

  1. 数据收集与清洗成本
  2. 知识图谱构建成本
  3. 图谱的维护与更新