前言
最近在github上搜罗Rag相关项目的时候,我根据star 搜索到了目前star 最高的一些RAG 项目 ,其中稳居榜首的就是RAGFlow。
RAG stars:>1000 language:Python pushed:>2025-01-01
github RAG 相关项目搜索结果
为了系统性的学习RAG 技术栈,除了对RAG 进行一些系统性的学习总结外,浏览一些高质量的RAG 开源项目也是一种非常好的学习方式。这些项目凝结了开发者们的智慧与经验,能让我更直观地了解技术的实际应用和实现逻辑。
既然RAGFlow能获得这么高的关注度,想必在技术实现和功能设计上有其独到之处。所以,我打算以它为研究对象,深入探究其内部机制,开启我的 RAG 技术学习之旅。接下来,就和我一起走进rag-flow的世界,看看它到底有哪些过人之处吧。
RAGFlow 项目简介
RAGFlow 是一款基于深度文档理解构建的开源 RAG(检索增强生成)引擎。它为各种规模的企业提供了一套精简的 RAG 工作流程,通过结合大语言模型(LLM),利用来自各类复杂格式数据的可靠引用,为用户提供真实可信的问答能力。 (官网介绍)
RAGFlow 架构简介
RAGFlow系统架构
RAGFlow 作为一款基于深度文档理解构建的开源 RAG 引擎,不仅遵循了 Naive RAG 的基本流程,还融合了 Advanced RAG 的先进方法,并在文档预处理和分块等关键环节进行了优化,形成了一套高效且强大的系统架构。
回顾Navie RAG 基础架构
在学习RAGFlow 系统架构之前,我们先复习一下RAG 的最基础架构Naive RAG,Naive RAG 作为 RAG 技术的基础架构,其核心流程可分为索引、检索和生成三个主要阶段。
- 索引阶段
-
文档预处理:对原始文档进行初步清理和转换,去除噪声信息,为后续处理做准备。
-
文档分块:将文档划分为较小的、易于处理的文本块,便于后续的向量化和索引构建。
-
向量化:将每个文本块转换为向量表示,以便在高维空间中进行相似度计算。
-
构建索引:根据向量表示构建索引结构,以便快速检索相关文本块。
-
- 检索阶段
-
问题向量化:将用户提出的问题转换为向量表示。
-
检索 top-k 个相关答案:在索引中查找与问题向量最相似的 top-k 个文本块。
-
- 生成阶段
-
组合上下文:将检索到的文本块组合成上下文信息。
- 使用大模型回答结果:将上下文信息输入到大语言模型(LLM)中,生成最终的回答。
-
RAGFlow 的 Advanced RAG 架构
RAGFlow在Naive RAG的基础上,引用了Advanced RAG的预检索方法-Multi-way Recall 多路召回,和后检索方法 Re-rank,形成了一套经典的Advanced RAG架构。
-
预检索方法 - Multi-way Recall 多路召回
-
Multi-way Recall 多路召回是一种基于多种策略的检索方法,通过结合不同的召回策略,可以提高检索的召回率和准确性。RAGFlow 采用多路召回策略,从多个角度对问题进行检索,确保能够找到更多相关的文本块。例如,在
ragflow/rag/nlp/search.py
中,可能会实现多种检索算法,通过不同的权重和规则来召回相关文本块。
-
-
后检索方法 - Re-rank
-
Re-rank 是在多路召回的基础上,对召回的文本块进行重新排序的过程。通过使用更复杂的排序算法和特征,可以提高检索结果的相关性和准确性。在
ragflow/rag/nlp/search.py
中,rerank
函数可能会根据关键词相似度、向量相似度等多种特征对召回的文本块进行重新排序,从而得到更优的检索结果。
-
文档预处理优化
除了引入 Advanced RAG 的预检索和后检索方法,RAGFlow 在文档预处理过程时也进行了优化,以提高数据处理的质量。
-
Document layout Analyze (文档版式分析):文档版式分析通过YOLO目标检测框架识别文档中的10种基本布局组件(文本、标题、图片、表格、页眉页脚等),能够准确理解文档的结构层次和阅读顺序;实现的具体代码参考:deepdoc\vision\layout_recognizer.py文件。
-
文档版式分析识别文档中的 10 种基本布局组件:
-
labels = ["_background_", # 背景"Text", # 正文"Title", # 标题"Figure", # 图片"Figure caption", # 图片说明"Table", # 表格"Table caption", # 表格说明"Header", # 页眉"Footer", # 页脚"Reference", # 参考文献"Equation", # 公式 ]
-
-
Table Structure Recognition (表格结构识别):表格结构识别专门处理复杂表格,识别行、列、标题和合并单元格等5种表格组件,并将表格内容转换为HTML格式或自然语言描述。实现的具体代码参考:deepdoc\vision\table_structure_recognizer.py文件。
-
表格结构识别识别 5 种表格组件:
-
labels = ["table", # 表格整体"table column", # 列"table row", # 行"table column header", # 列标题"table projected row header", # 行标题"table spanning cell", # 合并单元格 ]
-
-
两个模块采用ONNX Runtime推理引擎,支持CPU/GPU并行加速,通过与OCR结果融合,实现从非结构化文档到结构化数据的智能转换。这套系统使RAGFlow能够像人类一样理解文档的视觉结构,为后续的知识提取、检索和问答提供了准确的结构化基础,特别适合处理学术论文、技术手册、财务报表等复杂文档格式。
文档分块优化
与常规架构不同的是,RAGFlow 的文档分块是根据不同的场景进行分块,它的分块策略包括:
模板名称 | 适用场景 | 支持格式 | 分块策略 |
---|---|---|---|
General | 通用文档 | MD、DOCX、PDF、TXT、图片等 | 基于Token数量的朴素分块 |
Q&A | 问答数据集 | XLSX、CSV、TXT | 问答对分块 |
Resume | 简历文档 | DOCX、PDF、TXT | 结构化字段分块 |
Manual | 技术手册 | 层次化章节分块 | |
Table | 表格数据 | XLSX、CSV | 表格行分块 |
Paper | 学术论文 | 章节语义分块 | |
Book | 书籍文档 | DOCX、PDF、TXT | 层次化章节分块 |
Laws | 法律法规 | DOCX、PDF、TXT | 条款分块 |
Presentation | 演示文稿 | PDF、PPTX | 页面级分块 |
Picture | 图片文档 | JPG、PNG、GIF等 | 图片分块 |
One | 整文档 | 多种格式 | 单块分块 |
Audio | 音频文档 | 音频格式 | 转录分块 |
RAGFlow 的文档分块模块还根据不同的场景自实现了一些算法策略,所有算法都保存在nlp/_init_.py 文件中,它实现的算法包括:
-
Naive Merge Algorithm(朴素合并算法)
-
实现函数:naive_merge(), naive_merge_with_images(), naive_merge_docx()
-
核心思想:基于 Token 数量的简单合并策略
-
算法流程:
-
根据指定分隔符切分文本段落
-
逐段合并,直到达到设定的 Token 阈值(默认128)
-
支持图片和文本的同步合并
-
分隔符:支持自定义分隔符(默认:\n。;!?)
-
-
-
Hierarchical Merge Algorithm(层次化合并算法)
-
实现函数:hierarchical_merge()
-
核心思想:基于文档结构层次的智能合并
-
算法流程:
-
使用正则模式识别文档层级结构(BULLET_PATTERN)
-
按层级分类段落(标题、章节、条款等)
-
利用二分搜索建立层级关系
-
按结构层次合并相关内容
-
-
-
Bullet Pattern Recognition(项目符号模式识别)
-
实现函数:bullets_category(), qbullets_category()
-
支持模式:
-
中文模式:第X章、第X节、第X条、(一)、(二)等
-
英文模式:Chapter X、Section X、Article X等
-
数字模式:1.、1.1、1.1.1等多级编号
-
问答模式:专门用于Q&A文档的问题识别
-
-
-
Title Frequency Analysis(标题频率分析)
-
实现函数:title_frequency()
-
功能:分析文档中标题的频率分布,确定最适合的分块层级
-
-
内容类型特定算法
-
JSON分块:递归式JSON结构保持分块
-
表格分块:行级或批次级分块
-
图像分块:图文同步分块
-
邮件分块:头部信息与正文分离
-
-
算法设计亮点
-
自适应性:根据文档类型自动选择最优分块策略
-
语义完整性:优先保持语义单元的完整性
-
多模态支持:同时处理文本、图片、表格等多种内容
-
可配置性:丰富的参数配置选项
-
性能优化:使用缓存、并发等技术提升处理效率
-
任务调度架构优化
RAGFlow 采用分布式异步任务调度系统,基于 Redis队列和多进程并发,实现高效的文档处理任务分发。通过分布式架构、异步处理和智能优化实现了高效、可靠的文档处理任务管理,能够处理大规模文档集合的并发处理需求。
核心组件
-
任务执行器(Task Executor):rag/svr/task_executor.py
-
任务服务(Task Service):api/db/services/task_service.py
-
Redis队列系统:基于Redis Streams实现
-
任务数据模型:api/db/db_models.py
处理流程
-
任务收集(Collect):检查未确认的消息、从队列获取新任务、验证任务有效性
-
任务处理(do_handle_task):
-
任务类型分发:RAPTOR 分层摘要处理、知识图谱构建、标准分块处理
-
分块处理流程:获取文档二进制数据、调用对应的分块器、并发上传图片到Minio
-
-
任务监控与状态报告:采用心跳机制
优势
-
智能负载均衡
-
多队列支持:支持不同优先级的任务队列
-
动态扩缩容:可动态增加或减少任务执行器
-
资源限制:细粒度的并发控制和资源管理
-
-
故障恢复
-
任务状态持久化:任务状态保存在数据库中
-
断点续传:支持任务执行中断后的恢复
-
死信处理:处理无法完成的异常任务
-
-
性能优化
-
异步I/O:基于trio异步框架,高并发处理
-
内存管理:支持内存监控和快照
-
批量操作:批量插入文档存储,提高吞吐量
-
查询分析优化
RAGFlow 查询分析优化流程
接下来让我们看一下RAG Flow 的查询分析优化流程。
- 文本规范化:
# 中英文间添加空格
def add_space_between_eng_zh(txt):txt = re.sub(r'([A-Za-z]+[0-9]+)([\u4e00-\u9fa5]+)', r'\1 \2', txt)# 噪声词过滤
def rmWWW(txt):# 去除中文助词:什么、哪里、怎么、如何等# 去除英文虚词:what、who、how、the、a、an等
- 语言识别:
def isChinese(line):# 自动识别中英文混合文本# 基于非英文字符比例判断(≥70%为中文)
- 智能分词策略
-
粗粒度分词:基于词典的最优路径分词
-
细粒度分词:针对复杂词汇的二次分割
-
权重计算:基于TF-IDF的词汇重要性评分
-
- 权重计算策略
query_fields = ["title_tks^10", # 标题权重最高 标题匹配权重×10"important_kwd^30", # 重要关键词 权重×30"question_tks^20", # 问题匹配 权重×20"content_ltks^2", # 正文内容 权重×2"content_sm_ltks" # 细粒度内容
]
-
多轮对话查询完善
def full_question(tenant_id, llm_id, messages):# 将不完整的多轮对话转换为完整问题# 例:用户:"他的母亲是谁?" → "唐纳德·特朗普的母亲是谁?"# 时间相对转换:今天/昨天/明天 → 具体日期
-
关键词自动提取
def keyword_extraction(chat_mdl, content, topn=3):# 使用LLM从查询中提取最重要的关键词# 保持原语言,用英文逗号分隔# 用于查询扩展和相关性提升
-
跨语言查询支持
def cross_languages(tenant_id, llm_id, query, languages=[]):# 将查询翻译为多种目标语言# 保持格式和技术术语准确性# 支持批量翻译,用###分隔
-
知识图谱查询重写
def query_rewrite(self, llm, question, idxnms, kb_ids):# 提取答案类型关键词(answer_type_keywords)# 提取查询实体(entities_from_query)# 基于实体类型池进行语义理解
-
混合相似度计算
def hybrid_similarity(self, avec, bvecs, atks, btkss, tkweight=0.3, vtweight=0.7):# 向量相似度(70%) + 词汇相似度(30%)# 平衡语义理解和精确匹配
-
性能优化
-
智能缓存:LLM结果缓存,避免重复计算
-
批量处理:同时处理多个查询变换
-
阈值控制:相似度阈值过滤无关结果
-
长度限制:关键词数量限制(32个)防止查询过长
-
分层匹配:从粗到细的多层匹配策略
-
参考文献
https://github.com/infiniflow/ragflow