RAGFlow 是一款开源的深度文档理解 RAG 引擎,主打”先读懂、再检索”。传统 RAG 直接把 PDF 丢给切片器,表格、扫描件、多栏排版经常丢信息;RAGFlow 用自研的文档解析流水线先把复杂版面还原成结构化块,再喂给向量检索,召回质量肉眼可见地提升。本文从部署到 API 调用,带你落地一套可生产的检索增强生成系统。
一、为什么传统 RAG 在复杂文档上会翻车
多数开源 RAG 方案的默认链路是:读取文件 → 按固定长度切块 → 向量化 → 检索。这条链路对纯文本 Markdown 很友好,但一旦遇到真实业务里的 PDF 合同、带合并单元格的 Excel 报表、双栏论文或手机拍的扫描件,问题就暴露了:
- 版面丢失:双栏排版被按行顺序读成乱序文本,语义被打散。
- 表格崩坏:跨页表格被切成几段,数字与表头脱节,检索出来答非所问。
- 图片/印章忽略:扫描件里的图表、公章区域直接被跳过。
- 切块幻觉:固定 512 字切块把一句话拦腰截断,嵌入向量代表不了完整语义。
一个真实例子:某客服知识库把 200 页产品手册按 512 字一刀切后,用户问”保修期从哪天算起”,模型却把”激活当日生效”和”发货当日寄出”这两段隔着十几页的文字各取一半,拼出错误结论。根因不在模型,而在切块把上下文切散了。
结果就是”明明文档里有答案,模型却说不知道”。RAGFlow 的核心主张正是:检索质量的上限,取决于文档理解的精度。它把”理解”前置到切分之前,用视觉+布局模型先还原文档结构,再生成语义完整、边界清晰的块(chunk)。
二、RAGFlow 的核心能力:深度文档理解
RAGFlow 内置多种”文档布局识别”模型(基于深度学习的 OCR 与版面分析),支持把上传文件转成带坐标、带类型的结构化元素。不同文件类型走不同解析模板:
| 文档类型 | 解析方式 | 典型场景 |
|---|---|---|
| PDF / 扫描件 | OCR + 版面还原 | 合同、发票、论文 |
| Word / Markdown | 原生结构解析 | 制度文档、知识库 |
| Excel / CSV | 表格树重建 | 财务报表、台账 |
| PPT / 图片 | 视觉识别 + 文本抽取 | 培训材料、截图 |
解析完成后,RAGFlow 提供多种切块模板(General、Paper、Book、Resume、Table 等),你可以按文档性质选择,避免”一刀切”。这也是它和单纯用 LangChain 文本分割器最大的差异点。
三、5 分钟部署:Docker Compose 一键启动
RAGFlow 官方提供完整镜像,最低成本的方式是用 docker-compose 拉起。注意它依赖一个 Elasticsearch/Infinity 向量库,官方编排文件已包含,直接克隆运行即可:
# 拉取官方编排文件
git clone https://github.com/infiniflow/ragflow.git
cd ragflow/docker
# 如需使用 CPU 轻量版,编辑 .env 把 RAGFLOW_IMAGE 改为 ragflow:nightly-slim
docker compose -f docker-compose.yml up -d
# 启动后访问
# Web: http://localhost:80
# API: http://localhost:9380
docker compose ps
首次启动会拉取向量库镜像,稍等一两分钟。浏览器打开 http://localhost:80 即可进入控制台,注册账号后就能在界面里创建知识库、上传文档、发起对话。生产环境建议把 80 端口接到 Nginx 反向代理并配上 HTTPS。
四、用 API 构建知识库并问答
界面适合验证,工程化落地要走 API。下面这段 Python 演示完整链路:登录拿 token → 建数据集 → 上传文件并等待解析 → 发起检索式对话。记得先把 api_key 在控制台「API」页生成。
import requests, time
BASE = "http://localhost:9380"
# 1. 用邮箱密码换取 API Key(也可在控制台直接创建)
r = requests.post(f"{BASE}/v1/user/login",
json={"email": "you@example.com", "password": "your_pwd"})
token = r.json()["data"]["token"]
H = {"Authorization": f"Bearer {token}"}
# 2. 创建数据集(知识库)
ds = requests.post(f"{BASE}/v1/dataset",
headers=H,
json={"name": "产品手册库",
"chunk_method": "naive"}).json()
dataset_id = ds["data"]["id"]
# 3. 上传文档(解析是异步的)
with open("manual.pdf", "rb") as f:
up = requests.post(f"{BASE}/v1/document/upload",
headers=H,
data={"dataset_id": dataset_id},
files={"file": f}).json()
doc_id = up["data"]["id"]
# 4. 轮询解析状态,直到 done
while True:
st = requests.get(f"{BASE}/v1/document/get/{doc_id}", headers=H).json()
if st["data"]["status"] == "1": # 1 = 解析完成
break
time.sleep(3)
# 5. 发起对话(基于该知识库检索)
ans = requests.post(f"{BASE}/v1/chats_completions",
headers=H,
json={"question": "退款流程需要哪些材料?",
"dataset_ids": [dataset_id]}).json()
print(ans["data"]["answer"])
关键点:文档上传后解析是异步的,务必轮询 status 字段等到完成再问答,否则会检索到空库。大文件解析耗时从几秒到几分钟不等,建议用任务队列在后端托管,不要阻塞用户请求。
五、RAGFlow 与其他 RAG 框架怎么选
经常被拿来对比的有 LlamaIndex(编排层)和 Dify(应用平台)。三者定位并不完全相同:
| 维度 | RAGFlow | LlamaIndex | Dify |
|---|---|---|---|
| 核心定位 | 深度文档理解引擎 | 索引/检索编排库 | LLMOps 应用平台 |
| 复杂版面解析 | 强(内置 OCR) | 依赖外部解析器 | 依赖外部解析器 |
| 使用门槛 | 开箱即用 | 需写代码 | 图形化配置 |
| 适合角色 | 文档密集型知识库 | 研发自定义管线 | 快速搭 Agent/工作流 |
简单说:文档又多又脏,优先 RAGFlow;要高度自定义检索逻辑,用 LlamaIndex 自己搭;想图形化快速出应用,用 Dify。三者并不互斥。
六、生产落地的 5 条最佳实践
- 选对切块模板:论文用
paper、财报用table,别全站用naive。 - 解析异步化:上传走消息队列,前端轮询进度,避免大文件阻塞接口。
- 混合检索:开启关键词+向量双路召回,再接重排序,这是 RAG 进阶 里验证过的提升路径。
- 版本化管理知识库:文档更新后重建数据集并打标签,便于灰度与回滚。
- 把检索结果喂给工具调用:让 Agent 通过 Function Calling 主动查询知识库,而不是一次性塞进 prompt。
七、和现有 RAG 体系怎么协同
在我们已经有的 RAG 技术栈里,RAGFlow 最适合做”文档理解底座”:它负责把杂乱的 PDF/Excel 变成干净的结构化块,再把库暴露成 API;上层可以接 LlamaIndex 做复杂检索编排,或接 Dify 做对话界面。这种”RAGFlow 管解析、LlamaIndex 管编排、Dify 管前端”的分层,是中小团队性价比很高的组合。
八、小结
RAGFlow 的价值不在”又多一个 RAG 框架”,而在它把长期被忽略的文档理解环节做扎实了。对合同、报表、扫描件密集的业务,先用它把版面还原准,召回率往往比换更好的嵌入模型来得更直接。下一步可以把它接入你已有的知识库体系,作为解析层统一收口。
如果你的文档以干净的 Markdown 为主、结构规整,那直接上 LlamaIndex 也够用;但当资料来源混杂、含大量扫描件与表格时,把解析这一步交给 RAGFlow,是把”答得准”这件事的底座先打牢,性价比最高的一笔投入。




