Wend看源码-RAGFlow(上)

发布于:2025-07-11 ⋅ 阅读:(23) ⋅ 点赞:(0)

前言

        最近在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 技术手册 PDF 层次化章节分块
Table 表格数据 XLSX、CSV 表格行分块
Paper 学术论文 PDF 章节语义分块
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


网站公告

今日签到

点亮在社区的每一天
去签到