尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

PDF 转 Markdown,报告说保真率 98%,打开一看标题全是 nnnn

PDF 转 Markdown,报告说保真率 98%,打开一看标题全是 nnnn PDF 转 Markdown报告说保真率 98%打开一看标题全是 nnnn把一份 3 页的财务报告 PDF 交给 tri-pdf2md 转 Markdown门D 质量报告甩给我一个保真率 98.1%、置信度 A 级的成绩我打开产物一看标题全变成了 nnnn。跑完五阶段管道我才想明白保真率比的是「PDF 文本层和 Markdown 的重合度」不是「原文和转换结果」。源 PDF 的字体 ToUnicode 映射本身是坏的两侧抽出来都是 nnnn数字照样漂亮。指标诚实地回答了「转换丢没丢」却测不出「源文件字体坏没坏」。这份 PDF 是块什么料要转的是一份 3 页的英文财务报告虚构的季度业绩样本标题是中文。tri-pdf2md 的定位不是转换器是个质检车间先体检、再选刀、干完活必须交验、按用途打包。五阶段管道四档降级链PDF 在它眼里是有时效、有坐标的数据源每个产物都要带版本和页码锚点。门A 预检分级 → 门B 后端探测 → 门C 版面分析转换 → 门D 质量校验报告 → 门E 结构化交付门A 预检3 页、纯文本层、L0第一步不是转是体检。跑scripts/preflight.py输出是确定性的 JSON不允许我凭肉眼猜等级python scripts/preflight.py--pdfsample.pdf--json{page_count:3,avg_chars_per_page:211.7,text_pages:3,scanned:false,grade_suggestion:L0,risks:[]}3 页都有文本层、不是扫描件、没有表格信号预检建议 L0 快速档。干净利落risks 是空的。我当时还想着这单活应该很轻松后面就被打脸了。门B 探测本地只有 L0 的刀门B 探测六个后端在本地装没装import 和 CLI 双探测python scripts/detect_backends.py--gradeL0--json结果很有意思后端档位本地状态许可证pymupdf4llmL0未装AGPL-3.0markitdownL0✅ import 可用MITpdfplumberL0✅ 可用MITdoclingL1未装MITmarkerL1未装Apache-2.0mineruL2未装Apache-2.0 (3.3.0 OSL)探测给出的方案是 L0 档、首选 markitdown、降级链 pdfplumber并把 pymupdf4llm 列入missing_with_install附带安装命令pip install pymupdf4llm。按契约L1/L2 的重型后端docling/marker/mineru未装时不能擅自装数 GB 依赖得先问过我。这台机器上能用的只有 L0 的刀那就先拿 L0 干。坑一探测说 markitdown 可用CLI 却不在 PATH门B 探测 markitdown 是通过import markitdown探测成功的可我兴致勃勃敲markitdown sample.pdf -o sample.mdPowerShell 直接回我一句The term markitdown is not recognized as the name of a cmdlet...模块装上了CLI 没进 PATH。这个坑不大但很典型探测脚本测的是「库能不能 import」不等于「命令行能不能调」。绕一下用 Python API 走frommarkitdownimportMarkItDown mdMarkItDown()resultmd.convert(sample.pdf)open(sample.md,w,encodingutf-8).write(result.text_content)转换成功650 字符正文读起来一切正常。直到我扫了一眼开头几行1 nnnn The company reported strong results in the second quarter of 2026. Total revenue reached 42.5 billion, representing year-on-year growth of 3 percent.中文标题「1 总体业绩」变成了「1 nnnn」「2.1 营收构成」变成「2.1 nnnn」英文正文一个字没丢。门D 校验98.06% 保真率A 级无异常按流程转换完必须交验跑门Dpython scripts/quality_check.py--pdfsample.pdf--mdsample.md--backendmarkitdown--gradeL0--json报告里写保真率 98.06%、丢失率 1.94%、噪声率 2.42%置信度 A 级原因写着「保真率 98.1% ≥ 95% 且结构计数吻合、无异常」异常清单为空。乍一看完美可md_headings那个字段是 0。MD 里一个标题都没识别出来标题已经是 nnnn 了markitdown 没把它们当标题直接当普通段落输出。问题来了这 98% 是怎么算出来的门D 的保真率是「PDF 文本层 vs MD」的归一化 bigram 覆盖率。我用 pdfplumber 直接抽 PDF 的文本层验证了一下importpdfplumber pdfpdfplumber.open(sample.pdf)print(repr(pdf.pages[0].extract_text()[:200]))# nnnn\n1\nThe company reported strong results...PDF 源文件的文本层里标题位置本来就是 nnnn。这份 PDF 的标题用了某种没嵌好 ToUnicode 映射的字体PDF 侧抽出来是 nnnnmarkitdown 转出来也是 nnnn两侧完全一致bigram 覆盖率自然逼近 100%。保真率测的是转换过程丢没丢字测不出源文件本身坏没坏。这恰恰是 report.md 里那份「永不消失的复核项清单」第 5 条写的中文字体嵌入缺失导致的字符缺失。清单一直摆在那儿我却信了数字。门E 结构化锚点覆盖率 0.85页码锚点变成问号我顺手开了门E 结构化交付Obsidian 笔记 父子分块 审阅页python scripts/structure_pack.py--pdfsample.pdf--mdsample.md\--backendmarkitdown--gradeL0--confidenceA --fidelity-rate0.98\--doc-version v2026-08-28_demo--json产出 doc_idsample_891a1f3 页、1 个父块、13 个子块锚点覆盖率 0.846213 个里有 11 个子块带精确 bbox引用可追溯率 0.8462。子块长这样坐标是硬编码进去的{chunk_id:p001-c01,text:1 nnnn,page:2,bbox:[81.2,60.9,120.9,74.2],anchor_source:exact}但生成的 Obsidian 版里目录是空的页码锚点退化成%% p.? %%。标题树是空的章节锚点映射不到页只能给个问号占位。一个标题乱码的连锁反应标题树丢、目录丢、页码锚点丢。每一步工具都如实报告了问题全都出在源 PDF 那 4 个标题字符上。同样的坑换个场景L1 的活被 L0 硬扛这不是我唯一一次被数字骗到。翻了下 .tribro 里 2026-08-24 的转换记录32 页的《中国企业AI大模型落地应用现状调研报告》门A 预检判 L1混合型抽样页里有两页没有文本层但因为本地只有 L0 后端硬降档用 markitdown 跑门D 的账是这样的关键数据数值保真率88.8%丢失率11.2%噪声率12.9%置信度B85%~95%PDF 检出表格14 处MD 表格0全丢丢失集中页第 7 页69.9%、第 9 页78.7%88.8% 看着还行实际是整份报告 14 张表格全被降档转成了纯文本流一页没剩。置信度 B 级报告照样列出了复核项要人工核对。L1 的文档用 L0 的刀能出活但表格这种结构性内容就是第一个被牺牲的。扫描件是另一条线顺手把扫描件样例也丢进预检2 页、chars: 0、scanned: true等级建议直接给 L2风险提示「需 OCR 精细档质量预期 C 级起步」。这条诚实边界我挺认可扫描件没有文本层保真率算不出来就不硬算明说 C 级起步不给虚假承诺。这坑怎么填先怀疑源再怀疑工具转换结果乱码先用 pdfplumber 抽一层源文本层比对 PDF 侧是不是本来就坏。两侧都坏问题在 PDF 生成端字体没嵌 ToUnicode不在转换器。别只看保真率一个数把md_headings、md_tables这种结构计数一起看。保真率 98% 但标题数 0本身就是红灯。复核项清单不是摆设report.md 那份固定清单跨页表格、图表题注、脚注归属、多栏阅读顺序、中文字体嵌入缺失是白名单式兜底A 级也不该跳过。这次「中文字体嵌入缺失」那条就是为我准备的。档位要匹配文档L1/L2 的活别硬用 L0 扛表格结构会先死。值得为pip install pymupdf4llm或 docling 花几分钟或者干脆换能出 content_list 中间产物的后端。顺带一提我在给「雷达鸭」一个收录中国一人公司真实赚钱案例的 App鸿蒙版在华为应用市场整理案例资料时也撞过同样的事PDF 是从设计稿直接导出的标题字体没嵌全转换出来第一行就是乱码从那以后我养成了先抽源文本层的习惯。收尾这次最大的收获是把「保真率 98%」这个数字背后的口径想明白了它回答「转换丢没丢」不回答「原文好不好」。tri-pdf2md 的价值恰恰在于它把这种边界写进了契约诚实声明、分级保真、复核项永不消失。数字可以骗人但把「算的是什么、哪里需要人工看」讲清楚的工具不会。tri-pdf2md / PDF 转换 / Markdown / 踩坑复盘 / 开发者工具我是老三10 年软件开发经验软件设计师、人工智能应用工程师专注鸿蒙应用开发ArkTS北向开发与 Web 前端探索 AI 自动化不定期在 CSDN 分享鸿蒙 / AI 方向技术文章。本文遵循 MIT 协议转载请注明出处。这个系列的文章都来自开源的 tri 技能库。整套 tri-xxx 技能都能在 skillhub 找到并安装一条命令装完即用比如本文用到的 tri-pdf2mdskillhub install tri-pdf2md。装完每个技能都有 README想摸清它到底能干嘛读那个就够了。
返回列表