# RAGFlow 技术架构与实现原理 RAGFlow 是四家里**架构最重、解析能力最强、也是踩坑最多**的一个。它的招牌是 **DeepDoc**(自研文档解析:OCR + 版式 + 表格),这让它在扫描/图像文档上独一档;但代价是镜像最大(~16GB)、容器最多、v0.26 还有模型自配置的回归 bug。本文拆解它的技术栈、DeepDoc 原理、数据流与 task_executor 架构——所有结论来自对其容器、源码(`/ragflow/rag/...`)、MySQL 表、API 行为的一手观察。 ## 一、技术栈 | 层 | 选型 | 说明 | |---|---|---| | 后端 | **Python(API/调度)+ Go(部分解析/检索)** | 双语言,Python 为主 | | 文档解析 | **DeepDoc(自研)** | OCR + 版式分析 + 表格识别,不依赖外部 OCR 服务 | | 全文/向量检索 | **Elasticsearch 或 Infinity**(可切换) | 实测部署用 ES(ragflow-es01 容器,9200) | | 关系库 | **MySQL** | 存 dataset / document / 用户 / 模型配置(`llm_factories` 表是坑点) | | 对象存储 | **MinIO** | 存原始文档文件 | | 缓存/队列 | **Redis** | 任务队列 | | 任务执行 | **task_executor(独立进程)** | 消费解析+embedding 任务 | | 部署 | docker-compose,**5 个容器**(ragflow / es01 / mysql / minio / redis) | 镜像总体积 ~16GB,ragflow 单镜像 12.2GB | RAGFlow 的"重"是设计权衡——为了 DeepDoc 的解析能力,它带了完整的 ES + MinIO + 自己的解析管线,每一样都不能省。 ## 二、DeepDoc:RAGFlow 的护城河 DeepDoc 是 RAGFlow 区别于其他三家的核心。它在文档解析的几个层次都自研: 1. **OCR**:对**无文本层**的图像/扫描件,DeepDoc 自己 OCR 出文本。这是它在 DocVQA 实测中拿到 76%(另三家 0–10%)的根本原因——**只有 RAGFlow 能把扫描件转成可检索文本**。 2. **版式分析**:识别标题、段落、页眉页脚、多栏布局,按版式切块而不是机械地按字数切。 3. **表格识别**:把 PDF 里的表格还原成结构化内容(行列对齐),这对 datasheet、财报这类表格密集文档很关键。 DeepDoc 默认 OCR 是**可关的**——对纯文本 PDF,它会走轻量解析分支(实测 CUAD 的 SEC 合同走的就是 `split_model.parse()` 兜底,不走 OCR)。这解释了横评里的"反转": - **文本型 PDF(CUAD)**:DeepDoc 的 OCR/版式强项**用不上**,差异落在切片粒度,RAGFlow 反而最低(80%)。 - **扫描/图像文档(DocVQA)**:DeepDoc 的 OCR **决定性**,RAGFlow 碾压(76% vs 0–10%)。 DeepDoc 不是"处处最强",而是"复杂文档最强"。这是选型时必须想清楚的点。 ## 三、数据流:从上传到可检索 RAGFlow 的灌库是**多阶段异步 pipeline**,每一步都有独立的任务状态: ``` [上传文件] │ POST /api/v1/datasets//documents (multipart file) ▼ → MinIO 存原始文件, MySQL document 表建记录, run='TODO' [触发解析] │ POST /api/v1/datasets//chunks {document_ids:[...]} ▼ → document.run='RUNNING', 进 task_executor 队列 [task_executor 消费] │ ① DeepDoc 解析: OCR(若需) + 版式分析 + 表格识别 → 出 pages │ ② _bind_embedding_model: 检查 dataset 是否绑了 embedding 模型 │ (没绑就 FAIL: "No default embedding model is set") │ ③ 切块(chunking) → 出 chunks │ ④ 对每个 chunk 调 Ollama/配置的 embedding → 向量 ▼ → ES 索引建立, document.run='DONE' [检索] POST /api/v1/retrieval {dataset_ids, question, page_size, similarity_threshold} → ES 做向量+全文混合检索, 返回 chunks(含 document_keyword=来源文件名) ``` 几个实测要点: - **解析是异步的**,上传后要轮询 `GET /datasets//documents` 看 `run` 字段(TODO → RUNNING → DONE/FAIL)。DeepDoc 对复杂 PDF 慢(实测 50 份 SEC 合同 ~20 分钟,DocVQA 图像 ~10 分钟)。 - **dataset 必须绑 embedding 模型**:通过 UI 建的 dataset 会自动绑,但**通过 API 建(`POST /datasets {name}`)的 dataset 默认不绑**,解析时会 FAIL 报 "No default embedding model is set"。要 `PUT /datasets/ {embedding_model:"qwen3-embedding:4b@Ollama"}` 手工绑。 - `chunk_method`(naive / book / paper / laws ...)决定切块策略,不同文档类型选不同的能提升召回。 ## 四、v0.26 的模型自配置 bug(重要) 这是 RAGFlow 最坑的版本回归。`api/db/init_data.py:144` 的 `init_llm_factory()` 在 v0.26 **被官方注释掉**了,导致 `llm_factories` 厂商表未种子化。后果: - `GET /v1/llm/factories` 返回 **0 条**。 - `add_llm` 报 `"factory Ollama is not allowed"`。 - `set_api_key` 报 `"No models configured"`。 **API 自配模型走不通**,必须手工导 `conf/llm_factories.json` 到 MySQL,或走 UI 配。这对纯 API 自动化是硬伤——也是它在横评"API 摩擦度"拿 ★★★★ 的主因。这是 bug 不是设计,但选 v0.26 就得认。 ## 五、检索:ES 混合检索 RAGFlow 的检索走 ES(或 Infinity),支持: - **向量召回**(dense retrieval):用配置的 embedding 模型向量化 query,做 ANN 检索。 - **全文召回**(sparse/BM25):ES 的全文检索能力。 - **重排**(rerank):可配 rerank 模型(如 bge-reranker)对召回结果二次排序。 `/api/v1/retrieval` 的返回里,每个 chunk 带 `document_keyword`(来源文件名)、`content`、`score`、`docnm_kwd` 等。`similarity_threshold` 控制召回下限。 实测 RAGFlow 的检索延迟(0.89s)比 Dify(0.38s)和 FastGPT(0.41s)慢——ES 的查询开销 + 重排链路比 pgvector 直查重。但它的检索质量在"有表格/扫描"的场景下最高。 ## 六、为什么 RAGFlow "重但不可替代" 回到横评,RAGFlow 的画像很清晰: - **文本类任务(TechQA/CMRC)**:90% / 80%,不拔尖。它的切片/检索在"找对文档"上不如 MaxKB/Dify 稳。 - **文本型 PDF(CUAD)**:80%,最低。DeepDoc 强项用不上,被切片拖累。 - **扫描/图像(DocVQA)**:**76%,碾压**。唯一带 OCR。 - **建库最快(70s for 646 篇)**:它的批量 embedding 管线效率高(这点出乎意料,镜像最重但建库最快)。 - **资源最重**:16GB 镜像、5 容器、ES 吃内存。 RAGFlow 的定位是**"文档解析专家"**——如果你的知识库有大量 PDF(尤其扫描件、表格、复杂版式),它不可替代;如果是纯文本/简单 PDF,它 overkill 且不占优。 ## 七、API 自动化的现实 RAGFlow 的 API(`/api/v1`,鉴权用 RSA 加密密码): - 登录:密码需用容器内 `/ragflow/conf/public.pem` 做 RSA crypt 加密(不是简单 hash)。 - 数据集 CRUD、检索都正常。 - **模型自配受阻**(v0.26 bug),必须手工导 DB 或走 UI。 对自动化集成,RAGFlow 适合"配一次(UI)、之后只 API 灌库+检索"的模式,不适合"完全 API 从零起"。 ## 八、扩展性 RAGFlow 的多服务架构(ES/MySQL/MinIO/Redis/task_executor 分离)让它在**横向扩展**上是四家里最强的——ES 可扩成集群、task_executor 可多实例并行解析、MinIO 可分布式。这是它"重"换来的好处:适合大规模(百万级文档、高并发)的生产场景。 代价是运维复杂度——5 个容器、ES 的调优、DeepDoc 的资源消耗,都需要专人。对中小团队这是负担,对大规模企业这是值得的投资。 总结一句:**RAGFlow 是为"复杂文档 + 大规模"而生的,简单场景用它又重又不占优,复杂场景没它不行。**它的架构和 DeepDoc 完全围绕这个定位展开。