你还在为 RAG 文档预处理里的“按页分割”纠结吗?尤其是 PDF、PPT 这类格式,页面到底是不是天然的分块单位?我在做知识库项目的时候,经常看到团队为了“该不该按页切”吵起来。有人觉得按页切太粗暴,把一段完整的意思切开,检索结果自然飘;也有人觉得不按页切,PDF 解析出来就是一团乱麻,根本没法用。
先说我的判断:按页分割不是玄学,它是一个有适用边界、有参数语义、有前置条件的设计决策。问题不在于“按页切对不对”,而在于你有没有弄清楚页面边界在你的文档里代表什么语义。这篇文章不绕弯子,直接聊 PDF、PPT 按页分割的适用场景,以及重叠区这个看起来像调参玄学、实际上有明确权衡的环节。
1. 为什么“按页分割”总是第一个被想到的方案
1.1 页面是文档物理边界,不是天然语义边界
RAG 系统最常见的流程是:文档加载、预处理、切片、嵌入、保存向量库、检索、生成。切片是决定检索质量的关键环节,而按页分割几乎是所有 PDF 和 PPT 项目的默认起点。
原因很简单:页面是文档物理存在的最小稳定单位。PDF 有页码,PPT 有幻灯片编号,Word 转成 PDF 后也有固定版式。按页切,至少不会把一行文字拦腰截断,不会让标题和正文错位到离谱,也方便做引用溯源——用户问一个问题,系统返回“见第 8 页”,体验上比返回“来自第 3 个块”自然得多。
但这里的隐含问题是:页面边界通常是排版需要,而不是语义需要。一个 PPT 的标题可能出现在上一页,内容解释却在下一页。一个 PDF 合同条款,经常在上页末尾只写半行,下页开头继续。这就像一本书不是每个句号都恰好落在页底,PDF 分页只是排版引擎为了塞下内容做的换行安排,和“一个完整观点到哪里为止”没太大关系。
1.2 反直觉的真相:按页切不是“粗糙”,而是“锚点”
很多文章会把按页分割说成是入门级方案,好像做 RAG 就必须换成语义切块才算进步。我不同意。
按页分割真正有优势的地方,是它为后续检索提供了稳定的上下文锚点。在做知识库问答时,用户常常需要引用出处,“第几页”是一个跨系统可验证的坐标。相比之下,语义切块虽然看起来保持了内容完整,但如果切得不准,反而会出现“算法认为完整、人看不明白”的情况。
所以我认为,更准确的判断是:按页分割适合“以页为物理容器、且页面内容相对模块化”的文档;不适合“页面逻辑被排版打散严重”的文档。你需要先判断文档类型,而不是简单迷信某一种切法。
1.3 页面级分割能否成为最终切法,取决于三类信息
第一类是文本完整性,看一个页面内是否有跨页段落。第二类是结构信息,看文档是否有明显的标题层级和条目化内容。第三类是检索目标,看用户提问是面向全局概念,还是面向某个章节、某张图表、某个具体条款。
如果三类信息都支持按页切,那按页切就是最稳的方案。如果第二类和第三类出现冲突,就得考虑叠加其他切法,而不是直接放弃。
注意:先把“页面切片”和“语义切块”理解为可以组合的方案,而不是互斥的两派。很多实战项目最终采用的是混合策略。
2. PDF、PPT 按页分割的真实差异比想象中更大
2.1 PDF:版式复杂时,“一页一切”会暴露解析器短板
PDF 是一种“定位式”格式,它记录的是文本、图形对象在页面上的坐标和样式,不直接提供像 HTML 标签那样的语义结构。所以 PDF 解析结果完全依赖解析器能力。
常见的解析器有两类思路。一类是基于文本流的提取,比如从页面内容流里按顺序抽文字;另一类是基于版面的布局分析,比如先识别页面上的标题、正文、表格、图片区域,再按阅读顺序重组。
如果 PDF 是 Word 导出的数字版,没有太多复杂图文混排,按页分割通常问题不大。但一旦遇到多栏排版、表格跨页、页眉页脚、图文混排的 PPT 导出 PDF,问题就会爆发:跨页表格被切成两半,页眉页脚混入正文,图表被解析成乱码,文字顺序颠倒。
这时的“一页一切”不是分割策略的问题,而是上游解析质量问题。必须先解决 PDF 解析,再做页面切片。否则每个页面块里塞的都是错序文本,检索结果自然飘。
2.2 PPT:天然适合按页切,但也有隐藏前提
PPT 是所有办公文档里最适合按页分割的类型。原因很明显:PPT 的基本单位就是幻灯片,一个页面通常包含一个小主题,标题、要点、图示都集中在同一页,语义完整性往往很好。
但是“天然适合”不等于“天然能切好”。PPT 文件里的文字并不是一个有序文本流,而是多个文本框、形状、图表的组合。直接抽文本,可能把标题和正文拆散,甚至把页脚、评论、演讲者备注都混进来。
我用 python-pptx 或 LibreOffice 转换做 PPT 文本提取时,通常的做法是先按幻灯片遍历所有 shape,再从 shape 里取 text_frame 的文字,最后拼成一个按阅读顺序排列的块。这个顺序并不总是和视觉位置一致,所以需要人工检查样例。更麻烦的是,PPT 里很多信息是图片化的,比如架构图、截图、公式,这时候按页切得到的是“无文本页”或“少量文字页”,对 RAG 来说基本不可用。
所以 PPT 按页分割的正确姿势是:先按页提取文本,并保留页码、标题、形状描述等元数据;再判断这一页是否有可检索文本;最后决定是否对页面内的小块进行二次切分。只做第一层,后面会遇到大量“页面块但无内容”的问题。
2.3 Word、TXT 和政务知识库场景中的“伪分页”
TXT 和 Markdown 这类纯文本文件根本没有“页”的概念。按页分割对它们来说没有直接入口,只能按段落、标题层级或字数进行切分。
政务场景中很多红头文件、制度文件,本来是用 Word 排版,最终发布成 PDF。这些文档里真正重要的语义单元是“条”“款”“项”,不是页面。如果只按页切,最典型的问题是:一个制度条款前半部分在第 2 页,后半部分在第 3 页,检索时两头都搜不全。
在 Dify 这类平台上做政务 RAG 知识库时,很多团队会先做章节识别。常见做法是先把 PDF 转成带大纲的文本流,再用标题模式或目录结构把文档切成章节块。如果文档没有目录,就退回到“页级块优先、再在页内找条款边界”的思路。
3. 用参数而不是感觉设计“重叠区”
3.1 重叠区到底在解决什么问题
重叠区(overlap)的概念很简单:相邻两个块之间保留一段重复文本。假如一个块是 500 字,重叠 100 字,那第 1 块会包含原文第 1 到 500 字,第 2 块包含第 401 到 900 字。
为什么需要重叠区?因为用户提问可能恰好覆盖两个块的边界。比如一个制度的“审批流程说明”跨了三个自然段,按页切或按段落切后,第一段在块 A,后两段在块 B。用户问“审批流程是什么”,检索器可能只召回块 A,遗漏后半段关键条件。
重叠区的本质是用冗余换召回。代价是明显的:向量库存储变大,检索结果里会出现重复文本,最终生成阶段也可能把同一信息重复说两遍。所以重叠区不是越大越好,也不是固定值。
3.2 一个最小可运行的页面切片设计流程
我不建议一上来就调参。最好的方式是先做一个“能跑通”的版本,再根据偶发检索失败案例调整。
第一步,先选择解析工具并输出结构化文本。对 PDF,可以先尝试做布局分析,尽量把页眉页脚去掉;对 PPT,按幻灯片提取文本框。
第二步,给每个页面做元数据标注。至少要有文档 ID、页码、标题、文档类型、提取时间。如果你用的后端支持,可以把页面标题作为检索返回字段。
第三步,决定块的基本大小。按页切时,如果你发现某页文字特别长,可以再对该页做段落级切分;如果页很短,可以保留单页,不强行拼接。
第四步,设置重叠区。刚开始建议保守一点,比如每页如果超过 800 字,就叠 100 字左右;如果页面平均字数在 300 字以内,可以不用重叠。原因是 PPT 页面块通常已经足够语义完整,重叠反而让检索命中多个重复块,引入噪声。
第五步,验证 20 条真实问题,不要只看测试集成绩。把每条问题的检索结果和生成结果,与原文做一次对照,确定是否有“关键句漏召回”。
示例切分伪代码如下:
def split_document_by_page(pages, overlap_chars=100): chunks = [] for page in pages: text = clean_page_text(page.text) if len(text) <= 0: continue if overlap_chars and len(text) > overlap_chars * 2: chunks.extend(split_long_page(text, overlap_chars)) else: chunks.append({ "text": text, "page": page.number, "doc_id": page.doc_id, "title": page.title, }) return chunks这个伪代码不强依赖具体框架,你可以映射到 LangChain 的 RecursiveCharacterTextSplitter,或者 Dify 里的分段配置。关键是保留页面元数据,而不是只存一个文本字段。
3.3 先确定块的大小,再调重叠区
现在很多 RAG 框架里,默认切分参数经常是 500 字、重叠 50 字。这不是放之四海皆准的数字,只是适合英文中等密度文本的默认值。
中文文档的信息密度更高,相同字数包含的语义量更多。所以中文知识库的块大小可能要更小一些,比如 300 到 600 字之间。PPT 按页切时,块的文本量完全取决于一页有多少字,可能 50 字,也可能 800 字。
我的调整顺序是:先看块大小是不是匹配文档语义单元,再调重叠区。如果逐页文本平均 300 字,但语义单元是“一个完整的审批条款”,那就该做页内条款切分,而不是调重叠。如果块大小没问题,只是偶尔出现边界断句,才需要增加重叠区。
这里很容易踩坑的点是:重叠区设置得过大会让检索出现大量同质结果。嵌入模型会把相邻块映射到相近向量位置,一个 query 命中三个互相重叠的块,最后生成阶段可能反复引用同一段内容,看似有多个证据,其实只有一个信息源。
3.4 不要忽略元数据这个“隐藏重叠区”
真正的重叠不只是文本字符重叠,还有元数据重叠。如果你把每个页面都打上文档标题和章节路径,检索时这些上下文会跟着一起嵌入或展示。这在任务中相当于给每个块增加了一个稳定锚点,比纯字符重叠有效得多。
比如一个 Dify 政务项目里,文档是“某市预算管理办法”,每一块都会带上“第 X 章”元数据。用户问“预算调整需要什么程序”,系统不仅能命中正文,还能通过章节目录把上下文限定到“预算执行与调整”这个章节,提升召回准确率。这是比调 overlap 更重要的工程设计。
4. 正确适用场景与不适用的场景
4.1 按页分割适合哪类文档
按页分割最适合的文档,我总结为三类。
第一类:页面信息模块化强的演示文稿。PPT 基本上一页一个主题,按页切往往就是按主题切,语义完整性很好。
第二类:有强页码溯源需求的制度、法律、规范和合同类 PDF。用户需要明确知道答案来自哪一页,页面本身就是权威坐标。
第三类:扫描版 PDF 经过 OCR 后,版式恢复能力有限,此时按页切至少能保证不把 OCR 结果再次打乱。页面是一个稳妥的容器。
4.2 它不适合哪些场景
第一类:多栏排版复杂、图文混排严重的论文 PDF。这类文档按页切很容易把两栏文字混在一起,导致逻辑错乱,必须做版式分析。
第二类:内容连续性强、跨页频繁的说明书或教科书。一个公式推导可能从第 10 页到第 15 页,按页切会把完整推理拆得稀碎。
第三类:文本极少、信息以图片为主的 PPT。按页切只会得到“无文本块”,必须接入 OCR 或图像理解能力。
第四类:Agentic RAG 场景中对文本块操作频繁的任务。这里我写一句我的观察:Agent 工具通常希望拿到的是有明确语义边界的切片,页码边界的块不一定适合操作,因为它可能包含多个动作步骤或无关注记。按页切作为基础索引可以,但最终给 Agent 使用的上下文,往往要再做一层语义重组。
4.3 一个判断“按页切还是语义切”的决策表
| 判断维度 | 更适合按页切 | 更适合语义切 |
|---|---|---|
| 页面文本量 | 每页 100-800 字 | 页长跨度大,短页多 |
| 跨页连续性 | 低,页面自成主题 | 高,一个章节跨多页 |
| 排版复杂程度 | 简单单栏,或版式恢复困难 | 论文双栏、复杂图文 |
| 溯源要求 | 必须返回页码 | 更关注章节或概念 |
| 用户提问粒度 | 问章节、条款、单页内容 | 问全局概念、跨页流程 |
| 示例文档 | PPT、合同、制度 | 论文、长教程、技术手册 |
这张表不是让你严格打分,而是帮你快速定位主要矛盾。现实中很多文档是混合型:开头是 PPT 式要点,中间是长段落文字。这种情况下,我建议第一层按页建索引,第二层在页内做语义切块,两层结构同时保留。
注意:不要追求“一套切法跑完所有文档”。RAG 系统进入真实项目后,文档类型往往会越来越多,预处理层设计成可扩展的规则链,比追求算法完美更重要。
5. 检索结果变差时,应该按什么顺序排查
5.1 先看解析层,再怀疑切分参数
很多人一遇到 RAG 检索不准,就立刻调 chunk_size、overlap。但我的经验是,相当一部分问题的根源在解析层,而不是切分参数。
排查顺序应该是这样的:
- 先看原始文本流。把 PDF 或 PPT 解析后的文本直接打印出来,看段落顺序、页眉页脚、表格内容是否正常。
- 看页面内容是否干净。OCR 错字多不多,PDF 里是否有大量空行和隐形字符。
- 再看切分后的块边界。选几个典型文档,检查标题和正文是否被切到不同块。
- 然后到检索层。检查召回结果是不是在语义上和问题相关,而不是只看字面命中。
- 最后才调整重叠区和块大小。
5.2 页面内文本缺失,是最隐蔽的坑
PPT 按页切经常碰到“页面有图,但没有文字”的情况。用户在页面上看到一张组织架构图,但文本提取结果为空。这种问题靠调 overlap 永远解决不了,必须先引入图片 OCR 或多模态模型。
另一个隐蔽问题是文本框的顺序。PPT 的文本框顺序有时和视觉位置相反,比如标题在顶部但读取顺序在正文之后。按页切后,文本流顺序可能是“正文、页脚、标题”。这种问题需要在解析时按坐标排序,而不是盲目相信文件内部顺序。
5.3 一些问题不是切分能解决的
如果检索结果一直不理想,也要考虑是不是嵌入模型能力不够。短文本、长文本、专业术语密集的文档,对嵌入模型要求不一样。你可以在同一个切分方案下,对比测试通用 embedding 和专业领域微调后的 embedding,再决定是否更换模型。
如果答案需要融合多个来源的信息,比如“对比 A 制度和 B 制度中关于预算审批的差异”,此时单个块再完整也无法回答,必须依赖多路召回和重排。此时问题已经不在切分,而在检索链路的整体设计。
还有一类常见问题:用户提问“讲一下这份文档整体说了什么”,但切的是细粒度页面块,每块都很小。这种全局性问题应该用摘要索引或章节级切片来兜底,而不是把希望寄托在按页检索上。
6. 从“按页切”到“知识库”的工程化三步走
6.1 第一步:先跑通最小流程,再拆文档类型规则
我见过太多团队一开始就追求“完美切分”,在预处理环节花了两周,最后连一个端到端问答都没跑通。这种做法不可取。正确路径是先用默认参数跑通一个最小可用的 RAG 闭环,哪怕召回结果很粗糙,先把链路打通。
跑通之后,再根据真实文档样本建立规则链:哪些是 PDF 单栏、哪些是 PPT 图文混排、哪些是扫描件。每种类型对应一套解析策略和切分策略,这样做出来的预处理器才有扩展性,而不是变成一个玄学调参现场。
6.2 第二步:建立基于真实问题的评测集
切分参数和重叠区到底该怎么选,最终要靠评测结果说话。你可以从知识库里挑 30 到 50 个真实用户问题,记录每个问题对应的正确答案应该在文档的哪个位置。然后跑不同切分参数,看 Recall@K 的变化,也包括“正确答案是否在召回的 Top-K 块里”这个指标。
评测集不需要一开始很大,但要覆盖三类问题:单点事实型问题,比如“某制度的发布时间”;流程综合型问题,比如“预算调整流程是什么”;跨页边界型问题,专门找那些答案会跨页的内容。如果你发现跨页边界型问题频繁失败,再考虑增加重叠区或改用结构感知切分。
6.3 第三步:把页面边界变成长期可维护的设计资产
按页分割的价值不只在检索,它还是一个可追溯方案。至少要保留原始文档的页码映射,确保用户可以在知识库问答后点击查看原文位置。很多业务场景里,“可解释性”比“回答准确”更重要,尤其政务、法务、金融这类对出处有要求的场景。
长期维护阶段,还要解决文档更新的问题。如果一份 PDF 重新发布了新版本,旧版页面内容变了,那么需要让页面级索引对应到新版本的全局 ID,否则知识库里会出现新旧内容混用。这个更新策略,需要和文档版本管理配合。
写在最后:不要用“调参手感”替代“设计逻辑”
回到开头的问题:RAG 文档预处理里的“按页分割”和“重叠区”是玄学吗?
我觉得不是。它只是把很多变量压到了一个容易被忽视的层面:文档格式、解析器能力、页面语义完整度、检索粒度、评测方式。任何一个变量没想清楚,都会让人误以为切分策略是玄学。真正有效的做法是:先建好最小流程,再用真实问题评测,再用测试结果反推参数和文档类型规则。
下次再遇到“按页分割还是语义切块”的争论,你可以先问三件事:原始文档有哪些类型?页面边界是否等于语义单元?用户提问需要什么样的溯源粒度?这三个问题回答清楚了,切分策略自然就浮出水面。
重叠区也好,分页也好,它们都是服务于 RAG 整体效果的手段。把文档预处理当成一个有输入、有输出、有反馈的工程模块来设计,你对参数的每个调整就都有据可依了。