RAGFlow 深度解读
“检索之前先把文档吃透”——深度文档理解驱动的 RAG 引擎
一句话定位
83K star 的 RAG 引擎,核心差异化在 DeepDoc 文档深度解析引擎——对 PDF 表格、扫描件 OCR、嵌套表格等 20+ 格式做专门处理,解决”垃圾进垃圾出”的文档质量根源问题。
调研元信息
| 项目 | 值 |
|---|---|
| 调研日期 | 2026-06-23 |
| 仓库 | infiniflow/ragflow |
| Stars | ~83K |
| 主语言 | Python(后端核心)/ React+TypeScript(前端) |
| 代码量 | ~2,000+ Python 文件(后端核心)+ 前端 |
| 许可证 | Apache-2.0 |
| 犀牛鸟状态 | D 线(RAG)研究项目,非直接贡献目标 |
设计哲学
核心洞察:文档理解决定 RAG 天花板
RAGFlow 的核心洞察是:RAG 系统的瓶颈往往不在检索算法,而在文档解析质量。再好的向量检索,如果把表格数据切碎了、把图片里的文字丢了,召回的就是残缺信息。
类比:其他 RAG 系统处理文档像”用吸管喝珍珠奶茶”——把所有内容当一股液体吸进来,珍珠(表格数据)、茶(正文)、奶泡(图片说明)全混在一起,检索时自然分不清。RAGFlow 的 DeepDoc 像”先用筛子把珍珠、茶、奶泡分开”,每种成分用不同方式处理——表格保留行列结构,正文按语义分段,图片先 OCR 再提取文字。
这个设计解决了企业场景中最痛的问题:一份年报 PDF 里的财务表格,如果被当成纯文本按 500 字切分,”营收”可能在一个 chunk,”23.5 亿”在另一个 chunk,检索时答案被撕裂。DeepDoc 先做版面分析识别出表格区域,保留行列关系后整体存入一个 chunk,检索质量从源头保证。
“向上游要质量”的思维
这是一种”向上游要质量”的思维——与其在检索和 Rerank 阶段做复杂补救,不如在解析阶段就把文档结构理清楚。这和 WeKnora “多路检索互补”的思路正好互补:
- RAGFlow:在文档摄入管线做极致深度解析,保证每条 chunk 都是结构完整的语义单元
- WeKnora:在检索管线做三路混合 + RRF + 复合 Rerank,保证每条查询都能找到最相关的 chunk
两种思路不矛盾。实际上,RAGFlow 的 DeepDoc + WeKnora 的三路检索是理想的组合——前端保证输入质量,后端保证检索质量。
设计取舍
RAGFlow 的设计是有意取舍的结果:
- 深度解析 vs 处理速度:DeepDoc 的深度解析带来处理速度的代价。一份复杂 PDF 的版面分析 + 表格识别 + OCR 可能需要数十秒甚至分钟级别。对于需要实时索引更新的场景是瓶颈
- 文档理解 vs 检索深度:检索管线本身相对简洁(BM25 + 向量双路,简单权重融合,单模型 Rerank),和 WeKnora 的三路检索 + RRF + 复合 Rerank 相比深度明显不足。RAGFlow 的回答是:检索不是 RAGFlow 的竞争维度——文档解析才是
- 工程资源集中:把有限的工程资源集中投入到最有差异化价值的环节。与其做一个”检索也还行”的系统,不如做一个”文档解析天下第一”的系统
核心架构详解
全局架构图
┌─────────────────────────────────────────────┐
│ RAGFlow 系统全景 │
└──────────────────┬──────────────────────────┘
│
┌──────────────────────────────────┼──────────────────────────────────┐
│ │ │
┌────────▼────────┐ ┌──────────▼──────────┐ ┌───────────▼──────────┐
│ 文档摄入管线 │ │ 检索管线 │ │ 对话/Agent 管线 │
│ Ingest Pipeline │ │ Retrieval Pipeline │ │ Conversation/Agent │
└────────┬────────┘ └──────────┬──────────┘ └───────────┬──────────┘
│ │ │
┌────────┼────────────┐ ┌──────────┼──────────┐ ┌───────────┼──────────┐
│ │ │ │ │ │ │ │ │
格式适配 DeepDoc 模板分块 BM25 向量检索 Rerank 多轮对话 引用追踪 Agent 编排
Parser Engine Template 关键词 Vector 精排 Multi- Citation Agent
20+格式 深度解析 Chunker 检索 检索 可选 turn Graph
│ │ │ │ │ │ │ │ │
└────────┼────────────┘ └──────────┼──────────┘ └───────────┼──────────┘
│ │ │
│ ┌────────────▼────────────┐ │
│ │ 权重融合 (可配置) │ │
└─────────────────────│ w_BM25 + w_Vector │◄─────────────────────┘
└────────────┬────────────┘
│
┌────────────▼────────────┐
│ LLM 生成 + 引用溯源 │
│ (chunk 来源标注) │
└─────────────────────────┘
四大子系统职责
| 子系统 | 职责 | 核心模块 |
|---|---|---|
| 文档摄入管线 | 把各种格式的”脏文档”变成结构化 chunk | 格式适配器 + DeepDoc + 模板分块 |
| 检索管线 | 双路混合检索 + Rerank | BM25 + 向量 + 权重融合 + Rerank |
| 对话/Agent 管线 | 多轮对话 + 引用追踪 + Agent 编排 | 多轮上下文管理 + 引用溯源 + Graph Agent |
| 基础设施 | 向量数据库 + 任务队列 + API/前端 | Milvus/ES + Redis/Celery + Flask/React |
DeepDoc 深度文档理解引擎
DeepDoc 是 RAGFlow 的核心差异化能力,也是整个项目最有技术深度的模块。理解了 DeepDoc,就理解了 RAGFlow 为什么能在文档解析赛道上领先。
为什么需要深度文档理解?
传统 RAG 系统对文档的处理流程是:读取文本 → 按固定长度切分 → 向量化。这个流程对结构简单的纯文本文档(如 Markdown 笔记)够用,但对企业场景中的复杂文档(年报 PDF、合同扫描件、技术手册)存在严重问题:
问题一:表格数据被撕裂。一份年报 PDF 里的财务报表,包含跨行跨列的复杂表格。按固定长度切分后,表头和数据行可能分属不同 chunk,向量检索召回的数据行缺少列名上下文,LLM 无法理解数字含义。
问题二:图片文字丢失。扫描件 PDF 中的文字以图片形式存在,纯文本提取完全拿不到内容。一份 50 页的扫描合同,传统方式只能提取到 OCR 失败的乱码或空白。
问题三:版面信息缺失。PDF 页面中标题、段落、表格、图片、页眉页脚混排。纯文本提取丢失了所有版面信息——无法区分标题和正文,无法识别表格边界,无法判断图片与哪段文字关联。
问题四:公式无法识别。学术论文中的数学公式在纯文本提取后变成一堆无意义的符号序列,丧失语义。
RAGFlow 的 DeepDoc 引擎就是为了系统性地解决这四个问题。
DeepDoc 引擎内部架构
文档输入(PDF / Word / Excel / PPT / Markdown / HTML / 图片...)
│
├─ 格式适配层(Parser Router)
│ └─ 根据文件后缀选择对应解析器
│ └─ PDF → pdf_parser, Word → docx_parser, ...
│
└─ DeepDoc 核心处理管线
│
├─ Step 1: 版面分析(Layout Analysis)
│ └─ 输入:PDF 页面图像
│ └─ 输出:每个区域的类型标注(文本/表格/图片/标题/页眉页脚)
│ └─ 模型:基于深度学习的目标检测模型
│
├─ Step 2: 文本提取(Text Extraction)
│ ├─ 对文本区域:直接提取 PDF 内嵌文本
│ └─ 对图片/扫描区域:调用 OCR 引擎
│
├─ Step 3: 表格结构恢复(Table Structure Recognition)
│ └─ 输入:表格区域图像
│ └─ 输出:行列关系 + 跨行跨列信息
│ └─ 输出格式:HTML table 或结构化 JSON
│
├─ Step 4: 公式提取(Formula Extraction)
│ └─ 识别数学公式区域
│ └─ 输出:LaTeX 表示
│
└─ Step 5: 结构化内容组装
└─ 按版面顺序组装各区域内容
└─ 保留区域间的层级关系(标题→段落→子段落)
└─ 输出:结构化文档对象
版面分析(Layout Analysis)深度解析
版面分析是 DeepDoc 的第一步,也是最关键的一步——它决定了后续所有处理步骤的输入质量。
核心任务:给定一个 PDF 页面图像,识别出页面中每个区域的类型和边界。
检测的区域类型:
| 区域类型 | 说明 | 处理方式 |
|---|---|---|
| 文本(Text) | 正文段落 | 直接提取文本,按段落分块 |
| 标题(Title) | h1/h2/h3 层级标题 | 作为分块边界标记 |
| 表格(Table) | 包含行列结构的数据区 | 调用表格结构恢复模块 |
| 图片(Figure) | 插图、图表 | OCR 提取文字说明 + 图片描述 |
| 页眉(Header) | 页码、章节标记 | 通常过滤掉 |
| 页脚(Footer) | 页码、版权信息 | 通常过滤掉 |
| 脚注(Footnote) | 底部注释 | 保留,关联到引用位置 |
| 列表(List) | 有序/无序列表 | 保持列表完整性 |
技术实现:RAGFlow 使用基于深度学习的目标检测模型(类似 YOLO / Mask R-CNN 的架构)来做版面分析。模型在大量标注了区域类型的文档数据集上训练,能够识别不同排版风格下的区域边界。
类比:版面分析像”看一眼就知道这页纸上哪里是标题、哪里是正文、哪里是表格”——你不需要逐字阅读,只需要看排版就能判断。DeepDoc 的版面分析模型就是在模拟这个”一眼看排版”的认知过程。
版面分析的难点:
难点一:复杂排版。双栏排版、图文混排、表格内嵌图片——这些情况下区域的边界不清晰。双栏排版中左栏末尾和右栏开头在空间上不相邻,但在语义上是连续的。
难点二:表格边界识别。有些表格没有明显的边框线,只靠对齐和间距来暗示行列关系。版面分析需要正确识别出”这是一个表格”而不仅仅是”这是一段文本”。
难点三:跨页元素。一个表格可能横跨两页,版面分析需要把两个页面上的表格片段关联起来。
OCR 管线深度解析
当版面分析识别出图片区域或扫描件时,DeepDoc 会调用 OCR 引擎提取文字。
OCR 处理流程:
输入图像
│
├─ 1. 图像预处理
│ └─ 去噪(高斯模糊 / 中值滤波)
│ └─ 倾斜校正(检测文本行角度,旋转校正)
│ └─ 二值化(灰度 → 黑白,增强对比度)
│
├─ 2. 文本检测(Text Detection)
│ └─ 检测图像中所有文字区域的边界框
│ └─ 模型:DBNet / PSENet 等场景文字检测模型
│
├─ 3. 文本识别(Text Recognition)
│ └─ 对每个检测到的文字区域,识别具体文字内容
│ └─ 模型:CRNN / SVTR / TrOCR 等识别模型
│ └─ 支持中英文混合识别
│
├─ 4. 后处理
│ └─ 拼写纠错(针对 OCR 常见错误)
│ └─ 文本行排序(按照阅读顺序排列)
│ └─ 置信度过滤(低置信度结果标记待人工校验)
│
└─ 输出:提取的文字内容 + 位置信息
OCR 的特殊挑战:
挑战一:低质量扫描件。旧文档的扫描件可能模糊、有噪点、墨迹不均匀。DeepDoc 的图像预处理步骤尝试缓解这些问题,但极端低质量的扫描件仍然可能产生大量 OCR 错误。
挑战二:中英文混排。合同、技术文档经常出现中英文混排——一段中文中夹杂英文术语、人名、编号。OCR 引擎需要在中英文之间正确切换识别模式。RAGFlow 的 OCR 模型针对中英文混合场景做了专门优化。
挑战三:手写文字。手写体识别是 OCR 中最难的子问题之一,目前 RAGFlow 的 OCR 主要针对印刷体,手写体识别率较低。
挑战四:印章遮挡。中国合同文档中常见红色印章覆盖在文字上方,影响 OCR 识别。DeepDoc 有印章检测和去除的预处理步骤。
OCR 与简单文本提取的本质区别:
简单文本提取(如 PyPDF2、pdfplumber)只读取 PDF 内嵌的文本层。对于”原生 PDF”(由 Word/LaTeX 生成的),这种方法效果不错。但对于”扫描件 PDF”(由扫描仪生成的图片 PDF),内嵌文本层可能:
- 完全为空(纯图片扫描件)
- 包含 OCR 错误的文本(扫描仪自带的低质量 OCR)
- 文本顺序混乱(PDF 内嵌文本的排列顺序可能与阅读顺序不一致)
DeepDoc 的 OCR 管线在简单文本提取失败时自动接管,确保即使是扫描件也能获得高质量的文本内容。
表格结构恢复深度解析
表格结构恢复是 DeepDoc 最有价值也最技术密集的模块。
核心任务:给定一个表格区域的图像,恢复出完整的行列关系,包括跨行跨列信息。
为什么表格处理这么难?
日常类比:你看到一张 Excel 截图,人眼很容易看出”第一行是表头,第二行第三行是数据,’合计’跨了三列”。但计算机看到的是一堆像素——它需要从像素中推断出哪些像素组成单元格、哪些单元格属于同一行、哪些单元格跨了多列。
传统方法(如 pdfplumber、Camelot)基于线条检测——寻找水平线和垂直线来推断行列边界。但这种方法在以下场景完全失效:
- 无边框表格(只靠对齐暗示结构)
- 虚线或浅色边框(线条检测阈值难以设定)
- 跨行跨列(线条检测无法表达跨行跨列关系)
- 合并单元格(检测到的线段不完整)
RAGFlow 的做法是使用深度学习模型直接从图像预测表格结构,不依赖线条检测。
表格结构恢复流程:
表格区域图像
│
├─ Step 1: 表格检测
│ └─ 确认区域确实是表格(而非图片或文本)
│ └─ 输出:表格边界框
│
├─ Step 2: 行列结构预测
│ └─ 模型预测每个单元格的行列位置
│ └─ 输出:N×M 的网格结构
│
├─ Step 3: 跨行跨列识别
│ └─ 识别哪些单元格跨了多行或多列
│ └─ 输出:每个单元格的 (row_start, row_end, col_start, col_end)
│
├─ Step 4: 单元格内容提取
│ └─ 对每个单元格区域做 OCR 或文本提取
│ └─ 输出:每个单元格的文字内容
│
└─ Step 5: 结构化输出
└─ 组装成 HTML table
└─ 或者输出 JSON 结构
└─ 保留完整的行列关系
表格提取的具体示例:
原始 PDF 中的一个表格:
┌──────────┬──────────┬───────────────────────┐
│ 指标 │ 2024 年 │ 2023 年 │
├──────────┼──────────┼──────────┬────────────┤
│ │ │ 上半年 │ 下半年 │
├──────────┼──────────┼──────────┼────────────┤
│ 营收 │ 100 亿 │ 40 亿 │ 60 亿 │
│ 净利润 │ 20 亿 │ 8 亿 │ 12 亿 │
└──────────┴──────────┴──────────┴────────────┘
传统文本提取可能输出:
指标 2024年 2023年 上半年 下半年 营收 100亿 40亿 60亿 净利润 20亿 8亿 12亿
所有文字混在一起,行列关系完全丢失。如果按 500 字切分,”营收”和”100 亿”可能分属不同 chunk。
DeepDoc 表格结构恢复后输出(HTML):
<table>
<tr><td>指标</td><td>2024 年</td><td colspan="2">2023 年</td></tr>
<tr><td></td><td></td><td>上半年</td><td>下半年</td></tr>
<tr><td>营收</td><td>100 亿</td><td>40 亿</td><td>60 亿</td></tr>
<tr><td>净利润</td><td>20 亿</td><td>8 亿</td><td>12 亿</td></tr>
</table>
这个 HTML 表格保留了完整的行列关系——检索时”营收”和”100 亿”始终在一起,LLM 可以准确回答”2024 年营收是多少”。
表格识别的难点:
难点一:跨行跨列。上述示例中”2023 年”跨了两列(colspan=2)。深度学习模型需要正确预测这种跨越关系。
难点二:嵌套表格。某些复杂文档中存在表格内嵌套子表格的情况,层级关系复杂。
难点三:表格内图片。某些表格的单元格中包含小图标或 sparkline(迷你图表),需要特殊处理。
公式提取
学术论文和技术文档中经常出现数学公式。公式提取的挑战在于:
- PDF 中公式的渲染方式千差万别(LaTeX 渲染、MathType 嵌入、图片公式)
- 纯文本提取后公式变成无意义的符号序列
- LLM 需要 LaTeX 表示才能理解公式的数学含义
RAGFlow 的公式提取流程:
1. 版面分析识别公式区域
2. 公式识别模型将图像转为 LaTeX
3. LaTeX 作为 chunk 内容的一部分保留
4. 检索时 LaTeX 与自然语言混合检索
这使得 RAGFlow 在学术论文场景下有显著优势——用户问”傅里叶变换的公式是什么”,RAGFlow 能召回包含完整 LaTeX 公式的 chunk,而不是一堆乱码符号。
DeepDoc 与简单文本提取的本质区别
| 维度 | 简单文本提取(PyPDF2 等) | DeepDoc 深度解析 |
|---|---|---|
| 表格 | 文字堆叠,行列关系丢失 | 保留完整行列结构(HTML table) |
| 图片文字 | 完全丢失 | OCR 提取 |
| 扫描件 | 空白或乱码 | 深度学习 OCR |
| 版面信息 | 丢失 | 区域类型标注(标题/段落/表格/图片) |
| 公式 | 乱码符号 | LaTeX 表示 |
| 跨页表格 | 截断 | 自动关联 |
| 页眉页脚 | 混入正文 | 过滤 |
| 处理速度 | 极快(毫秒级/页) | 慢(秒~分钟级/页) |
| 适用场景 | 简单纯文本文档 | 企业复杂文档 |
模板驱动分块
核心思想:不同文档类型需要不同分块策略
RAGFlow 的第二个核心创新是模板驱动分块。传统 RAG 系统对所有文档使用同一种分块策略(通常是固定长度 + overlap),但不同类型的文档结构差异巨大——学术论文和法律法规的分块逻辑不可能一样。
类比:你去裁缝店做衣服。如果裁缝对所有人都用同一套模板——不管你是高矮胖瘦——做出来的衣服大概率不合身。RAGFlow 的做法是准备了多种”衣服模板”:学术论文有论文模板、法律文书有法规模板、产品手册有手册模板。每种模板根据文档的结构特征定义不同的分块逻辑。
内置知识库模板
RAGFlow 为不同文档类型预置了分块模板:
| 模板名称 | 适用文档类型 | 分块逻辑 | 特殊处理 |
|---|---|---|---|
| 通用(General) | 混合文档 | 按段落 + 语义边界切分 | 无特殊处理 |
| 问答(Q&A) | FAQ 文档、客服话术 | 每个问答对作为一个 chunk | 问题和答案绑定,不拆分 |
| 手册(Manual) | 产品手册、操作指南 | 按章节层级(h1/h2/h3)切分 | 保留操作步骤的完整性 |
| 论文(Paper) | 学术论文 | 摘要/引言/方法/实验/结论分别切分 | 公式区域保留 LaTeX |
| 书籍(Book) | 长篇书籍 | 按章节 + 小节切分 | 章节摘要自动生成 |
| 法律(Law) | 法律法规 | 按条款切分 | 条款编号与正文绑定 |
| 演示(Presentation) | PPT/Keynote | 每页幻灯片作为一个 chunk | 图片文字 OCR + 演讲者备注 |
| 表格(Table) | Excel/CSV | 每行/每条记录作为一个 chunk | 列名作为上下文保留 |
| 图片(Picture) | 图片集合 | 每张图片 OCR 作为一个 chunk | 图片描述生成 |
Q&A 模板深度解析
Q&A 模板是最能体现”模板驱动”价值的案例。
问题:很多企业知识库的核心内容是 FAQ(常见问题解答)文档。一个 FAQ 条目包含一个问题和对应的答案,二者构成不可分割的语义单元。
传统分块的问题:按 500 字切分,一个长答案可能被切成两半——前半部分在一个 chunk,后半部分在另一个 chunk。检索时只召回了前半部分,LLM 给出不完整的答案。更糟的情况是,问题在一个 chunk 的末尾,答案在下一个 chunk 的开头——检索时可能只召回问题没召回答案,或只召回答案没召回问题。
Q&A 模板的处理:
输入 FAQ 文档:
Q: 如何重置密码?
A: 步骤一:点击登录页面的"忘记密码"链接。
步骤二:输入注册时使用的邮箱地址。
步骤三:查收重置密码的邮件,点击链接。
步骤四:设置新密码并确认。
Q&A 模板分块:
Chunk 1: {
"question": "如何重置密码?",
"answer": "步骤一:点击登录页面的"忘记密码"链接。步骤二:输入注册时使用的邮箱地址。步骤三:查收重置密码的邮件,点击链接。步骤四:设置新密码并确认。"
}
→ 整个问答对作为一个不可分割的 chunk
Q&A 模板还支持多种 FAQ 格式的自动识别:
- 标准格式:Q: … A: …
- 编号格式:1. … 答:…
- Markdown 格式:### 问题 … 答案 …
-
表格格式: 问题 答案
RAGFlow 会自动检测 FAQ 文档的格式并选择对应的解析逻辑。
法律模板深度解析
法律文书的分块逻辑与通用文档完全不同:
- 法律条文以”条”为基本单位,每条有唯一编号(如”第三十二条”)
- 条款内部可能有”款”和”项”的层级
- 引用关系频繁(”依照本法第十五条的规定”)
法律模板的处理:
输入法律文档:
第三十二条 有下列情形之一的,用人单位可以解除劳动合同:
(一)在试用期间被证明不符合录用条件的;
(二)严重违反用人单位的规章制度的;
(三)严重失职,营私舞弊,给用人单位造成重大损害的;
...
法律模板分块:
Chunk 1: {
"article": "第三十二条",
"content": "有下列情形之一的,用人单位可以解除劳动合同:\n(一)在试用期间被证明不符合录用条件的;\n(二)严重违反用人单位的规章制度的;\n(三)严重失职,营私舞弊,给用人单位造成重大损害的;\n...",
"references": ["第十五条"] // 自动识别的引用关系
}
条款编号与正文绑定,引用关系被提取出来用于后续的知识图谱构建。
论文模板深度解析
学术论文有非常明确的结构:摘要(Abstract)→ 引言(Introduction)→ 相关工作(Related Work)→ 方法(Method)→ 实验(Experiment)→ 结论(Conclusion)。
论文模板按这些结构切分,每个章节作为独立 chunk。特殊处理包括:
- 摘要单独存为一个 chunk,因为摘要是对全文的高度概括,检索命中率最高
- 方法章节中的数学公式保留 LaTeX 表示
- 实验章节中的表格保留 HTML 结构
- 引用文献单独处理,不混入正文 chunk
模板选择的自动化
RAGFlow 支持两种模板选择方式:
方式一:用户手动指定。创建知识库时选择对应的模板类型。
方式二:自动检测。RAGFlow 根据文档的特征自动推断最合适的模板:
自动检测逻辑:
1. 文件后缀 → 初步筛选
PDF → 可能是论文/法律/通用
DOCX → 可能是手册/通用
XLSX → 表格模板
PPTX → 演示模板
2. 内容特征 → 精确匹配
包含 "第X条" → 法律模板
包含 "Abstract" "Introduction" → 论文模板
包含 "Q:" "A:" → Q&A 模板
包含 "步骤一" "步骤二" → 手册模板
3. 置信度不足时 → 回退到通用模板
检索管线
双路混合检索
RAGFlow 的检索管线是 BM25 + 向量双路混合,这是 RAG 领域的标准做法。与 WeKnora 的三路检索(BM25 + 向量 + 知识图谱)相比少了一路知识图谱,但设计上更简洁。
检索流程:
用户查询 q
│
├─ BM25 关键词检索
│ └─ 对查询做分词
│ └─ 在倒排索引中查找匹配文档
│ └─ 返回 top-K_BM25 结果
│
├─ 向量语义检索
│ └─ 对查询做 embedding
│ └─ 在向量库中做 ANN 搜索
│ └─ 返回 top-K_Vector 结果
│
└─ 权重融合
└─ final_score = w × vector_score + (1-w) × bm25_score
└─ w 可配置(默认 0.7)
└─ 按融合分数排序,返回 top-N
权重融合 vs RRF 融合
RAGFlow 使用简单权重融合,WeKnora 使用 RRF 融合。两者的核心区别:
权重融合(RAGFlow):
final_score = w × vector_score + (1-w) × bm25_score
直接对不同路的分数做加权平均。问题:BM25 分数和向量余弦相似度不在同一量纲——BM25 分数范围可能是 [0, 30],余弦相似度范围是 [0.5, 0.99]。直接加权的结果被 BM25 的绝对值主导。
RAGFlow 的解决方案是对各路分数做归一化(min-max normalization),将分数映射到 [0, 1] 区间后再加权。但这引入了新的问题:归一化方式的选择本身就是一个超参数,不同归一化方式在不同数据集上表现差异大。
RRF 融合(WeKnora):
\[\text{RRF}_{\text{score}}(d) = \sum_i \frac{1}{k + rank_i(d)}\]完全忽略分数的绝对值,只看排名。排名天然是归一化的——第 1 名就是第 1 名,不管分数是 0.99 还是 25.7。这消除了量纲不一致的问题。
结论:RRF 融合在理论上更优雅、在实践中更鲁棒。但 RAGFlow 选择权重融合也有其理由——实现简单、参数可解释性强(”语义权重 70%、关键词权重 30%”比”k=60”更容易向用户解释)、在大多数场景下效果差异不大。
Rerank 精排
RAGFlow 支持可选的 Rerank 步骤,使用 Cross-Encoder 模型对融合后的 top-N 结果做精排。
RAGFlow 的 Rerank vs WeKnora 的复合 Rerank:
| 维度 | RAGFlow | WeKnora |
|---|---|---|
| 模型 | 单 Cross-Encoder 模型 | Cross-Encoder 模型 |
| 信号数 | 1(模型分) | 3(0.6 模型分 + 0.3 基础分 + 0.1 来源分) |
| 鲁棒性 | 中(模型失准无兜底) | 高(基础分和来源分兜底) |
| 可选性 | 可选(可跳过) | 必须 |
| 来源感知 | 无 | 有(source_credibility) |
RAGFlow 的 Rerank 是单模型打分——如果 Rerank 模型对某些专业术语判断失误,没有其他信号兜底。WeKnora 的三信号复合 Rerank 在这方面更鲁棒。
但 RAGFlow 的设计取舍是合理的:文档解析质量已经从源头保证了 chunk 质量,Rerank 的边际收益相对较小。与其在 Rerank 上投入工程资源,不如继续打磨 DeepDoc。
Graph RAG 实现
从文档到知识图谱
RAGFlow 在 2025 年引入了 Graph RAG 功能,支持从文档中自动构建知识图谱,并将其作为检索增强的额外信号。这是 RAGFlow 从”纯文档解析 RAG”向”知识图谱增强 RAG”演进的重要一步。
Graph RAG 的构建流程:
文档 chunks
│
├─ Step 1: 实体抽取(Entity Extraction)
│ └─ 使用 LLM 从每个 chunk 中提取命名实体
│ └─ 实体类型:人物/组织/地点/概念/产品/事件...
│ └─ 输出:每个 chunk 的实体列表
│
├─ Step 2: 关系抽取(Relation Extraction)
│ └─ 使用 LLM 识别实体间的关系
│ └─ 关系类型:属于/创建/位于/包含/影响...
│ └─ 输出:(实体A, 关系, 实体B) 三元组列表
│
├─ Step 3: 实体消歧(Entity Resolution)
│ └─ 合并指代同一实体的不同表述
│ └─ "腾讯" = "Tencent" = "腾讯公司"
│ └─ 使用语义相似度 + 规则匹配
│
├─ Step 4: 图谱存储
│ └─ 存入图数据库(Neo4j / NetworkX)
│ └─ 实体为节点,关系为边
│
└─ Step 5: 图谱索引
└─ 建立实体 → chunk 的倒排索引
└─ 预计算常用遍历路径
LLM 驱动的实体关系抽取
RAGFlow 的 Graph RAG 和 WeKnora 的 PMI 知识图谱采用了完全不同的构建策略:
| 维度 | RAGFlow Graph RAG | WeKnora PMI 图谱 |
|---|---|---|
| 抽取方式 | LLM 驱动(GPT-4/Claude 等大模型) | 统计驱动(PMI 点互信息) |
| 实体质量 | 高(理解语义,能识别隐含实体) | 中(依赖共现频率,可能遗漏低频实体) |
| 关系质量 | 高(理解语义,能识别复杂关系) | 低(只知道”有关联”,不知道”什么关系”) |
| 构建成本 | 高(每次抽取消耗 LLM token) | 低(纯统计计算,无需 LLM 调用) |
| 构建速度 | 慢(受 LLM API 限流) | 快(本地计算) |
| 可扩展性 | 受 LLM 成本限制 | 随文档量线性增长 |
| 适用场景 | 小规模高质量知识库 | 大规模文档库 |
RAGFlow Graph RAG 的 Prompt 设计(伪代码):
ENTITY_EXTRACTION_PROMPT = """
从以下文本中提取所有命名实体和它们之间的关系。
文本:{chunk_text}
请以 JSON 格式输出:
{{
"entities": [
{{"name": "实体名", "type": "人物/组织/概念/..."}},
...
],
"relations": [
{{"source": "实体A", "relation": "关系类型", "target": "实体B"}},
...
]
}}
"""
这个 Prompt 让 LLM 同时完成实体抽取和关系抽取,一次调用拿到所有信息。代价是每次调用都消耗 LLM token——如果知识库有 10,000 个 chunk,每个 chunk 一次 LLM 调用,成本可能达到数百美元。
Graph RAG 检索模式
RAGFlow 的 Graph RAG 支持两种检索模式:
模式一:实体扩展检索。从查询中提取实体,在图谱中找到关联实体,用关联实体扩展查询。
查询:"RAGFlow 的文档解析用了什么技术?"
→ 提取实体:["RAGFlow", "文档解析"]
→ 图谱遍历:RAGFlow --使用--> DeepDoc
文档解析 --包含--> 版面分析
文档解析 --包含--> OCR
文档解析 --包含--> 表格识别
→ 扩展查询:["RAGFlow", "文档解析", "DeepDoc", "版面分析", "OCR", "表格识别"]
→ 用扩展后的查询做向量检索 → 召回更全面
模式二:子图检索。从查询实体出发,提取相关子图,将子图结构作为额外上下文注入 LLM。
查询:"DeepDoc 和 WeKnora IMA 的区别?"
→ 提取实体:["DeepDoc", "WeKnora IMA"]
→ 图谱遍历:找到 DeepDoc 和 WeKnora IMA 之间的关联路径
→ 提取子图:包含两个实体的关联节点和边
→ 将子图信息作为额外上下文注入 LLM prompt
Graph RAG 的局限
RAGFlow 的 Graph RAG 目前仍处于较早阶段,有以下局限:
局限一:构建成本高。LLM 驱动的实体关系抽取成本随文档量线性增长,大规模知识库的图谱构建成本可能不可接受。
局限二:图谱质量依赖 LLM。LLM 的抽取结果不稳定——同样的文本,不同时间调用可能产出不同的实体和关系。图谱质量的一致性难以保证。
局限三:增量更新困难。文档更新时,需要重新抽取实体关系并合并到现有图谱中。实体消歧在增量场景下更加困难——新抽取的”腾讯”和图谱中已有的”腾讯公司”是否是同一实体?
局限四:与 WeKnora 图谱相比深度不足。WeKnora 的 PMI 图谱虽然关系语义较弱(只知道”有关联”),但构建成本低、可扩展性好、增量维护简单。RAGFlow 的 LLM 驱动图谱虽然关系语义更强,但成本和可维护性是短板。
多轮对话与引用追踪
多轮对话机制
RAGFlow 支持基于知识库的多轮对话,核心是上下文管理——将之前的对话历史作为额外上下文注入当前查询。
多轮对话流程:
用户第 1 轮:"RAGFlow 支持哪些文件格式?"
→ 检索知识库 → 召回相关 chunk → 生成答案 + 引用来源
用户第 2 轮:"它和 Dify 在文档解析上有什么区别?"
→ 上下文管理:
├─ 当前查询:"它和 Dify 在文档解析上有什么区别?"
├─ 对话历史:"RAGFlow 支持哪些文件格式?" + 答案
└─ 指代消解:"它" → "RAGFlow"
→ 改写查询:"RAGFlow 和 Dify 在文档解析上有什么区别?"
→ 检索知识库 → 生成答案 + 引用来源
指代消解是多轮对话的核心技术难题——用户说”它”,系统需要知道”它”指代的是上一轮对话中的哪个实体。RAGFlow 使用 LLM 做指代消解:将对话历史和当前查询一起送给 LLM,让 LLM 输出消解后的查询。
引用追踪(Citation)
RAGFlow 的另一个亮点功能是引用追踪——生成的答案中每个断言都标注了来源 chunk。
引用追踪的实现:
1. 检索阶段:记录每个 chunk 的来源文档、页码、位置
2. 生成阶段:在 Prompt 中要求 LLM 标注引用来源
Prompt: "请基于以下参考内容回答问题。在回答中,用 [1] [2] 标注每个信息的来源。"
3. 后处理:将 [1] [2] 映射到具体的 chunk 信息
[1] → 来源: 年报2024.pdf, 第 12 页, 第 3 段
[2] → 来源: 财务报告.docx, 第 5 页, 表格 2
4. 前端展示:答案中的引用标注可点击,跳转到原文对应位置
引用追踪的价值在于可验证性——用户可以点击引用标注查看原文,确认答案是否准确。这在企业场景中特别重要——财务数据、法律条文、技术规范等不能容忍幻觉的场景,引用追踪提供了”交叉验证”的能力。
Agent 编排
RAGFlow 提供了基于图的 Agent 编排能力,允许用户定义多步骤的检索-推理流程。
Agent 编排架构:
用户查询
│
└─ Agent Graph
│
├─ Start Node: 接收用户查询
│
├─ Retrieval Node: 调用知识库检索
│ └─ 可配置检索参数(知识库、top-K、权重)
│
├─ LLM Node: 调用 LLM 生成/推理
│ └─ 可配置模型、Prompt、温度
│
├─ Conditional Node: 条件判断
│ └─ "检索结果是否充分?" → 是/否分支
│
├─ Rewrite Node: 查询改写
│ └─ 当检索不充分时改写查询重新检索
│
└─ End Node: 输出最终答案
RAGFlow 的 Agent 编排相比 Dify 的可视化 Workflow 更轻量——节点类型较少,但与 RAG 的集成更紧密。适合定义”检索-判断-再检索-生成”这类 RAG 专用的推理流程。
与 WeKnora 的对比:
| 维度 | RAGFlow Agent | WeKnora Agent | Dify Workflow |
|---|---|---|---|
| 编排方式 | Graph 定义 | API/MCP 被外部调用 | 可视化 DAG |
| 节点类型 | 检索/LLM/条件/改写 | 无内建编排 | 丰富(30+ 节点类型) |
| RAG 集成 | 原生深度集成 | N/A | 知识检索节点 |
| 适合场景 | RAG 专用的多步推理 | 被其他 Agent 框架调用 | 通用 LLM 应用 |
与竞品的差异化矩阵
| 能力维度 | RAGFlow | WeKnora | Dify | AnythingLLM | FastGPT |
|---|---|---|---|---|---|
| 文档解析深度 | 极高(DeepDoc) | 高(IMA) | 中 | 低 | 中 |
| 支持格式数 | 20+ | 15+ | 10+ | 8+ | 10+ |
| 表格识别 | 深度(行列+跨行跨列) | 深度(IMA) | 基础 | 基础 | 基础 |
| OCR 能力 | 深度学习 OCR | IMA OCR | 插件 | 基础 | 基础 |
| 检索路数 | 2 路(BM25+向量) | 3 路(BM25+向量+图谱) | 2 路(BM25+向量) | 1 路(向量) | 2 路(向量+$text) |
| 融合策略 | 权重融合 | RRF(k=60) | 加权融合 | 无 | 单参数加权 |
| 知识图谱 | LLM 驱动(实验性) | PMI 自动构建 | 无 | 无 | 无 |
| Rerank | 单模型 | 三信号复合(0.6/0.3/0.1) | 单模型 | 无 | 单参数 |
| 分块策略 | 模板驱动(9 种模板) | 4 级自适应 | 固定大小 | 固定大小 | 固定大小 |
| 引用追踪 | 有(chunk 级溯源) | 无原生 | 有 | 无 | 基础 |
| Agent 编排 | Graph-based | API/MCP | 可视化 DAG | 简单 | 可视化 |
| 向量库支持 | 4+(Milvus/ES/Chroma/Qdrant) | 10 种 | 6+ | 11 | 1-2 |
| 开发语言 | Python | Go | TS/Python | Node.js | TypeScript |
| 部署门槛 | 高(4C8G+) | 中(2C4G+) | 中(2C4G+) | 极低(1C2G) | 中 |
| 社区规模 | 83K star | 14.3K star | 144K star | 61K star | 28K star |
RAGFlow 的竞争身位:
- 文档解析维度:绝对领先。DeepDoc 的深度解析能力是所有竞品中最强的
- 检索质量维度:中等。双路混合 + 权重融合 + 单模型 Rerank,和 WeKnora 的三路检索 + RRF + 复合 Rerank 有明显差距
- 平台能力维度:中等偏上。有 Agent 编排、引用追踪、多轮对话,但不如 Dify 的可视化 Workflow 成熟
- 部署便利维度:偏低。DeepDoc 的计算资源需求高,最低 4C8G 的门槛是五个项目中最高的
核心结论:RAGFlow 在”文档解析”这个维度上是赛道第一,但这个领先不是全方位的——在”检索质量”和”平台生态”维度上分别弱于 WeKnora 和 Dify。
源码关键实体索引
| Python 模块 / 文件 | 核心功能 | 关键类/函数 |
|---|---|---|
deepdoc/parser/ |
格式适配器路由 | ParserFactory, get_parser() |
deepdoc/parser/pdf_parser.py |
PDF 深度解析核心 | PDFParser, parse(), 调用版面分析+OCR+表格 |
deepdoc/parser/docx_parser.py |
Word 文档解析 | DocxParser, 提取段落/表格/图片 |
deepdoc/parser/excel_parser.py |
Excel 解析 | ExcelParser, 按行提取+列名保留 |
deepdoc/parser/ppt_parser.py |
PPT 解析 | PptParser, 每页提取+OCR |
deepdoc/vision/layout.py |
版面检测模型 | LayoutRecognizer, detect() |
deepdoc/vision/ocr.py |
深度学习 OCR | OCRRecognizer, recognize() |
deepdoc/table/table_structure.py |
表格结构恢复 | TableStructureRecognizer, recognize() |
deepdoc/formula/ |
公式提取与 LaTeX 转换 | FormulaRecognizer, to_latex() |
rag/retrieval/hybrid.py |
BM25 + 向量混合检索 | HybridRetriever, retrieve() |
rag/retrieval/bm25.py |
BM25 关键词检索 | BM25Retriever, search() |
rag/retrieval/vector.py |
向量语义检索 | VectorRetriever, search() |
rag/chunking/intelligent.py |
基于文档结构的智能分块 | IntelligentChunker, chunk() |
rag/chunking/template.py |
模板驱动分块 | TemplateChunker, 各种模板实现 |
rag/rerank/ |
可选 Rerank | Reranker, rerank() |
rag/graph/ |
Graph RAG 构建与检索 | GraphBuilder, GraphRetriever |
api/apps/ |
后端业务逻辑入口 | Flask 路由,知识库/对话/文档管理 |
agent/ |
Agent 编排 | AgentGraph, 节点定义与执行 |
web/ |
前端 React 应用 | 知识库管理/对话/Agent 编排 UI |
关键调用链:
文档摄入调用链:
api/apps/document_app.py (上传接口)
→ deepdoc/parser/ (格式适配)
→ deepdoc/vision/layout.py (版面分析)
→ deepdoc/vision/ocr.py (OCR)
→ deepdoc/table/table_structure.py (表格识别)
→ rag/chunking/template.py (模板分块)
→ rag/embedding/ (向量化)
→ Milvus/ES (存储)
检索调用链:
api/apps/conversation_app.py (对话接口)
→ rag/retrieval/hybrid.py (混合检索)
→ rag/retrieval/bm25.py (BM25)
→ rag/retrieval/vector.py (向量)
→ rag/rerank/ (Rerank)
→ LLM 生成 + 引用标注
本地代码结构
ragflow/
├── deepdoc/ # 文档深度解析引擎(核心)
│ ├── parser/ # 各格式解析器
│ │ ├── pdf_parser.py # PDF 解析(版面分析+表格识别)
│ │ ├── docx_parser.py # Word 解析
│ │ ├── excel_parser.py # Excel 解析
│ │ ├── ppt_parser.py # PPT 解析
│ │ ├── markdown_parser.py # Markdown 解析
│ │ ├── html_parser.py # HTML 解析
│ │ ├── image_parser.py # 图片解析(OCR)
│ │ └── ... # 20+ 格式
│ ├── vision/ # 视觉模型(版面检测/OCR)
│ │ ├── layout.py # 版面分析模型
│ │ ├── ocr.py # OCR 识别模型
│ │ └── layout_recognizer.py # 版面检测器封装
│ ├── table/ # 表格结构恢复
│ │ ├── table_structure.py # 表格结构识别模型
│ │ └── main.py # 表格处理入口
│ ├── formula/ # 公式提取
│ └── utils/ # 工具函数
├── rag/ # RAG 检索模块
│ ├── retrieval/ # BM25 + 向量混合检索
│ │ ├── hybrid.py # 混合检索器
│ │ ├── bm25.py # BM25 检索
│ │ └── vector.py # 向量检索
│ ├── chunking/ # 基于解析结果的智能分块
│ │ ├── intelligent.py # 智能分块
│ │ └── template.py # 模板驱动分块
│ ├── rerank/ # 可选 Rerank
│ ├── graph/ # Graph RAG
│ └── embedding/ # 向量化
├── api/ # 后端 API 服务(Flask)
│ └── apps/ # 业务逻辑入口
├── agent/ # Agent 编排
├── web/ # 前端界面(React)
├── docker/ # 容器化部署
└── conf/ # 配置文件
竞赛贡献切入点
RAGFlow 本身不是犀牛鸟直接贡献项目(那是 WeKnora 的位置),但 RAGFlow 的技术思想可以为竞赛贡献提供灵感。以下方向是将 RAGFlow 的技术优势迁移到 WeKnora 的可行路径:
方向一:DeepDoc 思想迁移——增强 WeKnora 的文档解析
WeKnora 目前使用 IMA 引擎做文档解析,但在表格结构恢复和公式提取方面可能不如 DeepDoc 深入。可以参考 DeepDoc 的表格结构恢复模型,为 WeKnora 贡献更精细的表格处理能力。
具体贡献:
- 将 DeepDoc 的表格结构恢复逻辑移植为 WeKnora Plugin
- 参考
deepdoc/table/table_structure.py的模型结构,用 Go 或 Python 实现一个表格识别 Plugin - 对比 IMA 和 DeepDoc 在不同表格类型上的识别精度
难度:高。需要理解深度学习模型并做跨语言移植。
方向二:模板驱动分块思想迁移——增强 WeKnora 的自适应分块
WeKnora 有 4 级自适应分块(auto → heading → heuristic → recursive → legacy),但没有 RAGFlow 那样针对不同文档类型的专门模板。可以为 WeKnora 贡献 Q&A / 法律 / 论文等模板分块 Plugin。
具体贡献:
- 参考 RAGFlow 的
rag/chunking/template.py实现 - 为 WeKnora 写一个
TemplateChunkerPlugin - 支持至少 3 种文档类型的模板分块
- 在 RAGAS 评估中对比模板分块 vs WeKnora 默认自适应分块的效果差异
难度:中。模板分块的逻辑相对简单,核心挑战是 Plugin 的 EventManager 集成。
方向三:引用追踪功能
RAGFlow 的引用追踪(Citation)是一个用户价值很高的功能——用户可以点击答案中的引用标注跳转到原文。WeKnora 目前没有原生引用追踪功能。
具体贡献:
- 在 WeKnora 的检索结果中附加 chunk 的来源元数据(文档名、页码、位置)
- 在生成 Prompt 中加入引用标注要求
- 在前端展示引用标注和跳转链接
- 参考 RAGFlow 的
rag/citation/模块实现
难度:中低。引用追踪的实现相对简单,核心是元数据传递和 Prompt 设计。
方向四:RAGFlow + WeKnora 集成评估
RAGFlow 的 DeepDoc 做极致文档解析 + WeKnora 的三路检索做极致检索质量——两者组合是否 1+1>2?这是一个有学术价值的实验问题。
具体贡献:
- 用 RAGFlow DeepDoc 解析一组企业文档,生成高质量 chunk
- 将 chunk 导入 WeKnora,走三路检索 + RRF + 复合 Rerank
- 对比四种配置的 RAGAS 评估结果:
- A: RAGFlow 解析 + RAGFlow 检索(基线)
- B: WeKnora 解析 + WeKnora 检索
- C: RAGFlow 解析 + WeKnora 检索(组合方案)
- D: WeKnora 解析 + RAGFlow 检索
- 写消融实验报告,量化文档解析质量对检索质量的边际贡献
难度:中。需要搭建两套系统并准备评估数据集,但不需要深度修改源码。
方向五:Graph RAG 改进
RAGFlow 的 Graph RAG 目前使用 LLM 驱动的实体关系抽取,成本高且不稳定。可以探索将 WeKnora 的 PMI 统计方法与 RAGFlow 的 LLM 方法结合——PMI 做初始图谱构建(低成本),LLM 做关系类型标注(高精度)。
具体贡献:
- 在 RAGFlow 的 Graph RAG 中引入 PMI 预筛选
- 先用 PMI 找到高共现实体对,再用 LLM 标注关系类型
- 对比全 LLM 抽取 vs PMI 预筛选+LLM 标注的成本和精度
- 如果效果验证,可贡献回 RAGFlow 社区
难度:中高。需要理解两种图谱构建方法并做融合设计。
交叉引用
| 相关页面 | 关系 |
|---|---|
| RAG 知识库全景 | RAGFlow 在 5 项目比较中的定位 |
| 跨项目深度分析 | 文档解析能力 / 检索管线的跨项目比较 |
| WeKnora 精读 | RAGFlow 文档解析 vs WeKnora 检索深度的互补分析 |
| WeKnora 竞赛贡献指南 | RAGFlow 技术思想迁移到 WeKnora 的具体路径 |
| Agentic RAG 模式 | RAGFlow Agent 编排在 6 种模式中的位置 |
| RAG 评估方法论 | RAGAS 评估如何应用于 RAGFlow vs WeKnora 对比 |
| RAG Agent 集成 | RAGFlow 作为检索后端与 Agent 框架的集成模式 |
| 选型决策树 | 什么场景选 RAGFlow(PDF/表格密集 → RAGFlow) |
| Memory vs RAG 边界 | D 线(RAG)与 B 线(Memory)的分工——RAGFlow 处理外部文档检索,Memory 系统处理对话记忆 |
| 腾讯记忆生态 | RAGFlow 在腾讯 DB-Agent-Memory 生态中的定位——文档理解层,与 WeKnora 检索层互补 |
局限性与场景边界
处理速度瓶颈
DeepDoc 的深度解析带来处理速度的代价。具体数据(参考值,取决于硬件和文档复杂度):
| 文档类型 | 页数 | DeepDoc 处理时间 | 简单文本提取时间 |
|---|---|---|---|
| 纯文本 PDF(10 页) | 10 | ~5 秒 | <1 秒 |
| 含表格 PDF(10 页) | 10 | ~30 秒 | <1 秒 |
| 扫描件 PDF(10 页) | 10 | ~60 秒 | N/A(提取为空) |
| 复杂年报 PDF(50 页) | 50 | ~5 分钟 | <5 秒 |
| Markdown 文档 | - | <1 秒 | <1 秒 |
对于需要实时索引更新的场景(如知识库频繁编辑),DeepDoc 的处理速度是瓶颈。RAGFlow 的应对策略是异步处理——文档上传后放入任务队列,后台解析完成后通知用户。
纯文本文档的”杀鸡用牛刀”问题
对于纯文本文档(如 Markdown 笔记、代码注释),DeepDoc 的深度解析反而是过度处理——额外的版面分析步骤没有价值但增加了延迟。
RAGFlow 的应对策略是格式适配器路由——根据文件后缀选择解析器。Markdown 文件直接走 markdown_parser.py(简单解析),不经过 DeepDoc 的版面分析管线。
检索管线深度不足
RAGFlow 的检索管线(BM25 + 向量 + 权重融合 + 单模型 Rerank)在文档质量已经很好的场景下(如结构化的 Markdown 知识库),与 WeKnora 的三路检索 + RRF + 复合 Rerank 相比,检索质量有明显差距。具体差距体现在:
- 缺少知识图谱第三路 → 多跳推理能力弱
- 权重融合 vs RRF → 量纲不一致问题
- 单模型 Rerank → 无兜底信号,模型失准时无保障
- 无来源可信度评分 → 官方文档和用户笔记一视同仁
社区与生态
RAGFlow 的 83K star 说明社区活跃度高,但在以下方面不如 Dify:
- 插件市场:Dify 有丰富的社区插件,RAGFlow 的插件生态较小
- 可视化编排:Dify 的 Workflow DAG 是最成熟的,RAGFlow 的 Agent Graph 相对简单
- 文档完善度:Dify 的官方文档更全面,RAGFlow 的文档在部分高级功能上缺失
学习建议
源码阅读路线
如果你是第一次接触 RAGFlow 的源码,建议按以下顺序阅读:
- 先读
deepdoc/parser/——理解各种格式如何被适配和路由 - 再读
deepdoc/vision/layout.py——理解版面分析的核心逻辑 - 然后读
deepdoc/table/table_structure.py——理解表格结构恢复,这是 DeepDoc 最有技术深度的模块 - 接着读
deepdoc/vision/ocr.py——理解 OCR 管线的实现 - 再读
rag/chunking/template.py——理解模板驱动分块的设计 - 然后读
rag/retrieval/hybrid.py——理解双路混合检索的实现 - 最后读
rag/graph/——理解 Graph RAG 的构建与检索
每个模块大约需要 1-2 小时精读。总计约 10-15 小时。
对比学习路线
为了更深入理解 RAGFlow 的设计取舍,建议与 WeKnora 做对比阅读:
| 阅读维度 | RAGFlow 模块 | WeKnora 模块 | 对比重点 |
|---|---|---|---|
| 文档解析 | deepdoc/ |
IMA 引擎 | 哪些场景谁的解析更好? |
| 分块策略 | rag/chunking/template.py |
pkg/chunker/ |
模板驱动 vs 自适应降级链 |
| 检索融合 | rag/retrieval/hybrid.py |
pkg/fusion/ |
权重融合 vs RRF |
| Rerank | rag/rerank/ |
pkg/rerank/ |
单信号 vs 三信号 |
| 知识图谱 | rag/graph/ |
pkg/retriever/graph/ |
LLM 驱动 vs PMI 统计 |
实践建议
- 部署 RAGFlow:用 Docker Compose 一键部署,上传一份含表格的 PDF 体验 DeepDoc 的效果
- 对比实验:同一份 PDF 分别用 RAGFlow 和 WeKnora 解析,对比 chunk 质量
- 模板定制:尝试为特定文档类型(如公司内部模板)定制分块模板
- Graph RAG 实验:上传一组相关文档,构建知识图谱,对比 Graph RAG 和普通检索的效果差异
- RAGAS 评估:用 RAGAS 对 RAGFlow 和 WeKnora 做端到端评估,量化文档解析对检索质量的边际贡献
进阶研究方向
- DeepDoc 模型优化:版面分析和表格识别模型的推理速度优化(量化、剪枝、蒸馏)
- 增量文档更新:当文档只修改了一小部分时,如何避免全量重新解析
- 跨模态检索:图文混排文档中,如何同时检索文字内容和图片语义
- 领域自适应:在特定行业(医疗、法律、金融)上微调版面分析和 OCR 模型
- 多语言支持:DeepDoc 在中文场景的优化较多,其他语言(日文、韩文、阿拉伯文)的支持需要额外工作
证据等级
| 来源 | 标签 |
|---|---|
| RAGFlow 源码 deepdoc/rag/ 目录 | [源码] |
| RAGFlow GitHub README / 官方文档 | [文档] |
| deep-dive-weknora.md RRF/Rerank 参数 | [已有] |
| rag-knowledge-landscape.md 横评 | [已有] |
| deep-dive.md 跨项目分析 | [已有] |
| Graph RAG 论文(微软) | [社区] |
| DeepDoc 技术博客 | [社区] |
| 未实测 | 以源码/docs/社区为准 |