告别“调包侠”!理解RAGFlow切分原理,是你成为RAG架构师的“第一道坎”!

揭秘RAGFlow文档切分原理

一、引言

书籍文件往往篇幅巨大、结构复杂,不同章节、目录、致谢等混杂在同一文档中。RAGFlow 在处理 book 类文档时,整合了多种解析器(docx、pdf、txt、html、doc),通过自动识别版面结构、过滤非正文、并结合视觉模型生成图片摘要,实现对长文档的精准切分与高质量抽取。本篇将带你逐步拆解源码,了解 RAGFlow 如何优雅地解析一本“书”。

二、省流版

1.核心逻辑

book 模式 面向长篇书籍类文档(docx/pdf/txt/html/doc),通过对不同文件类型自动选择最优解析策略,融合文本语义分块与视觉摘要,实现高质量内容抽取。其目标是:在保持上下文完整性的同时最大限度地过滤无效内容(如目录、致谢页等),为后续知识检索提供干净、结构化的输入。

2.设计亮点

  • 语义级正文过滤:通过正则与上下文规则剔除目录、致谢等非正文部分;
  • 文本块连续性优化:pdf 文档通过_naive_vertical_merge 与 _merge_with_same_bullet 修复 OCR 切分断裂、项目符号分裂等问题。

3.手撕版

书籍的解析支持文件格式为 docx|pdf|txt|html|doc 五种格式。

其中官方建议由于一本书篇幅较长,并非所有部分都有用,如果是 PDF 格式,请为每本书设置页码范围,以消除负面影响并节省计算时间。

if re.search(r"\.docx$", filename, re.IGNORECASE):
...
elif re.search(r"\.pdf$", filename, re.IGNORECASE):
...
elif re.search(r"\.txt$", filename, re.IGNORECASE):
...
elif re.search(r"\.(htm|html)$", filename, re.IGNORECASE):
...
elif re.search(r"\.doc$", filename, re.IGNORECASE):
...

docx

1.1 解析器初始化

docx 的解析器是直接引用的 General 模式下的 docx 解析器,主要对 docx 文档中的段落和表格分别进行处理。详细的 docx 解析器技术拆解可参考General 模式语义切块(docx 篇)》

doc_parser = naive.Docx()

段落和表格处理后的最终输出格式如下:

sections, tbls = doc_parser(
filename, binary=binary, from_page=from_page, to_page=to_page)
'''
# sections
[
(清洗后的文本, 合并后的图片对象, 样式名),
("这是段落文本", PILImage对象, "Normal"),
("这是图注", PILImage对象, "Caption"),
...
]
# tbls
[
((None, "<table>...</table>"), ""),
((None, "<table>...</table>"), ""),
...
]
'''

1.2 目录表格过滤

过滤 docx 文档中的目录表格。

tbls = _remove_docx_toc_tables(tbls)

通过关键字正则判断是否是目录表格,满足其中一条则认为是目录表格。

_TOC_TABLE_KEYWORDS = re.compile(r"(table of contents|目录|目次)", re.IGNORECASE)
_TOC_DOT_PATTERN = re.compile(r"[\.|·]{3,}\s*\d+")

1.3 非正文内容过滤

过滤解析后文本中的非正文内容,例如:目录,致谢等。

remove_contents_table(sections, eng=is_english(
random_choices([t for t, _ in sections], k=200)))

通过关键字正则判断是否是非正文内容。

re.match(r"(contents|目录|目次|table of contents|致谢|acknowledge)$",
re.sub(r"( | |\u3000)+", "", get(i).split("@@")[0], flags=re.IGNORECASE))

1.4 使用视觉模型识别并总结图片摘要

使用 VLM 对文档中的图片进行摘要总结,并以规定格式输出。详细的 vision_figure_parser_docx_wrapper 技术拆解可参考

tbls=vision_figure_parser_docx_wrapper(sections=sections,tbls=tbls,callback=callback,**kwargs)

将包含图片信息的对象数组转换成 figures_data,如以下格式:

(
(figure_data[1], [figure_data[0]]), # 原始图片信息,图片描述信息
[(0, 0, 0, 0, 0)], # 位置信息
)

1.5 移除正文中的图片内容

sections=[(item[0],item[1] if item[1] is not None else "") for item in sections if not isinstance(item[1], Image.Image)]

docx 处理流程结束后输出,sections(正文文本内容)和 tbls(表格内容,图片内容)。

  1. pdf

2.1 布局识别器

与 General 模式下 pdf 文档的处理一样,分为 DeepDOC 和 Plain Text 两种布局识别器。

if parser_config.get("layout_recognize", "DeepDOC") == "Plain Text":
pdf_parser = PlainParser()
else:
pdf_parser = Pdf()

Plain Text 布局识别器实现请参考[下【Plain Text 布局识别器】模块。

2.2 DeepDOC 布局识别器

中相同,Pdf 继承基类 PdfParser。

pdf_parser = Pdf()
class Pdf(PdfParser)

PdfParser 基类的核心功能在《General 模式语义切块(pdf 篇)》中已有详细说明,这里作简要概述:

  • __images__:负责将 PDF 页面数字化,生成可结构化的页面图像数据,为后续的布局分析与表格提取奠定基础。
  • _layouts_rec:基于页面图像与 OCR 文本框信息,执行每页的版面分析与坐标重建。
  • _table_transformer_job:针对识别出的表格区域,提取和解析表格内容,实现表格结构化处理。
  • _text_merge:通过规则合并相邻文本块,解决 OCR 输出中文本碎片化的问题。
  • _concat_downward:按照阅读顺序(Y 坐标从上到下,X 坐标从左到右)对文本框进行排序,恢复自然的文本流。
  • _filter_forpages:检测并过滤非正文页面,如目录页、致谢页等,以提升后续文本分析质量。
  • _extract_table_figure:负责表格与图像的提取与输出,支持跨页表格合并及图像截取。
  • __filterout_scraps:对碎片化文本进行二次清理与组装,进一步优化 OCR 文本的完整性。

2.2.1 Pdf 类

Pdf 类作为入口点,调用 PdfParser 中提供的功能实现整个复杂的文档处理流程,并记录了各阶段耗时,解析进度等信息,这点与 General 模式下的 Pdf 类职能一致,但具体实现内容存在差异。

class Pdf(PdfParser):
def __call__(self, filename, binary=None, from_page=0,
to_page=100000, zoomin=3, callback=None):
# 静态的 pdf 页面转换为可结构化数据
self.__images__(
filename if not binary else binary,
zoomin,
from_page,
to_page,
callback)
# 对文档每页的布局分析,和坐标重建
self._layouts_rec(zoomin)
# 表格数据内容提取
self._table_transformer_job(zoomin)
# 基于规则合并文本
self._text_merge()
# 提取表格,图片内容输出
tbls = self._extract_table_figure(True, zoomin, True, True)
self._naive_vertical_merge()
# 检测并过滤非正文页面
self._filter_forpages()
self._merge_with_same_bullet()
callback(0.8, "Text extraction ({:.2f}s)".format(timer() - start))
return [(b["text"] + self._line_tag(b, zoomin), b.get("layoutno", ""))
for b in self.boxes], tbls

2.2.1.1 _naive_vertical_merge

其中 _naive_vertical_merge 主要目的是将同一列中垂直方向相邻的文本框进行合并。

先过滤无效文本:

1)跨页数字符号过滤:移除跨页的页码、编号等无关文本

if b["page_number"] < b_["page_number"] and re.match(r"[0-9  •一—-]+$", b["text"]):
bxs.pop(i)
continue

2)空文本过滤

if not b["text"].strip():
bxs.pop(i)
continue

再通过文本框布局识别,确认文本布局是否符合合并规则:

3)布局一致性检查:确保合并的文本框属于同一布局区域

if not b["text"].strip() or b.get("layoutno") != b_.get("layoutno"):
i += 1
continue

4)垂直距离阈值检查:防止合并距离过远的文本框

if b_["top"] - b["bottom"] > mh * 1.5:
i += 1
continue

5)水平重叠度检查:确保文本框在水平方向有足够重叠

overlap = max(0, min(b["x1"], b_["x1"]) - max(b["x0"], b_["x0"]))
if overlap / max(1, min(b["x1"] - b["x0"], b_["x1"] - b_["x0"])) < 0.3:
i += 1
continue

最后通过上述筛选的文本框,对其文本语义连续性分析,决定是否需要合并。

# 支持合并的特征(连接性标点)
concatting_feats = [
b["text"].strip()[-1] in ",;:'\",、‘“;:-",
len(b["text"].strip()) > 1 and b["text"].strip()[-2] in ",;:'\",‘“、;:",
b_["text"].strip() and b_["text"].strip()[0] in "。;?!?”)),,、:",
]
# 反对合并的特征
feats = [
b.get("layoutno", 0) != b_.get("layoutno", 0),
b["text"].strip()[-1] in "。?!?",
self.is_english and b["text"].strip()[-1] in ".!?",
b["page_number"] == b_["page_number"] and b_["top"] - b["bottom"] > self.mean_height[b["page_number"] - 1] * 1.5,
b["page_number"] < b_["page_number"] and abs(b["x0"] - b_["x0"]) > self.mean_width[b["page_number"] - 1] * 4,
]
# 强制分离特征
detach_feats = [b["x1"] < b_["x0"], b["x0"] > b_["x1"]]
if (any(feats) and not any(concatting_feats)) or any(detach_feats):
i += 1

2.2.1.2 _merge_with_same_bullet

将具有相同项目符号的连续文本框合并为一个文本块,保持项目符号列表的结构。

pdf 中可能存在以下项目列表, 一个完整的项目符号列表可能被识别为多个独立的文本框,_merge_with_same_bullet 主要是将同一个项目列表内容进行合并。

# 带有项目符号列表示例
• 项目一:产品介绍
• 项目二:技术规格
• 项目三:价格信息

2.3 使用视觉模型识别并总结图片摘要

与 docx 处理一致,需要使用 VLM 对文档中的图片进行摘要总结,并以规定格式输出。

tbls=vision_figure_parser_pdf_wrapper(tbls=tbls,callback=callback,**kwargs)
  1. TXT

与 General 模式下获取 txt 文档方案一致,使用 get_text。如果传入的二进制内容,则使用从 rag.nlp 引入的方式自动推断出正确的编码,进行解码;否则直接从文件路径读取文本进行拼接返回。

txt = get_text(filename, binary)

与 docx 文档处理方案一致,获取文本后过滤文本中的非正文内容,例如:目录,致谢等。

remove_contents_table(sections, eng=is_english(
random_choices([t for t, _ in sections], k=200)))
  1. HTML

与 General 模式下处理 html 文档方案一致,使用 HtmlParser 解析器进行文档解析。详细技术实现可参考

sections = HtmlParser()(filename, binary)

与 docx 文档处理方案一致,获取文本后过滤文本中的非正文内容,例如:目录,致谢等。

remove_contents_table(sections, eng=is_english(
random_choices([t for t, _ in sections], k=200)))
doc_parsed = parser.from_buffer(binary)

与 docx 文档处理方案一致,获取文本后过滤文本中的非正文内容,例如:目录,致谢等。

如何高效转型Al大模型领域?

作为一名在一线互联网行业奋斗多年的老兵,我深知持续学习和进步的重要性,尤其是在复杂且深入的Al大模型开发领域。为什么精准学习如此关键?

  • 系统的技术路线图:帮助你从入门到精通,明确所需掌握的知识点。
  • 高效有序的学习路径:避免无效学习,节省时间,提升效率。
  • 完整的知识体系:建立系统的知识框架,为职业发展打下坚实基础。

AI大模型从业者的核心竞争力

  • 持续学习能力:Al技术日新月异,保持学习是关键。
  • 跨领域思维:Al大模型需要结合业务场景,具备跨领域思考能力的从业者更受欢迎。
  • 解决问题的能力:AI大模型的应用需要解决实际问题,你的编程经验将大放异彩。

以前总有人问我说:老师能不能帮我预测预测将来的风口在哪里?

现在没什么可说了,一定是Al;我们国家已经提出来:算力即国力!

未来已来,大模型在未来必然走向人类的生活中,无论你是前端,后端还是数据分析,都可以在这个领域上来,我还是那句话,在大语言AI模型时代,只要你有想法,你就有结果!只要你愿意去学习,你就能卷动的过别人!

现在,你需要的只是一份清晰的转型计划和一群志同道合的伙伴。作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。

在这里插入图片描述

第一阶段(10天):初阶应用

该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。

  • 大模型 AI 能干什么?
  • 大模型是怎样获得「智能」的?
  • 用好 AI 的核心心法
  • 大模型应用业务架构
  • 大模型应用技术架构
  • 代码示例:向 GPT-3.5 灌入新知识
  • 提示工程的意义和核心思想
  • Prompt 典型构成
  • 指令调优方法论
  • 思维链和思维树
  • Prompt 攻击和防范

第二阶段(30天):高阶应用

该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。

  • 为什么要做 RAG
  • 搭建一个简单的 ChatPDF
  • 检索的基础概念
  • 什么是向量表示(Embeddings)
  • 向量数据库与向量检索
  • 基于向量检索的 RAG
  • 搭建 RAG 系统的扩展知识
  • 混合检索与 RAG-Fusion 简介
  • 向量模型本地部署

第三阶段(30天):模型训练

恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。

到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?

  • 为什么要做 RAG
  • 什么是模型
  • 什么是模型训练
  • 求解器 & 损失函数简介
  • 小实验2:手写一个简单的神经网络并训练它
  • 什么是训练/预训练/微调/轻量化微调
  • Transformer结构简介
  • 轻量化微调
  • 实验数据集的构建

第四阶段(20天):商业闭环

对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。

  • 硬件选型
  • 带你了解全球大模型
  • 使用国产大模型服务
  • 搭建 OpenAI 代理
  • 热身:基于阿里云 PAI 部署 Stable Diffusion
  • 在本地计算机运行大模型
  • 大模型的私有化部署
  • 基于 vLLM 部署大模型
  • 案例:如何优雅地在阿里云私有部署开源大模型
  • 部署一套开源 LLM 项目
  • 内容安全
  • 互联网信息服务算法备案

学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。

如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。

这份完整版的大模型 AI 学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值