Featured image of post RAGFlow 深度解析:为什么它是最值得关注的 RAG 开源项目

RAGFlow 深度解析:为什么它是最值得关注的 RAG 开源项目

RAGFlow 不只是另一个 RAG 框架,它的核心价值在于 DeepDoc 文档理解引擎和开箱即用的企业级设计。

过去两年,RAG 领域涌现了无数框架:LangChain、LlamaIndex、Haystack……它们各有侧重,但解决的核心问题相似——如何让 LLM 接地气。

但如果你实际做过企业级 RAG 项目,会发现一个被忽视的问题:文档解析

大部分框架默认你已经有干净、结构化的文本。现实却是:PDF 扫描件、嵌套表格、数学公式、多栏排版……这些"脏活累活"往往占据项目 60% 以上的时间。

RAGFlow 的定位很明确:从文档到答案的全流程解决方案,而不是又一个"需要你自己处理文档"的检索框架。

这篇文章会深入分析 RAGFlow 的设计思路、核心技术和适用场景。

一、RAGFlow 的差异化定位

现有框架的盲区

LangChain 和 LlamaIndex 的设计假设是:

输入:干净的文本 / 简单的 PDF
处理:Chunk → Embed → Retrieve → Generate
输出:答案

但企业真实场景是:

输入:扫描件 PDF、带表格的年报、技术手册、合同......
预处理:OCR、布局分析、表格识别、公式识别......
处理:Chunk → Embed → Retrieve → Generate
输出:答案 + 引用

预处理阶段的复杂度,往往被框架忽略。

RAGFlow 的思路

RAGFlow 的核心定位:

不只是 RAG 框架,而是"文档理解 + RAG"的一体化方案

它的技术栈覆盖:

阶段能力技术方案
文档解析OCR、布局分析、表格识别DeepDoc(自研)
文档切分8 种切分策略按文档类型选择
检索向量 + 关键词 + Rerank混合检索 + RRF 融合
生成多模型支持OpenAI、Qwen、Ollama 等
运维可视化 UI、API、监控企业级特性

一句话总结:RAGFlow 解决的是"从 PDF 到答案"的完整链路,而不是"从文本到答案"。

二、DeepDoc:RAGFlow 的核心护城河

DeepDoc 是 RAGFlow 自研的文档理解引擎,也是它区别于其他框架的核心竞争力。

为什么需要 DeepDoc

传统 PDF 解析的问题:

问题 1:OCR 质量差

原文:错误码 E0028
OCR 结果:错误码 E002B(8 被识别成 B)

用户问:错误码 E0028 是什么意思
检索:找不到(因为文档里是 E002B)

问题 2:布局信息丢失

原文(两栏排版):
┌──────────────┬──────────────┐
│ 左栏内容      │ 右栏内容      │
│ 跨多行...    │ 跨多行...    │
└──────────────┴──────────────┘

普通解析结果:
左栏内容
右栏内容  ← 两栏混在一起,语义被打断

问题 3:表格结构破坏

原文表格:
┌────────┬────────┬────────┐
│ 参数    │ 类型    │ 说明    │
├────────┼────────┼────────┤
│ timeout│ int    │ 超时时间│
│ retry  │ bool   │ 是否重试│
└────────┴────────┴────────┘

普通解析结果:
参数 类型 说明 timeout int 超时时间 retry bool 是否重试
← 变成一行,结构全丢了

DeepDoc 的技术方案

DeepDoc Pipeline:

┌──────────┐    ┌──────────┐    ┌──────────────┐
│  Input   │───▶│  Layout  │───▶│   OCR Engine │
│  File    │    │  Analysis│    │  (PaddleOCR) │
└──────────┘    └──────────┘    └──────┬───────┘
                ┌──────────────────────┘
┌──────────────────────────────────────────────┐
│           Structure Recognition               │
│  ┌──────────┐ ┌──────────┐ ┌──────────────┐  │
│  │  Table   │ │  Figure  │ │   Formula    │  │
│  │  Parser  │ │  Parser  │ │   Parser     │  │
│  └──────────┘ └──────────┘ └──────────────┘  │
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
│           Semantic Understanding              │
│  • 标题识别                                   │
│  • 章节分割                                   │
│  • 关系提取                                   │
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
│           Markdown / Structured Output        │
└──────────────────────────────────────────────┘

核心技术点

模块技术方案解决的问题
OCRPaddleOCR高精度文字识别
布局分析YOLO/LayoutLM检测文本、表格、图片区域
表格识别Table-Transformer还原表格结构
公式识别LaTeX-OCR数学公式转 LaTeX
图片描述VLM生成图片文字描述

表格识别的原理

表格是最难处理的文档元素之一。DeepDoc 的表格识别流程:

Step 1: 表格检测
用目标检测模型定位表格区域

Step 2: 结构识别
Table-Transformer 识别:
- 行边界
- 列边界
- 单元格合并关系

Step 3: 内容识别
对每个单元格做 OCR

Step 4: 结构化输出
┌────────┬────────┐
│ A1     │ A2     │   →   [{"row":1,"col":1,"text":"A1"}, ...]
├────────┼────────┤
│ B1     │ B2     │
└────────┴────────┘

为什么这件事重要

如果表格结构丢了,用户问"参数 timeout 的类型是什么",系统找不到答案——因为表格已经变成一团乱码。

与其他解析方案的对比

方案OCR布局分析表格识别公式识别
PyPDF2
pdfplumber⚠️ 基础⚠️ 基础
Unstructured⚠️ 外部⚠️ 基础
DeepDoc

DeepDoc 是目前开源方案中对复杂文档支持最完整的。

三、Chunking 策略:一种文档一种切法

RAGFlow 提供了 8 种 Chunking 策略,针对不同文档类型:

为什么需要多种策略

不同类型文档的结构差异很大:

FAQ 文档:
Q: 问题
A: 答案
─────────
每个 QA 对是独立的语义单元

技术手册:
## 安装
步骤 1...
步骤 2...
## 配置
参数 1...
参数 2...
─────────
按章节切分,保留标题上下文

法律文档:
第一条 ...
第二条 ...
第三条 ...
─────────
按条款切分,每条有独立法律意义

用同一种"固定长度切分"处理所有文档,效果必然不好。

RAGFlow 的 8 种策略

策略适用文档切分依据
Naive简单文本固定字符数
Q&AFAQ 文档问题-答案对
Book书籍、长文档章节层级
Manual技术手册小节
Law法律、合同条款
Paper学术论文摘要、章节
Table表格数据行/单元格
Picture图片VLM 描述

核心思路:保留语义完整性

无论哪种策略,核心原则相同:一个 chunk 应该能独立回答一个问题

以 Book Chunking 为例:

原始文档:
# 第一章 概述
## 1.1 背景
文本内容...
## 1.2 目标
文本内容...
# 第二章 设计
## 2.1 架构
文本内容...

切分结果:
Chunk 1: 【第一章 概述 > 1.1 背景】文本内容...
Chunk 2: 【第一章 概述 > 1.2 目标】文本内容...
Chunk 3: 【第二章 设计 > 2.1 架构】文本内容...

关键设计:把父级标题拼到 chunk 前面

这样做的原因我在 RAG 进阶篇详细讲过:Embedding 只能看到 chunk 内部的文字。如果 chunk 里没有"第一章"、“概述”、“背景"这些关键词,用户问"第一章的背景是什么"时就召不回。

Table Chunking 的特殊性

表格数据的切分需要特殊处理:

方案 1:行级切分
每行一个 chunk,保留表头

方案 2:单元格级切分
每个单元格一个 chunk,附带行列信息

RAGFlow 的做法:
- 检测表格结构
- 保留表头作为上下文
- 行级切分
- 每个 chunk 包含:表头 + 该行内容

示例:
原始表格:
| 参数 | 类型 | 说明 |
|------|------|------|
| timeout | int | 超时时间 |

切分后的 chunk:
【表:API 参数配置】
参数: timeout | 类型: int | 说明: 超时时间

这样用户问"timeout 参数的类型是什么”,就能精确召回这一行。

四、检索架构:混合检索 + RRF 融合

RAGFlow 的检索架构是标准的混合检索方案:

整体架构

Query
  ├─── 向量检索(Dense)───┐
  │                       │
  ├─── 关键词检索(BM25)──┤──→ RRF 融合 ──→ Rerank ──→ Top-K
  │                       │
  └─── Metadata 过滤 ─────┘

RRF 融合算法

RRF(Reciprocal Rank Fusion)的核心思想:不依赖分数,只依赖排名

RRF 公式:
score(d) = Σ 1 / (k + rank_i(d))

其中:
- d:文档
- rank_i(d):文档 d 在第 i 路检索中的排名
- k:平滑参数(通常 60)

为什么有效

问题:向量分数(0.82)和 BM25 分数(5.2)不在同一尺度

传统方案:
- 分数归一化:复杂,不稳定
- 加权融合:权重难调

RRF 的做法:
- 不管分数多少
- 只看排名
- 排名第 1 → 得分 1/61
- 排名第 2 → 得分 1/62
- 两路都召回的文档,得分更高

示例

Query:"错误码 401"

向量检索:
#1 Doc_A
#2 Doc_B
#3 Doc_C

BM25 检索:
#1 Doc_D
#2 Doc_C  ← 两路都有
#3 Doc_A  ← 两路都有

RRF 融合:
Doc_C: 1/(60+3) + 1/(60+2) = 0.032  ← 最高
Doc_A: 1/(60+1) + 1/(60+3) = 0.032
Doc_B: 1/(60+2) + 0 = 0.016
Doc_D: 0 + 1/(60+1) = 0.016

两路都召回的文档,得分更高,自然排在前面。

Rerank 实现

RAGFlow 内置 Cross-Encoder Rerank:

原理:
Query + Document → Transformer → Relevance Score

为什么比向量检索更准:
- 向量检索:Query 和 Document 各自编码,交互少
- Cross-Encoder:Query 和 Document 拼在一起编码,充分交互

支持的 Rerank 模型:

模型特点延迟(100 候选)
bge-reranker-v2-m3多语言,效果好~180ms
bge-reranker-large效果好~150ms
ms-marco-MiniLM轻量,快速~45ms

Rerank 的成本很高,只能对小规模候选做精排。RAGFlow 的默认配置:

召回:top-50(向量 + BM25)
Rerank:top-50 全部重排
输出:top-5

五、与其他框架的对比

功能对比

维度RAGFlowLangChainLlamaIndex
文档解析⭐⭐⭐⭐⭐ DeepDoc⭐⭐⭐ 基础⭐⭐⭐ 基础
Chunking⭐⭐⭐⭐⭐ 8 种策略⭐⭐⭐ 需自己实现⭐⭐⭐⭐ 较丰富
检索⭐⭐⭐⭐⭐ 混合 + RRF⭐⭐⭐ 需组合⭐⭐⭐⭐ 较完整
可视化 UI⭐⭐⭐⭐⭐ 完整⭐⭐ LangSmith⭐⭐⭐ LlamaCloud
开箱即用⭐⭐⭐⭐⭐ 高⭐⭐⭐ 需组装⭐⭐⭐⭐ 较高
自定义扩展⭐⭐⭐ 中等⭐⭐⭐⭐⭐ 高⭐⭐⭐⭐⭐ 高

架构理念对比

RAGFlow:应用导向
"我要做一个企业知识库" → RAGFlow 提供完整方案
特点:一站式,开箱即用

LangChain:组件导向
"我要组装一个 Agent" → LangChain 提供各种组件
特点:灵活,但需要自己组装

LlamaIndex:数据导向
"我要索引和查询数据" → LlamaIndex 提供数据框架
特点:数据处理能力强,适合研究

代码风格对比

# RAGFlow:高层抽象,配置驱动
from ragflow import RAGFlow

app = RAGFlow()
dataset = app.create_dataset(name="knowledge")
dataset.add_documents("./docs")
chat = app.create_chat(dataset=dataset)
response = chat.query("What is RAG?")

# LangChain:Chain 组合式
from langchain.chains import RetrievalQA
from langchain.vectorstores import Chroma
from langchain.embeddings import OpenAIEmbeddings

vectorstore = Chroma.from_documents(docs, OpenAIEmbeddings())
qa = RetrievalQA.from_chain_type(
    llm=ChatOpenAI(),
    retriever=vectorstore.as_retriever()
)
response = qa.run("What is RAG?")

# LlamaIndex:索引为中心
from llama_index import VectorStoreIndex, SimpleDirectoryReader

documents = SimpleDirectoryReader("./docs").load_data()
index = VectorStoreIndex.from_documents(documents)
query_engine = index.as_query_engine()
response = query_engine.query("What is RAG?")

选型建议

场景推荐理由
企业知识库RAGFlow开箱即用,DeepDoc 解析复杂文档
复杂 Agent 应用LangChain灵活的 Chain/Tool 组合
数据分析研究LlamaIndex强大的索引策略
快速原型RAGFlow最快落地
高度定制化LangChain/LlamaIndex更底层的控制

六、生产级特性

API 设计

RAGFlow 提供完整的 REST API:

# 创建数据集
POST /api/dataset
{"name": "my_knowledge"}

# 上传文档
POST /api/document/upload
-F "file=@document.pdf"
-F "dataset_id={id}"

# 对话
POST /api/chat/completion
{
  "question": "什么是 RAG?",
  "dataset_ids": ["{id}"],
  "stream": true
}

部署方案

最小部署(Docker Compose):
├── ragflow(API 服务)
├── milvus(向量库)
├── mysql(元数据)
└── elasticsearch(可选,全文检索)

生产部署(Kubernetes):
├── Ingress
├── ragflow deployment(多副本)
├── milvus cluster
├── mysql primary/replica
└── 监控(Prometheus + Grafana)

多租户与权限

租户隔离:
- 每个租户独立的数据集
- 数据集级别的访问控制
- API Key 认证

权限模型:
- 管理员:全部权限
- 编辑者:上传、解析、编辑
- 查看者:仅查询

可观测性

指标监控:
- 文档处理吞吐量
- 检索延迟(P50/P95/P99)
- LLM 调用耗时
- 向量库查询性能

日志追踪:
- 请求级 Trace ID
- 结构化日志
- 全链路追踪

七、RAGFlow 的优势与局限

优势

维度说明
DeepDoc业界最强的开源文档解析能力
开箱即用完整 UI + API,快速落地
企业级多租户、权限、监控完备
多策略 Chunking针对不同文档类型优化
混合检索向量 + BM25 + Rerank 完整支持

局限

维度说明
灵活性不如 LangChain/LlamaIndex 灵活
Agent 能力不适合复杂多 Agent 场景
定制成本深度定制需要理解源码
学习曲线概念较多,需要时间熟悉

适用场景

强烈推荐

  • 企业内部知识库
  • 需要处理复杂文档(PDF、表格)
  • 追求快速落地
  • 需要可视化管理和审计

谨慎选择

  • 复杂 Agent 编排
  • 需要深度定制检索逻辑
  • 已有 LangChain/LlamaIndex 生态

八、快速入门

# 克隆项目
git clone https://github.com/infiniflow/ragflow.git
cd ragflow

# Docker Compose 启动
docker compose up -d

# 访问 Web UI
open http://localhost:9380

# 创建数据集、上传文档、开始对话

核心概念:

Dataset(数据集)
├── Document(文档)
│   ├── Chunk(切片)
│   └── Embedding(向量)
└── Chat(对话)

流程:
上传文档 → DeepDoc 解析 → 切分 → 向量化 → 存储
Query → 检索 → Rerank → LLM 生成 → 答案 + 引用

九、总结

RAGFlow 不是"又一个 RAG 框架",而是从文档到答案的全流程解决方案

它的核心价值:

1. DeepDoc:解决被忽视的文档解析问题
2. 多策略 Chunking:不同文档不同切法
3. 混合检索:向量 + BM25 + Rerank
4. 开箱即用:UI + API + 部署方案

如果你在做企业级 RAG 项目,尤其是需要处理复杂文档的场景,RAGFlow 是目前最值得尝试的开源方案。

它不一定是灵活性最高的,但可能是落地最快的。


相关链接

使用 Hugo 构建
主题 StackJimmy 设计