Ch29: Go docparser——HTML 归一化、格式契约与 chunk 保护
Part 8 · 前置:Ch28 docreader · 后续:Ch30 向量库 案例:case-1725
结论先行:internal/infrastructure/docparser/ 负责 异构解析结果 → Go 可控 Markdown/HTML。上游(OCR/VL)改输出格式时,必须同步验证 chunker 的 protectedPatterns 假设——#1725 是「中间层未满足下游契约」的教科书案例。
一、日常类比
docparser 是翻译官:Python 侧说「表格方言」(HTML + 内联 style),chunker 只听得懂「标准 Markdown 表格语」。翻译官若原样传话,裁纸工人(chunker)会把 HTML 当普通段落从中间剪开。
二、管线位置与数据流
docreader (Py) ──gRPC/HTTP──► docparser (Go) ──► chunker ──► embed ──► vector store
│ │
Excel/PDF/OCR HTML→MD 归一化
样式剥离
table 边界标记
case-1725 修复策略(PR #1755,+149 行):
- 简单 HTML 表 → Markdown 管道表
- 复杂 rowspan/colspan → 剥离
style,保留<table>供 chunker 扩展保护 - 66 行测试锁定 regression
三、下游 chunker 的格式 invariant(读代码前必知)
chunker 假设 ingest 文本满足:
- 表格要么为 完整 Markdown pipe 块,要么为 可识别的 HTML table 块
- 不应出现拦腰截断的
<td style=...>碎片 - 代码块用 fence ``` 包裹(若来自 MD)
违反 invariant → 检索层 无法修复(见 Ch39 GIGO)。
rg -n "HTML|Markdown|table|Convert" internal/infrastructure/docparser/ -g '*.go'
rg -n "protectedPattern|Protected" --glob '*.go' internal/ pkg/
列出你仓库版本的 Convert* 函数名与测试文件 *_test.go。
四、与 RAGFlow DeepDoc 对比(该层该学什么)
| WeKnora docparser | RAGFlow DeepDoc | |
|---|---|---|
| 重心 | 归一化 + 桥接 Python | 版面分析 + 深度表格 |
| 改动面 | Go 149 行可合入 | 模型+GPU 重 |
| 竞赛 | ★ 适合犀牛鸟 PR | 对标参考 |
DeepDoc 强在 Level 2 结构;WeKnora 竞赛 PR 多在 Level 1–2 边界 + 下游契约。
五、动手(60 分钟)
- 读 case-1725 mermaid B→C→D
- 在 docparser 测试里找 HTML table fixture
- 人为构造「带 text-align 的 40 行 HTML 表」,ingest 后 grep chunk 是否含完整
<table>或| - 对照 lab/queries-smoke-20.jsonl D 组自测
六、贡献 checklist
- 新 OCR 输出格式 → 先写 invariant 文档 再改代码
- 每个 docparser PR 带 chunk 边界 集成测试(不只 unit)
- 链接到 #1725 模式:ch-patterns-from-cases
章末自检
- 画 Python→Go 边界,标 #1725 发生层
- 列举 chunker 应保护的两种表格表示
- 说明为何「只增大 ChunkSize」不能根治 HTML 表切断