为什么先做解析
文档 RAG 的常见失败不是向量库召回不准,而是解析阶段把两列表格拍成一列、把页眉页脚混进正文、丢掉页码。模型再强,也只能基于被破坏的文本回答。Docling 的定位就是把 PDF、DOCX、HTML 解析成保留版面与阅读顺序的统一结构,再输出 Markdown 或 JSON。
装与跑
pip install docling
# 先拿一份最难的扫描件试
docling ./contracts/2026-001.pdf --to md --output ./out先用官方 CLI 跑一份最难的扫描件,确认输出里的标题层级、表格、页码是否保留;不要一上来就批量。批量脚本里给每份文件记录来源路径与页数,后面做引用回溯要靠它。
批量转换脚本
from pathlib import Path
from docling.document_converter import DocumentConverter
converter = DocumentConverter()
out = Path('out'); out.mkdir(exist_ok=True)
for pdf in Path('contracts').rglob('*.pdf'):
try:
doc = converter.convert(pdf).document
md = doc.export_to_markdown()
(out / (pdf.stem + '.md')).write_text(md, encoding='utf-8')
print('ok', pdf)
except Exception as e:
print('fail', pdf, repr(e))逐份转换、逐份落盘,失败的文件单独记日志,不要一个异常中断整批。转换结果是中间产物,原始文件保持只读;脚本里也不要顺手改写源目录。
切块规则
按标题层级切,不按固定字符数切;表格单独成块并保留表头;每块带上文件名、页码、标题路径三个元数据。这样回答里能给出「第几页、哪一节」,而不是只给一个文件名。
抽检清单
随机抽 20 份,检查:表格行列是否对齐、页码是否能回到原页、标题层级是否断裂、页眉页脚是否被清掉。四项里有一项系统性失败,就先修解析或换引擎,别急着加向量库。
先让机器读对,再让它答得快。