RAG学习笔记
从之前的实践来看,结构化解析的效果是明显强于常规的文件内容提取的。相对于常规的文件内容提取,结构化解析保留了文件的层级结构以及各个层级的标题信息,可以有效提升文档内容的召回率。常规 RAG 文件解析方案为了尽可能提升结构化解析能力,常规情况下会选择实现基础文件类型的结构化解析,其他文件尽可能转换为基础文件类型。而目前最常见适用于结构化解析的基础类型为 html 和 markdown。比如目前最常见
数据库构建
数据解析
结构化解析以及常规的文件内容提取
从之前的实践来看,结构化解析的效果是明显强于常规的文件内容提取的。相对于常规的文件内容提取,结构化解析保留了文件的层级结构以及各个层级的标题信息,可以有效提升文档内容的召回率。
常规 RAG 文件解析方案为了尽可能提升结构化解析能力,常规情况下会选择实现基础文件类型的结构化解析,其他文件尽可能转换为基础文件类型。而目前最常见适用于结构化解析的基础类型为 html 和 markdown。比如目前最常见的 pdf 格式,热门开源项目 marker 和 MinerU 都在尝试将其转换为 markdown 格式。(内容来源于RAG最佳实践)
- 常规的文件内容提取: 其目标是尽可能多地、直接地获取文档中的文本内容。通常是“扁平化”处理。所谓”扁平化“,也就是提取所有文本段落,可能忽略格式(加粗、斜体等)、忽略或简化文档的层级结构(标题级别、章节嵌套关系、列表项关系),当然,也可能丢失元信息(标题、作者、表格结构、脚注、超链接文本和关系)。举个例子:把一个 PDF 文件里的文字,不分章节、不分标题、不分列表项,全部按顺序提取出来,变成一个长长的纯文本字符串或段落列表。一个 Word 文档被提取后,所有标题都变成了普通文本段落,失去了层级感。
- 结构化解析: 其目标不仅要获取文本内容,还要保留并理解文档的原始逻辑结构。也就是需要识别并保留标题层级(H1, H2, H3, …)以及它们之间的嵌套关系(哪个小节属于哪个大节)、识别并保留列表结构(有序列表、无序列表、列表项的父子/兄弟关系)、识别并处理表格(表头、行列数据及其对应关系)、识别段落及其所属的章节、保留重要的格式信息(如代码块、引用块)、处理超链接(保留链接文本和链接地址)、结果通常是一个树状结构或带有丰富标签的语义块(如 HTML DOM 树、Markdown 的 AST 抽象语法树、JSON 等)。
- “基础文件类型的结构化解析”
基础文件类型: 如博客中明确提到的,目前最常用、最适合进行高质量结构化解析的文件格式是 HTML 和 Markdown。HTML: 本身就是一种描述结构和语义的标记语言。它天然地使用标签(如<h1>,<h2>,<p>,<ul>,<li>,<table>,<div>)来定义内容的层级、类型和关系。解析 HTML 本质上就是解析其 DOM 树,这是最直接、最成熟的结构化解析方式。Markdown: 是一种轻量级标记语言。它通过特定的符号(如#表示标题,-或*表示列表,>表示引用, 缩进表示代码块/嵌套)来清晰地表达文档的结构和语义。Markdown 文件很容易被解析成结构化的抽象语法树(AST)。
为什么它们是“基础”的?
结构明确: 它们的设计初衷就包含了表达文档结构。
解析成熟: 有大量成熟、稳定、高效的解析库(如 Python 的BeautifulSoup/lxml用于 HTML,markdown-it/mistune/commonmark用于 Markdown)。
通用性强: 解析后的结构化结果(如 HTML DOM 树或 Markdown AST)很容易被后续的 RAG 流程(分块、向量化、检索、提示工程)理解和利用。
转换目标: 如博客所述,很多复杂格式(如 PDF, DOCX, PPTX)的解析策略,就是优先将它们转换成 HTML 或 Markdown 这两种“基础格式”,然后再利用成熟的基础格式解析器进行结构化解析。
为什么大模型无法直接解析PDF?
其实这与问题”为什么PDF难以转换成word文档?“类似,博客PDF转Word为什么这么难中有详细介绍。
现在文档多用PDF格式,是因为PDF跨平台兼容,也就是不管用的是什么操作系统,又或者什么设备,PDF 文件都能保持统一的格式;同时,PDF安全性强,可以设置加密、加水印等。但也因此增加了读取PDF内容的困难程度,如下图所示:
(图片来源于文档布局的多样性)
文档切片
文档切片可以理解为把原始文档按一定规则切成小片段,用于后续的向量化、入库。至于为什么要切块,个人认为,最重要的原因是向量模型的上下文有限制。当然,还有提高召回率以及准确率。
关于文档切片,有将其划分为5个层级的,也有按场景划分的。多是针对通用情况,当然最常用的就是递归切分(需要预先定义好一组有效的分隔符及其优先级顺序)或者滑动切分(我现在最常用的流程就是将PDF解析为Markdown文档(纯文本),这种纯文本情况最适合滑动切分),适用于内容结构不均匀的文本,滑动切分一般切分长度为300左右(并不是切分长度越大越好,冗余信息太多无重点,也会造成模型的幻觉),重叠长度为30左右。
当无法确定分块大小的时候,最佳的方式就是就行A/B测试,但是这需要反复测试,耗时耗力。一般来说选择小的分块大小是最好的选择。
这段时间我还学习了一种切分方式——结构化混合切片法,根据标题、语义段落(文章结构)以及滑窗,这种划分方式可以尽可能的保留语义的完成,也更适合问答RAG。
向量检索
现在的RAG项目中,混合检索(向量检索+BM25)和重排序几乎成了标配。所以想要再度加强RAG的召回率和准确率,就需要从更细节的地方下手。
- 在混合检索中,需要进行加权多路结果融合,这里的权重如何选择?(当然,如果不用多路结果融合,就使用RRF策略)
- 检索的分片长度如何选择?这里需要考虑的是,如果分片长度太短,可能无法包含完整所需的信息,太长又要考虑模型上下文限度以及信息的冗余。所以,这里常有的操作是增加检索返回的文档数或者以小到大(也就是small2big,短句做向量索引,召回后用对应位置的上下文来进大模型prompt)。
检索压缩
检索压缩是为了减少返回文档中的冗余,同时增加大模型的推理速度,EasyRAG 采取的是基于 BM25 的压缩方案,其原理在于,首先将query拆分,然后使用 BM25 计算每个拆分的query与每个句子之间的相似度,最后按照相似度递减的顺序将句子添加到列表中(按原句子相对顺序拼接分数高的句子),直到达到设定的压缩率。
后来又了解到最大边际相关性(Maximum Marginal Relevance, MMR),这解决了标准相似度搜索中的一个常见问题,即排名靠前的文档往往非常相似甚至存在冗余。在LangChain中,MMR是一种检索技术,用于选择不仅与给定查询相关,而且彼此之间具有多样性的文档。这同样也是一种检索压缩,但是这多针对于处理可能有多种解释的模糊查询,或者寻求提高检索信息的整体质量和全面性,而不仅仅是返回最相似的文档。
为武汉地区的开发者提供学习、交流和合作的平台。社区聚集了众多技术爱好者和专业人士,涵盖了多个领域,包括人工智能、大数据、云计算、区块链等。社区定期举办技术分享、培训和活动,为开发者提供更多的学习和交流机会。
更多推荐


所有评论(0)