标准回答
一、先把结论讲清楚
核心原则是:先按格式抽取出干净、带结构的文本,统一成一种结构化中间表示,再做后续的分块与嵌入。绝不能把原始字节直接塞给切分器。
二、按格式选解析器
- Markdown:天然带 #` 标题层级和列表/代码块结构,几乎是理想输入;解析后直接利用标题层级做结构感知分块即可。
- HTML:需去掉标签、脚本、导航/广告等噪声,只留正文;但其
h1~h6、table、li等标签本身就是很好的结构信号,可映射成层级元数据。 - Word(.docx):用
python-docx等库读取段落样式(Heading 1/2…)、列表与表格,能较可靠地还原标题层级。 - PDF 最棘手:PDF 只描述「字符画在哪个坐标」,没有逻辑结构。需做**版面分析(layout analysis)**还原阅读顺序、识别多栏排版、页眉页脚、表格区域;扫描件/图片型 PDF没有文本层,还得先 OCR。常用 pdfplumber、PyMuPDF 或带版面模型的解析工具。
三、统一中间表示
把各格式解析结果都转成统一的结构化对象,每个文本片段附带元数据:标题路径、层级、来源文件、页码等。下游分块、召回、引用溯源都依赖这层抽象,而与原始格式解耦。
四、专项内容处理
- 表格:抽成 Markdown/HTML 表或「每行一句自然语言」,避免纯文本展平后行列错乱。
- 图片:用多模态模型或 OCR 生成描述/caption 再入库。
- 公式:尽量转 LaTeX/文本,避免乱码。
- 多栏版面:靠版面分析恢复正确阅读顺序,否则两栏文字会交错串行。
五、为什么要保留标题层级
保留层级既能驱动结构感知/语义分块、避免跨章节混切,又能在召回时把章节标题作为上下文锚点拼进 prompt,提升答案的相关性与可溯源性。
工程上常见做法是统一接入 Unstructured、LlamaParse 这类解析层抽象掉格式差异,对 PDF 这类难格式单独配置版面/OCR 流水线。
常见误区
⚠️ 常见踩坑
误区一:容易答偏的地方:误以为「所有格式都先转纯文本再统一切分」最省事。纯文本会丢掉标题层级、表格行列与阅读顺序,PDF 多栏甚至会交错串行,导致分块与召回质量崩塌。正确做法是按格式保留结构、转成带元数据的中间表示。
追问
追问 1:为什么 PDF 比 HTML / Word 难解析这么多?
因为 PDF 本质是「打印描述」,只记录每个字符的字体和页面坐标,不保存段落、标题、表格这些逻辑结构,阅读顺序也不可靠。HTML/Word 自带 DOM 或样式层级,结构信息现成。所以 PDF 必须靠版面分析从坐标反推结构,扫描件还没有文本层、得先 OCR,难度陡增。
追问 2:扫描件 PDF 和原生(数字)PDF 的处理流程有什么不同?
原生 PDF 有文本层,可直接抽取字符再做版面分析;扫描件本质是图片,没有文本层,必须先用 OCR 把图像识别成文字(并尽量带坐标),再走版面分析。OCR 会引入识别错误和噪声,通常还要加后处理纠错、置信度过滤,整体可靠性和成本都比原生 PDF 差。
追问 3:统一中间表示里应该带哪些元数据,有什么用?
至少带:来源文件名、页码、标题路径(所属章节层级)、内容类型(正文/表格/图片描述)。用途包括:驱动结构感知分块、在召回时把章节标题作为上下文锚点、做引用溯源(答案能定位到具体文件页码)、以及按来源做权限或时效过滤。
🔗 相似问题
同一考点的不同问法,换着练更稳
延伸学习
按主题分类的相关资源,便于系统复习
