Ch34: RAGFlow 源码走读——DeepDoc 与摄入管线
Part 9 · 前置:Ch17 RAGFlow 精读 · 后续:Ch35 FastGPT
结论先行:RAGFlow 大师路径 = 先读透 deepdoc/,再读 rag/retrieval/。检索层相对薄(BM25+向量);PDF 表格被切碎、扫描件 OCR 失败、公式丢失等 issue 必进 deepdoc/vision + deepdoc/table。WeKnora 竞赛高 ROI:在 docparser/docreader 层借鉴 DeepDoc,而非只卷 RRF。
一、日常类比
普通 RAG 摄入像 搅拌机:PDF、Word、表格全打成一种「文本奶昔」,珍珠(数字)和布丁(表头)混在一起。DeepDoc 像 中央厨房分档口:先版面识别分区,表格档保留行列,正文档按语义切,图片档 OCR 后再入库——检索时不再「凭运气捞到半张表」。
二、Commit / 版本 Pin 说明
| 项 | 建议 |
|---|---|
| 仓库 | infiniflow/ragflow |
| Docker | 官方 docker compose,镜像 tag 以 clone 日 2026-06 为准并记录 commit |
| 注意 | deepdoc/ 模型权重较大,首次启动需下载;GPU 可选但 OCR/版面更快 |
git clone https://github.com/infiniflow/ragflow.git
cd ragflow && git log -1 --oneline > ~/ragflow-pin.txt
docker compose -f docker/docker-compose.yml up -d
Pin 写入实验笔记,与 Ch37 元数据表「RAGFlow 版本/tag」列对齐。
三、目录地图(DeepDoc 优先)
deepdoc/
parser/ # 格式路由:pdf_parser, docx_parser, excel_parser...
vision/
layout.py # LayoutRecognizer — 文本/表/图/标题检测
ocr.py # OCRRecognizer — 扫描件
table/
table_structure.py # TableStructureRecognizer — 行列/跨行跨列
formula/ # 公式 → LaTeX
rag/
chunking/ # template.py, intelligent.py — 九种模板分块
retrieval/ # hybrid, bm25, vector — 相对薄
graph/ # Graph RAG(experimental)
api/db/services/ # 业务:document_service, task_service
| 模块 | 改这里当… |
|---|---|
deepdoc/parser/pdf_parser.py |
PDF 整体解析策略 |
deepdoc/table/table_structure.py |
表格数字与表头分离 |
rag/chunking/template.py |
财报「整表不切断」模板 |
rag/graph/ |
实验性图谱,勿当生产默认 |
四、一条具体调用链(PDF 上传 → Chunk 入库)
api/apps/document_app.py # 上传 HTTP
→ api/db/services/document_service.py # 创建 doc 记录、派发 task
→ rag/svr/task_executor.py # 异步摄入 worker
→ deepdoc/parser/pdf_parser.py # PDFParser.parse()
→ deepdoc/vision/layout.py # LayoutRecognizer.detect()
→ deepdoc/vision/ocr.py # 扫描页 OCR(按需)
→ deepdoc/table/table_structure.py # 表格结构恢复
→ deepdoc/formula/ # 公式块(论文场景)
→ rag/chunking/template.py # 按文档类型选模板分块
→ rag/utils/es_conn.py 或 vector store # 写入索引
检索侧短链:rag/retrieval/hybrid.py → BM25 + 向量 → 可选 rerank → LLM。大师 80% 时间花在摄入链。
五、grep 起手式
cd ragflow
rg -n "class PDFParser|class LayoutRecognizer" deepdoc/
rg -n "TableStructureRecognizer|table_structure" deepdoc/table/
rg -n "TemplateChunker|template" rag/chunking/
rg -n "experimental|graph" rag/graph/ -i
rg "parse-pitfalls|DISPIMG" . # 对照 lab 语料关键词
六、与 WeKnora / Lab / Cases
| RAGFlow 模块 | WeKnora 映射 | 案例 |
|---|---|---|
table_structure |
docparser 表格保护 | case-1725 |
vision/ocr |
docreader 扫描件 | case-1743 |
| 解析噪声过滤 | Excel DISPIMG | case-1785 |
| D 组表格 query | Lab corpus | parse-pitfalls.md |
对照实验:同一含表 PDF 分别 ingest WeKnora 与 RAGFlow,对比 chunk 是否含完整 <table> 或同行「表头+数值」——理解 Ch17「向上游要质量」。
七、动手练习(45–60 分钟)
| 时段 | 任务 |
|---|---|
| 0–15 min | 启动 RAGFlow,创建 Knowledge Base,选「财报/通用」模板 |
| 15–30 min | 上传 parse-pitfalls.md,在 UI 查看 chunk 预览 |
| 30–45 min | rg PDFParser 打开 pdf_parser.py,标出调用 layout → table 的两行 |
| 45–60 min | 对 queries-smoke-20.jsonl 的 D3(DISPIMG)跑一条问答,记录 chunk 是否含噪声字符串;写 3 行与 WeKnora Ch28 差异 |
章末自检
- 画出 DeepDoc 五步(版面→OCR→TSR→公式→组装)在目录上的对应
- 说清为何 Graph RAG 在
rag/graph/且标 experimental - 从
document_service.py指到pdf_parser.py的下一跳文件名 - 解释「改表格 issue 为什么要进 deepdoc 而非 retrieval」