处理复杂 PDF 时,常会遇到一类高风险结果:每个字都识别出来了,但阅读顺序和字段关系却是错的。解析任务显示成功,分块与向量化正常完成,用户也能搜到很多相似内容,但模型拿到的证据已经不是原文真正表达的意思。
先看一个双栏理赔指南的例子。左栏写办理步骤,右栏写申请材料。如果解析器按照同一水平位置依次拼接,输出会变成一句步骤接一句材料。用户问“需要提交哪些材料”时,检索器看到的不是一个完整材料清单,而是一段步骤和材料交错的文本。
面试官很可能追问:
PDF 里的文字已经提取出来了,为什么还要做版面分析?双栏、跨页表格和图片应该怎样变成可检索内容?
只回答“使用某个 PDF 解析库”,问题并没有真正解决。面试官想听的是,错误会在哪一层发生,你怎样保住结构,失败之后又怎样验证。
为什么“把字读出来”还不够?
在人眼看来,一页文档由标题、段落、表格、图片和注释组成。人在阅读时会自然判断先看左栏还是右栏,哪一行是表头,哪个说明属于哪张图。
程序看到的却可能只是很多文字框和绘制对象。对象在文件里的排列顺序,不保证等于阅读顺序。仅按纵坐标排序,双栏内容会交叉;仅按程序返回顺序拼接,页眉可能插进正文,图片说明也可能跑到下一段。
这类错误不会阻止向量化。每个错乱片段仍然是一串合法文字,Embedding 仍能生成,向量库仍能接收。错误一直传到生成阶段,最后表现成“模型回答不稳定”。
所以复杂 PDF 解析要先恢复内容关系,再讨论怎样切块。不能指望后面的检索器从一段错乱文字里推理出原始版面。

同一批文字按不同顺序拼接,可能表达不同含义。双栏页面里的步骤和材料交叉,就是一种典型情况。
一条可靠的复杂 PDF 解析链路怎么走?
可以把解析链路拆成七步。
第一步,按页读取基础元素。
取得字符层、文字框、字体与位置信息,同时识别页面中的图像。扫描页还要先走文字识别路线。这里保存的是原始证据,不要急着拼成一大段文本。
第二步,版面区域分类。
版面分析可以把标题、正文、表格、图片、页眉页脚、印章和水印列为需要区分的区域类型。具体类别要按实际文档调整,关键是让不同内容进入不同后处理逻辑。
第三步,恢复阅读顺序。
先判断页面有几栏,再在每个栏位内部按纵向顺序组织。标题与紧随其后的正文要保持联系,同一段被拆成多个文字框时需要合并。栏间切换不能只依赖一个坐标,还要结合区域边界、间距和内容类型。
第四步,专项处理表格。
表格不能只留下单元格文字。要恢复行、列、表头和合并单元格等关系。结构化结果可以保存为 HTML、JSON 或其他能够表达行列的格式,同时保留表格标题、页码和原始区域。
第五步,绑定图片与说明。
图片区域要与附近标题、图注和正文说明建立关系。普通截图可以提取可见文字,流程图或数据图则还包含箭头和结构。任何自动生成的图片描述都属于派生信息,必须保留原图引用,并与原文内容区分。
第六步,清理重复和噪声。
页眉、页脚、水印和重复页码会在多页文档中反复出现。清理时要避免误删正文,尤其是标题与页眉样式接近的材料。规则应该在代表性页面上抽检,而不是一次配置后永久信任。
第七步,输出统一内容单元。
每个单元包含正文、内容类型、标题路径、页码、坐标、来源文件和解析状态。表格与图片还要保留结构数据或原始资源标识,方便后续切分、检索和引用。

先保留页面元素,再恢复区域、顺序和结构,最后输出带来源位置的内容单元。
这条链路不要求所有页面都调用最重的模型。普通单栏文本可以走较轻的路线,只有识别出特殊版面或表格时,再进入对应处理。是否分流,要由样本和验收结果决定。
双栏页面为什么不能只按坐标排序?
假设左栏有三个办理步骤,右栏有三项所需材料。
如果程序只按纵坐标从上到下排序,左右两栏同一高度的文字会轮流出现。最终片段可能是“事故发生后联系机构,身份证复印件,提交诊断证明,合同复印件”。
从词面看,它和理赔高度相关。检索器甚至可能把它排在前面。但它把动作与材料的层次打乱,模型无法判断哪些是步骤、哪些是附件。
更合理的处理是先识别栏位边界,在栏内恢复顺序,再依据标题和区域关系组织内容。遇到跨栏标题时,还要判断它是整页标题,还是只属于某一栏。
同一行被拆成多个文字框时,可以根据水平距离、字体、基线和标点合并。上下两段是否属于同一段,则要结合垂直间距、缩进和段落边界。没有一条对所有 PDF 都适用的单坐标规则。
验证双栏恢复也不能只看最终文本是否通顺。应把原始页面、区域框和排序后的结构并排抽检,并用能够区分左右栏的问题测试。只有当“办理步骤”和“申请材料”能够分别被正确找到,结构才算真正保住。
表格为什么不能只“识别文字”?
表格的语义来自位置关系。
一个单元格写着“两个工作日”,离开表头后,无法判断它表示处理时限、等待时间还是有效期。一列产品名和一列适用条件如果错位,所有字都正确,事实对应关系仍然错误。
有边框表格可以借助线条和单元格区域恢复结构。无边框表格则更依赖文本对齐、间距和表格识别能力。无边框表格容易被基础解析器提取成列关系混乱的纯文本,需要采用专项表格路线输出结构化结果。
跨页表格更难。
下一页可能没有重复表头,只保留数据行。系统要判断新页面是上一张表的延续,还是一张新表。可以利用表格标题、列数、对齐方式、页面边界和续表标识进行判断,但最终规则要在自己的文档样本上验证。
如果表格很长,需要拆成多个 Chunk,每块都要重复带上必要表头、表格标题、页码范围和分块序号。这样用户问某个字段时,检索到的数值不会变成没有列名的孤立文本。
图片、流程图和说明应该怎样绑定?
图片不等于图片里的文字。
OCR 能读出截图中的标签,却不一定理解箭头从哪个节点指向哪个节点。数据图表中的坐标、图例和趋势也不能只靠把可见文字串起来还原。
比较稳妥的做法,是先把图片区域与附近标题、图注和正文说明绑定成一个内容单元,再按图片类型选择处理路线。
普通界面截图可以提取文字,并保留原图。流程图可以生成受控描述,但描述要明确标识为模型派生内容,不能覆盖原图事实。数据图表如果要结构化提取,也应保留图表区域和来源位置,并进入抽检。
图片说明和图片一旦分离,也会出现检索错位。用户搜到“如图所示的审批路径”,系统却只返回这句话,没有返回对应图片或描述。这个片段虽然文字相关,仍不能独立支持答案。
因此,切分时应把图片、标题和必要说明视为一个关系单元。若内容太长,可以拆分正文,但图片标识和核心图注需要在相关片段中保留。
三类 bad case,怎样沿链路定位?
下面的案例都是为了说明故障位置的教学问题,不代表某个真实系统已经得到量化结果。
第一类,双栏内容交叉
现象是步骤和材料互相穿插。
先看区域识别结果。如果左右栏根本没有分开,问题在版面分类。如果区域正确但最终文本交叉,问题在阅读顺序恢复。如果结构化输出正确,切分后才混在一起,再检查 Chunk 合并逻辑。
第二类,表格标题和数据分离
现象是检索命中“实验结果”或“处理时限”,却找不到对应表格数据。
先看表格区域、标题和图注是否建立关联,再看结构化存储是否保留表头与行列。最后检查切分时是否把表格标题留在上一块,数据放进下一块。
第三类,多级标题被压成一行
可以设想“第一章、第一节、第二节”层级消失的示例。解析后,章节标题与正文被拼在一起,后续片段不再知道自己属于哪个主题。
排查时看标题类型是否被识别,标题路径是否写进内容单元,以及正文块是否继承上级标题。只在最终文本前加一个文件名,不能替代完整章节关系。

从区域识别、顺序恢复、结构化输出到切分逐层检查,才能知道错误到底发生在哪里。
排错时最好保留三份中间产物:原始页面、带区域框与顺序编号的版面结果、最终结构化内容。再加上切分结果与检索候选,就能从用户反馈一路回到错误源头。
还有一类经常被忽略的故障:单页结果正确,跨页关系却在重新处理时发生漂移。比如上一版把第二页判断为续表,新版却把它识别成新表;或者标题区域略有变化,后续所有正文的标题路径都跟着改变。这类差异不会表现为漏字,却会让同一个问题命中不同语义单元。
因此,复杂 PDF 的解析结果最好形成可比较的页面契约。每页记录区域类型、阅读顺序、父子关系、跨页连接和原始位置;表格额外记录表头、列结构、续表关系和拆分边界。候选版本运行后,先比较这些结构差异,再决定是否重建 Chunk。不能只比较最终 Markdown 是否相似,因为相似文字背后可能已经换了行列关系。
对于跨页表格,至少要验证三个问题:两页是不是同一张表,续页数据继承的是哪组表头,拆分后的每个片段能否独立解释字段。判断不确定时,应保留两页原始区域和待复核状态,而不是为了输出完整表格强行合并。强行合并制造的是新的事实关系,风险高于暂时不放行。
回归时还应分别观察普通单栏、双栏、表格和图文混排。专项规则只对命中的页面生效,不能因为修好一种跨页表格,就让普通页面全部进入更重、更不稳定的处理路线。面试官若问“怎样控制复杂模型的使用范围”,可以回答:先用可解释的页面特征路由,再用固定坏样本验证召回范围,并记录每次升级新增和退出专项路线的页面。
结构差异最终还要落到用户问题。选择能够区分表头、续表和标题层级的问题,比较新旧版本实际提供的证据与引用位置。只有结构检查与问题检索同时通过,才能说明新版解析不仅看起来更整齐,也确实保住了原文关系。
脚注、侧栏和页内注释也会制造类似问题。它们通常字号更小、位置靠边,却可能限定正文中的适用条件。如果解析器把脚注当页脚删除,答案会丢掉例外;如果把所有脚注插入段落中间,正文顺序又会被打断。不能仅凭区域位于页面底部就决定删除,而要结合跨页重复、引用符号和正文关系判断。
处理脚注时,可以先保存注释区域和引用标识,再把正文中的标号与对应注释建立关联。用于检索的片段可以在需要时附上相关脚注,但必须区分正文和补充说明,避免模型把脚注例外说成主规则。找不到明确引用关系时,保留原页位置比猜测绑定更安全。
页面侧栏也不能一律并入正文。它可能是案例、提示、版本说明或独立流程。先判断侧栏是否有独立标题、边框或稳定区域,再决定作为子内容单元还是正文补充。验收问题要覆盖“主规则是什么”和“有哪些例外”两类问法,确认侧栏既不会污染主流程,也不会在用户询问限制条件时完全消失。
这类结构尤其适合通过对照证据验收:人工标出正文主张、脚注限制和侧栏说明各自的位置,检查解析后是否仍能分别定位,并验证组合回答时引用覆盖了每个事实。若系统只找到主规则却漏掉否定条件,即使整体文字覆盖很高,也应作为高风险坏样本保留。
公式和特殊符号也要单独看待。普通文本提取可能保留变量名,却丢掉上下标、分式和符号关系;把公式转成一行字符后,检索虽然还能命中术语,含义却可能已经变化。可以同时保留可搜索的文字说明、结构化公式表示和原页区域,无法可靠转换时明确标记,而不是生成一个看似完整的等式。
验收公式时不必覆盖整本文档,可以挑选会影响结论的定义、约束和计算式,检查符号、上下标及正文解释是否保持关联。用户问题若依赖公式条件,返回证据也应包含必要说明与原页引用。这样既让普通术语可检索,也避免模型依据一段残缺符号自行补全推导。
怎么证明复杂 PDF 解析真的有效?
评测要分层,不要只汇报“解析成功率”。
第一层是元素覆盖。
检查标题、正文、表格、图片和说明是否被找到。对扫描页还要检查文字区域。缺少某一类元素时,要能定位到具体页面和处理阶段。
第二层是顺序与层级。
对双栏、混排和多级标题页面准备人工标注顺序,核对解析后是否仍然保持。标题是否与正文关联,列表层级是否存在,也要单独检查。
第三层是表格结构。
抽取代表性表格,检查表头、行列和单元格对应关系。跨页表格还要验证续表是否正确合并,拆块后是否重复携带必要表头。字符都对但列错位,仍然是不合格结果。
第四层是可溯源性。
从任意内容单元返回原文件、页码和页面区域。图片描述要能回到对应图片,表格数据要能回到对应表格区域。只有文件名而没有具体位置,不足以支持核验。
第五层是端到端检索。
分别为双栏正文、表格字段、图片说明和多级标题准备固定问题、参考答案与证据位置。检查正确证据能否进入候选,关键关系是否在同一可理解片段中,引用是否指向正确页面。
第六层是 bad case 回归。
每次调整版面规则或表格模型后,都要重新跑以前失败的页面,同时确认普通单栏文档没有被新规则破坏。只看新样本变好,不看旧样本回归,很容易把错误从一种页面转移到另一种页面。

覆盖、顺序、表格、溯源、检索和回归分别验收,才能避免一个总分掩盖结构错误。
评测记录里不需要预填漂亮数字。先写清样本类别、期望结构、实际结果和失败原因,跑完自己的数据后再汇总。无法复核来源的指标提升,不应该出现在面试答案中。
面试官继续追问,怎么接?
为什么不直接使用一个强大的多模态模型读取整页?
多模态模型可以作为某些复杂页面的处理选择,但仍要解决成本、稳定性、输出结构和原文定位问题。即使模型生成了页面描述,也要保留原始区域并验证描述是否忠实。不能因为模型更强,就跳过来源与质量控制。
无边框表格怎么判断?
可以结合文本块的对齐、间距、重复列位置和表格识别结果判断。是否进入专项模型,要在自己的页面样本上验证。回答时重点是说明它不能依赖可见边框,而不是背某个固定像素阈值。
跨页表格应该合并还是拆分?
先确认两页是否属于同一张表,再根据长度和检索需要决定。合并要保留页码范围,拆分要重复表头、标题和续表信息。无论哪种方式,都不能让数据行离开字段名。
图片描述能不能直接当原文?
不能。自动描述属于派生信息,可能遗漏或推断。它可以帮助检索,但必须保留原图引用和来源位置,关键内容还要抽检。回答中应区分原文文字、结构化提取和模型生成描述。
解析成功但 RAG 仍答错,先查哪里?
先拿出模型实际看到的证据。若证据中的顺序和字段关系已错,回到解析与切分。如果证据结构正确却没有被找回,再查检索。如果正确证据已经排在前面,才继续检查上下文组织与生成。
怎样证明不是只调用了开源解析器?
讲清输入分类、路由条件、保留的数据结构、失败页面、验收样本和回归过程。工具名称只是链路中的一环,真正的工程贡献体现在怎样让输出适合自己的文档,并且能够证明它可靠。
一段话讲清复杂 PDF 的解析与验收
把版面、表格和引用连成一段回答,可以这样说:
复杂 PDF 的难点不只是识别文字,而是恢复人类阅读时使用的顺序和关系。PDF 中的文字框返回顺序不一定等于阅读顺序,所以我会先按页保留字符、坐标和图像,再做版面区域分类,区分标题、正文、表格、图片和页眉页脚。双栏页面先识别栏位,再在栏内恢复顺序;表格单独恢复行列、表头和跨页连续关系;图片与标题、图注和正文说明绑定,任何自动生成的描述都保留原图引用。最后统一输出正文、类型、标题路径、页码、坐标和解析状态,再进入切分与索引。验收不会只看提取字数,而会分别检查顺序、层级、表格关系、原文定位,并用固定问题验证正确字段能否一起被召回。出现错误时,再从原始页面、区域结果、结构化内容和 Chunk 逐层定位。