github上RAGFLOW项目业务分析

第一阶段:索引流程(把文档变成知识库)

步骤1:文档接入与存储

• 操作:通过 UI/API 上传 PDF、Word、Excel、PPT、图片、扫描件、网页等;原始文件存入对象存储(如 MinIO),元数据(文件名、时间、来源)入库 PostgreSQL。

• 为什么这么做:统一入口屏蔽格式差异;原始文件留存用于溯源与引用;对象存储适合非结构化文件,PostgreSQL 管好元数据便于检索过滤。

• 优点:全格式兼容;原始文件可追溯;存储分层成本低。

• 缺点:小文件多会增加存储开销;上传量大时需异步队列防阻塞。

理解:文档入库存档,方便溯源与引用。具体原始文件存入(如 MinIO),元数据(文件名、时间、来源)入库 PostgreSQL

怎么做到的?

• PyMuPDF:PDF 解析

• python-docx:Word 解析

• pandas:Excel 解析

• python-pptx:PPT 解析

• Pillow + OpenCV:图片处理

• PaddleOCR:扫描件、图片文字识别(核心)

• BeautifulSoup4 + Playwright:网页抓取、动态网页解析

步骤2:文档深度解析(DeepDoc 核心)

• 操作:

a. OCR:扫描件/图片转文字(支持多语言);

b. 布局分析:识别标题、段落、列表、图片、表格位置;

c. 表格理解(TSR):解析合并单元格、行列标题,转自然语言描述;

d. 结构化输出:带位置、层级、类型的文本块。

• 为什么这么做:传统 RAG 只抽纯文本,会丢结构、表格、层级关系,导致分块断裂、检索不准、生成幻觉。DeepDoc 做「视觉-结构-语义」三重解析,还原文档原貌。

• 优点:表格/扫描件解析强;结构保留完整;信息提取准确率比纯文本高 30%+。

• 缺点:解析耗资源(CPU/GPU);复杂排版(如多栏、手写)仍有误差;OCR 质量依赖图片清晰度。

理解:多格式文档读取成数据,特例图片转文字,原有文档用框架去识别布局、表格等形式(方便后续词向量转换

步骤3:智能分块(Chunker,核心可控点)

• 操作:

◦ 模板分块:按文档类型(论文/合同/简历/财报)预设规则,按标题/章节/段落边界切分;

◦ 语义分块:用小模型算句子相似度,语义连贯为一块;

◦ 滑动窗口兜底:固定长度+重叠(如 1000 字/200 重叠);

◦ 可视化调整:手动拖拽分块边界,避免关键信息割裂。

• 为什么这么做:分块是 RAG 成败关键------块太大(整页)语义混杂、检索不准;块太小(句子)上下文断裂、信息不全;无规则切(按字数)易拆断标题-正文、表格-说明。模板+语义分块,优先按自然边界切,兼顾完整与精准。

• 优点:关键信息保留率比滑动窗口高 47%;可按业务定制;支持人工干预,可控性强。

ragflow智能分块后的结果和token是什么关系

token的数量直接划定了每个分块(Chunk)的"最大容量"。智能分块的过程,就是在保证语义完整和不超过Token上限之间寻找最佳平衡。

ragflow的智能分块,怎么可以人工干预?1.提供了ui界面,预览 和 编辑 的方式;2.也可以改参数 / 换策略(干预自动分块逻辑)

• 缺点:模板需适配场景;语义分块增加计算量;人工调整成本高。

理解:按文档类型预设规则

步骤4:文本向量化(Embedding)

• 操作:对每个分块,调用嵌入模型(默认 BGE、支持 OpenAI/本地模型)生成稠密向量(如 1024 维);向量+文本+元数据(页码、位置、来源)绑定。

稠密向量 简单说,就是用一串包含小数(浮点数)的、长度固定的数组来表示一个东西(比如一句话、一张图)的"语义"

同类别的:稀疏向量.

一个直观的例子

搜索"智能手机"。用稠密向量可能搜出"iPhone",因为它在语义上相近;用稀疏向量则只会搜出严格包含"智能"和"手机"这两个词的结果。

在现代RAG系统中,标准做法是:

混合检索 = 稠密向量(语义召回) + 稀疏向量(关键词召回)

先用两种方法分别找出各自认为相关的文档,再用重排序器(Reranker) 把两路结果合并排序,这样能兼顾语义理解能力和关键词匹配的精准度。

其他相关的向量类型

除了稠密和稀疏,你还会碰到这些概念:

多模态向量:可将文本、图像、音频等不同类型的数据映射到同一个向量空间。例如,输入"一只猫"的文本和一张猫的图片,两者生成的向量会非常相似。

二进制向量:把浮点数向量"压缩"成只含0和1的向量,主要用来加速检索和节省存储空间,但检索时精度会有所损失。

静态向量(Word2Vec、GloVe):每个词对应一个固定向量,不依赖上下文。"苹果"这个词,无论是在水果还是手机语境下,生成的向量都是同一个。如今在RAG中已很少使用。

动态/上下文向量:这是现在主流的方式(BERT、GPT家族)。"苹果"在"吃苹果"和"买苹果手机"两个句子中,会生成不同的向量,能准确理解上下文。

动态/上下文向量和稠密向量 的区别???

动态/上下文向量是"看语境定词义",而稠密向量通常指"一词一义"的静态表示。

动态/上下文向量同一个词在不同句子中,会生成不同的向量。根据语境实时算,灵活但慢,能理解一词多义。(并且它通常本身就是一种稠密向量),更高级。"动态"和"稠密"并非互斥的两个类别实际情况是:绝大多数动态/上下文向量本身也是稠密向量

• 为什么这么做:把语义转成向量空间距离------语义越近,向量距离越小,实现「意思相似」的检索,而非仅关键词匹配。

• 优点:支持语义检索;跨语言/歧义理解强;向量维度固定,便于数据库索引。

• 缺点:嵌入模型有成本(API/算力);向量不可解释;不同模型向量空间不兼容,切换需重嵌。

理解:就是把源头数据转换成词向量(机器可识别的语言)

步骤5:混合存储(向量+全文+元数据)

• 操作:

◦ 向量库:Milvus/FAISS/Chroma 存向量,建 HNSW 索引加速检索;

◦ 全文库:Elasticsearch 存原始文本,做关键词/模糊检索;

◦ 关系库:PostgreSQL 存元数据(来源、页码、分块 ID),用于过滤与溯源。

• 为什么这么做:单一存储有短板------向量库语义强但关键词弱、难过滤;全文库关键词准但语义差;关系库管好元数据便于权限、过滤、引用。三者结合,兼顾语义+精准+可追溯。

• 优点:混合检索效果最优;支持过滤(如只查某文档/日期);元数据完整,答案可引用来源。

• 缺点:多组件部署复杂;数据同步需维护;存储成本高(向量+文本+元数据三份)。

ragflow的第四步混合存储,详细怎么做的

用一步不漏、从数据流向到底层存储结构、再到入库代码逻辑,把 RAGFlow 第四步「混合存储(Hybrid Storage)」讲得清清楚楚,你听完就能直接对应到界面和源码。

一、先明确:RAGFlow 的"混合存储"存了什么?

不是只存向量,是四块同时存:

原始文件(PDF/Word/图片)→ 对象存储(MinIO/S3)

分块文本 + 结构化元数据 → 关系库(MySQL/PostgreSQL)

稠密向量(Dense Embedding) → 向量库(Elasticsearch/Infinity/Milvus)

稀疏向量(BM25 索引) → 全文检索(同 ES/Infinity,不需要额外引擎)

这就是"混合"的含义:结构化 + 非结构化 + 向量 + 全文索引,四路一体。

二、整体流程:分块完成后 → 怎么进入混合存储(最关键)

前置:你已经完成了

文档解析(PDF → 文本 / 表格 / 图片)

智能分块(自动 + 人工干预)

每一块 = chunk = {id, doc_id, content, title, page_no, ...}

第 4 步:混合存储(分 5 个子步骤)

子步骤 1:元数据 & 原始文件入库(MySQL + MinIO)

目的:记录 "文档 / 块" 的属性、位置、权限,保证可追溯

1.MySQL 写入(核心元数据)

document 表:文档名、类型、大小、上传时间、用户 ID、知识库 ID

chunk 表:块 ID、文档 ID、块内容(text)、标题、页码、token 数、是否有效

chunk_meta:层级路径(如 "第一章→1.1")、关键词、来源页码

2.MinIO/S3 写入(原始文件 + 图片)

原始 PDF/Word 原封不动存,用于 "查看原文"

块里包含的图片 → 转 jpeg → 存 MinIO → 记录 img_id 到 chunk 表

一句话:MySQL 管 "块的属性",MinIO 管 "原始文件和图片"。

子步骤 2:生成稠密向量(Dense Embedding)

目的:做语义检索,解决"意思相似但词不一样"

对每个 chunk.content 调用 Embedding 模型:

支持:BGE-M3、text-embedding、GLM-Embedding、Jina 等

输出:固定长度浮点数组(如 1024 维)

特点:

一块 → 一个向量

语义越近,向量距离越近

子步骤 3:生成稀疏向量(BM25)→ 全文索引

目的:做关键词精确匹配,解决"专业术语、编号、人名"

RAGFlow 用 ES/Infinity 内置 BM25:

不需要你自己算稀疏向量

直接把 chunk.content 写入 ES 的 text 字段

ES 自动分词 → 建倒排索引 → 支持 BM25 打分

一句话:稠密向量管语义,BM25 管关键词。

子步骤 4:向量 + 全文索引 写入同一引擎(ES/Infinity/Milvus)

核心设计:一个索引存所有,不用跨库

以 Elasticsearch 为例(RAGFlow 默认)

每个 chunk 对应一条 ES 文档

{

"chunk_id": "xxx",

"doc_id": "yyy",

"content": "RAGFlow 混合存储...",

"title": "混合存储",

"vector": 0.123, 0.456, ..., // 稠密向量

"create_time": "2026-04-25"

}

vector 字段:向量索引(用于语义检索)

content 字段:text 索引(用于 BM25 全文检索)

同库同索引:检索时一次请求同时拿两种结果

子步骤 5:建立关联 & 缓存(Redis)

目的:加速检索、避免重复计算

MySQL ↔ ES 关联:靠 chunk_id 双向映射

ES 查出来 → 用 chunk_id 去 MySQL 拿标题、页码、层级路径

Redis 缓存:

缓存热门 chunk 的向量、内容

缓存检索结果,减少 ES 查询压力

Q:Elasticsearch怎么存储 稠密向量和稀疏向量的??

vector 字段存储;ES自动计算,详细如下

这个向量不是一个预先画好的图,而是一个实时生成的成绩单

稀疏向量 = 一个很长的表格,每行代表一个文档,每列代表一个关键词,每个格子里要么是0(没这个词),要么是BM25算出来的重要性分数(有这个词)。

它的特点是:格子特别多(几十万个关键词),但每个文档里非零的格子特别少(只有几个词有分数)。

就像一个超级大的Excel表格,里面几乎全是0,只有零星几个数字,ES就靠这些"零星数字"来快速找到你想搜的文档。

第二阶段:检索流程(用户提问→精准答案)

步骤6:用户提问解析

• 操作:接收自然语言问题,做意图识别+关键词提取+问题向量化;可配置问题改写(如扩写、拆解多轮)。

意图识别是怎么做的?

• 为什么这么做:用户问题常简短/口语化/歧义多------向量化匹配语义,关键词补精准,改写优化检索词,提升召回率。

• 优点:口语化/歧义问题适配强;多轮问题可拆解;检索输入质量高。
• 缺点:改写规则需调优;意图识别不准会误导检索。
步骤7:多路召回(混合检索核心)
• 操作:
a. 向量检索:问题向量查向量库,返回 Top-K 语义相似分块;
b. 全文检索:关键词查 Elasticsearch,返回 Top-K 匹配分块;
c. 结果合并:去重,保留双路高相关分块。
• 为什么这么做:向量检索擅长「意思对但词不同」(如「营收」vs「收入」);全文检索擅长「关键词精准匹配」(如专有名词、编号);两者互补,召回更全、更准。
• 优点:召回率比单路高 20%+;兼顾语义与精准;覆盖歧义/专业术语场景。
• 缺点:双路检索增加耗时;结果合并需去重,逻辑复杂。
步骤8:重排序(Rerank)
• 操作:召回结果送入重排模型(如 BGE-Rerank、Cross-Encoder),逐对计算问题与分块的语义相关性,重新排序,取 Top-N 最相关分块(如 3-5 块)。
• 为什么这么做:召回阶段为保全,会返回较多噪声;重排模型做细粒度相关性打分,过滤无关、排准顺序,给 LLM 高质量上下文,减少幻觉、提升答案精准度。
• 优点:上下文质量显著提升;幻觉率降低 30%+;排序更贴合用户问题。
• 缺点:重排模型耗时/成本高;模型选择影响大;Top-N 数量需调优。
步骤9:提示词构建与 LLM 生成
• 操作:把「用户问题+Top-N 重排分块+引用来源模板」拼接成提示词,调用 LLM(OpenAI/Qwen/ChatGLM/本地模型)生成答案;强制引用分块来源(页码/文档名),支持流式输出。
• 为什么这么做:LLM 强于语言生成但易幻觉;用检索到的真实文档上下文约束生成,让答案「有据可依」;引用来源提升可信度,便于核查。
• 优点:幻觉大幅抑制;答案精准、可追溯;支持多轮对话、流式输出。
• 缺点:提示词长度有限(LLM 上下文窗口);长文档需控制分块数量;LLM 成本/响应时间依赖模型。

第三阶段:系统核心能力与整体优缺点

核心能力(区别于普通 RAG)

  1. DeepDoc 深度解析:表格/扫描件/结构文档解析强,信息保留完整。
  2. 可控分块:模板+语义+可视化调整,分块不割裂、信息全。
  3. 混合检索:向量+全文+重排,召回准、噪声少。
  4. 可追溯生成:答案必带引用来源,可信度高、可核查。
  5. 低门槛可视化:拖拽式流程、模板化配置,非开发者可上手。
    整体优点
    • 全链路一体化:从解析到生成一站式,无需拼接多开源组件,部署简单。
    • 企业级适配:权限、多用户、异步队列、可观测性齐全,适合生产环境。
    • 中文优化好:默认 BGE 中文模型,中文语义理解强,适配国内场景。
    • 开源可自部署:Apache 2.0 协议,可私有化部署,数据安全可控。
    整体缺点
    • 资源消耗高:解析、嵌入、重排都耗 CPU/GPU,小机器部署慢。
    • 复杂度高:多组件(ES/Milvus/PostgreSQL)依赖,运维有门槛。
    • 定制成本:垂直场景(医疗/法律)需调优模板、分块策略、提示词。
    • 幻觉仍存在:复杂问题、长上下文、跨文档推理仍有幻觉,需持续优化。

总结

RAGFlow 的核心逻辑是:用 DeepDoc 保住文档结构与细节 → 用可控分块平衡完整与精准 → 用混合检索+重排拿到高质量上下文 → 用带引用的生成抑制幻觉。每一步都在解决传统 RAG「解析浅、分块乱、检索偏、幻觉重」的痛点,代价是更高的资源消耗与复杂度,换来企业级可用、精准、可追溯的知识库问答能力。

需要我把以上流程整理成一份可直接执行的部署与调优清单,包含硬件配置建议、关键参数默认值与调优范围、常见问题排查步骤吗?