Wend看源码-RAGFlow(下)

前言

Wend看源码-RAGFlow(上)-CSDN博客

        在上篇文章里,我们对 RAGFlow 的架构展开了介绍与说明,详细剖析了它的优化策略,像预处理优化、分块优化、任务调度优化以及查询分析优化等方面。而本篇文章将聚焦于 RAGFlow 的核心模块与具体使用方式,助力读者更深入洞悉其特点与优势 。

RAGFlow 核心模块

DeepDoc


DeepDoc 核心流程图

        DeepDoc 模块主要负责文档的预处理工作,包括文档版式分析、表格结构识别等。这些功能有助于更好地理解文档的结构和内容,从而提高后续检索和生成的准确性。通过对文档进行深度解析,DeepDoc 能够将复杂格式的文档转换为适合 RAG 系统处理的结构化数据。

        DeepDoc 包括两个核心模块,分别是:

Vision(视觉处理)

        负责图像级的文档理解,包括光学字符识别、版式分析和表格结构识别。DeepDoc 的视觉处理模块遵循"像人类一样理解文档"的设计理念。正如人类阅读文档时会先观察整体布局、识别文字内容、理解表格结构一样,Vision 模块通过计算机视觉技术模拟这一认知过程。

三大核心能力
  • OCR
    • 基于深度学习的端到端文字识别;支持中英文混合文档处理;具备位置坐标信息保留能力;自适应图像质量优化。
    • 实现原理
# 核心OCR处理流程
class OCR(Recognizer):
    def __call__(self, image_list, batch_size=16):
        # 图像预处理
        # 文字检测
        # 文字识别
        # 坐标信息提取
        return ocr_results
  • Document layout Analyze (文档版式分析):文档版式分析通过YOLO目标检测框架识别文档中的10种基本布局组件(文本、标题、图片、表格、页眉页脚等),能够准确理解文档的结构层次和阅读顺序。
  • Table Structure Recognition (表格结构识别):表格结构识别专门处理复杂表格,识别行、列、标题和合并单元格等5种表格组件,并将表格内容转换为HTML格式或自然语言描述。
Parser(文档解析器)

        DeepDoc 的解析器模块为每种主流文档格式都提供了专门优化的解析器:

解析器支持格式特色功能
PdfParserPDF复杂版式解析、图表提取、坐标保留
DocxParserDOCX样式信息保留、嵌入对象处理
ExcelParserXLS/XLSX公式解析、多工作表处理
PptParserPPT/PPTX幻灯片结构、动画信息
HtmlParserHTML标签结构、CSS样式处理
JsonParserJSON结构化数据保持、嵌套解析
MarkdownParserMD标记语言解析、链接处理
TxtParserTXT编码自动检测、格式推断

        此外,DeepDoc Parser 中包含一个专业简历解析器resume模块,该模块主要包含个人信息提取、教育背景分析、工作经历整理、技能标签识别、项目经验提取等简历处理的关键步骤。

agent

        Agent和RAG是互补的技术,RAGFlow v0.8.0引入了Agent机制,具有以下特点:

  • 前端:提供无代码工作流编辑器
  • 后端:基于图的任务编排框架
  • 目标:编排搜索技术(查询意图分类、对话引导、查询重写等),提供更高的检索准确性并适应更复杂的场景。
RAGFlow 具体组件简介

        RAGFlow 中agent模块包含的具体组件包括:

  • 核心RAG组件

组件名文件名功能描述
Beginbegin.py会话开始组件,提供欢迎信息和初始化对话
Generategenerate.py使用LLM生成回答,支持引用、工具调用和流式输出
Retrievalretrieval.py从知识库检索相关信息,支持向量搜索和重排序
Answeranswer.py终端回答组件,整合信息并提供最终响应
Categorizecategorize.py查询意图分类,将用户输入分到预定义类别
Relevantrelevant.py判断查询与知识库的相关性
Messagemessage.py发送静态消息,支持随机选择多条消息
Rewriterewrite.py基于对话历史重写用户查询
Keywordkeyword.py从查询中提取关键词,支持指定提取数量
  • 搜索引擎组件

组件名文件名功能描述
Googlegoogle.pyGoogle搜索,支持多国家/语言设置
Bingbing.pyBing搜索引擎接口
Baidubaidu.py百度搜索引擎接口
DuckDuckGoduckduckgo.pyDuckDuckGo隐私搜索引擎
  • 金融场景组件

组件名文件名功能描述
TuSharetushare.py获取中国股市数据和财经新闻
AkShareakshare.py中国金融数据接口,涵盖股票、期货等
YahooFinanceyahoofinance.py获取全球股票和金融市场数据
WenCaiwencai.py同花顺问财智能搜索接口
Jin10jin10.py金十数据财经新闻和数据
  • 学术搜索组件

PubMedpubmed.py医学文献搜索,查找生物医学论文
ArXivarxiv.py科学论文预印本搜索
GoogleScholargooglescholar.py学术文献和引用搜索
Wikipediawikipedia.py维基百科知识搜索
  •  翻译组件

组件名文件名功能描述
DeepLdeepl.pyDeepL高质量翻译服务
BaiduFanyibaidufanyi.py百度翻译API接口
  • 工具组件

组件名文件名功能描述
QWeatherqweather.py天气数据查询和预报
Crawlercrawler.py网页爬虫,抓取指定URL内容
Templatetemplate.py模板渲染组件,支持变量替换
  • 控制流组件

组件名文件名功能描述
Switchswitch.py条件分支组件,支持多条件逻辑判断
Iterationiteration.py循环控制组件,支持迭代处理
IterationItemiterationitem.py迭代项处理组件
Concentratorconcentrator.py数据汇聚组件,合并多个输入
Invokeinvoke.py组件调用器,动态调用其他组件
  •  数据处理组件

组件名文件名功能描述
ExeSQLexesql.pySQL执行组件,支持数据库查询
Codecode.py代码执行组件,支持Python代码运行
  • 通信组件

组件名文件名功能描述
Emailemail.py邮件发送组件,支持附件和HTML格式
  •  开发工具组件

组件名文件名功能描述
GitHubgithub.pyGitHub API接口,访问代码仓库信息
  • 基础架构组件

组件名文件名功能描述
ComponentBasebase.py所有组件的基类,定义通用接口和行为
ComponentParamBasebase.py组件参数基类,提供参数验证和管理
  • 设计模式

    • 统一架构:所有组件都继承自ComponentBase和ComponentParamBase

    • 参数验证:每个组件都有完整的参数检查机制

    • 流式支持:核心组件支持流式输出

    • 错误处理:统一的异常处理和错误响应

  • 功能特色
    • 丰富的数据源:覆盖搜索引擎、学术、金融、天气等多个领域

    • 智能控制流:支持条件判断、循环、汇聚等复杂逻辑

    • 多语言支持:内置翻译组件,支持国际化

    • 开发友好:提供代码执行、GitHub集成等开发工具

    • 生产就绪:包含邮件通知、数据库查询等企业级功能

        这个组件体系为RAGFlow提供了构建复杂智能Agent工作流的完整能力,用户可以通过拖拽组合这些组件来实现各种业务场景的自动化处理。

Agent 图结构
  • 核心数据结构DSL(Domain Specific Language)

        图结构主要在 agent/canvas.py 中通过 DSL 来表示,这是一个JSON格式的数据结构:

dsl = {
    "components": {
        "begin": {
            "obj": {
                "component_name": "Begin",
                "params": {}
            },
            "downstream": ["answer_0"],  # 下游连接
            "upstream": [],              # 上游连接
        },
        "answer_0": {
            "obj": {
                "component_name": "Answer", 
                "params": {}
            },
            "downstream": ["retrieval_0"],
            "upstream": ["begin", "generate_0"],
        },
        "retrieval_0": {
            "obj": {
                "component_name": "Retrieval",
                "params": {}
            },
            "downstream": ["generate_0"], 
            "upstream": ["answer_0"],
        }
    },
    "path": [["begin"]],     # 执行路径追踪
    "history": [],           # 对话历史
    "messages": [],          # 消息队列  
    "answer": []             # 回答队列
}

  • 图结构的关键要素

  • 节点

    • 组件ID:每个节点的唯一标识符(如“begin”,“answer_0")

    • 组件对象:obj 字段包含组件类型和参数

    • 连接关系:upstream和downstream数组定义有向边

# 组件A -> 组件B 的连接关系
"componentA": {
    "downstream": ["componentB"],  # A指向B
    "upstream": []
},
"componentB": {
    "downstream": [],
    "upstream": ["componentA"]     # B来自A
}
  • Canvas类 - 图执行引擎

        Canvas 类是图结构的核心管理器,负责:

  • 图的加载和验证

def load(self):
    # 验证必需组件
    assert "Begin" in cpn_nms, "There have to be an 'Begin' component."
    assert "Answer" in cpn_nms, "There have to be an 'Answer' component."
    
    # 实例化所有组件
    for k, cpn in self.components.items():
        param = component_class(cpn["obj"]["component_name"] + "Param")()
        param.update(cpn["obj"]["params"])
        cpn["obj"] = component_class(cpn["obj"]["component_name"])(self, k, param)
  • 图的遍历执行

def run(self, **kwargs):
    # 路径追踪
    self.path.append([])
    
    # 获取下游组件
    downstream = self.components[self.path[-2][-1]]["downstream"]
    
    # 依次执行组件
    for cpn_id in downstream:
        cpn = self.components[cpn_id]["obj"]
        ans = cpn.run(self.history, **kwargs)
        self.path[-1].append(cpn_id)
  • 循环检测

def _find_loop(self, max_loops=6):
    # 检测执行路径中的循环模式
    path = self.path[-1][::-1]
    # ... 循环检测逻辑
  • 图结构的可视化表示
    • 虽然后端使用DSL表示图结构,前端的可视化编辑器会将其渲染为:
    • 节点: 各种组件的可视化卡片
    • 连线: 表示数据流向的有向边
    • 执行路径: 高亮显示当前执行状态
预定义Agent DSL 模板

        RAGFlow在agent/templates 文件夹下定义了Agent DSL 的预定义模板,用户可以在前端直接选择预定义的模板,更快捷的选择工作流完成相关操作。

模板名称主要功能适用场景核心组件特色功能
WebSearch Assistant网络搜索助手需要实时网络信息的智能问答Retrieval + Baidu + DuckDuckGo + Wikipedia整合知识库和多个搜索引擎,提供全面信息检索
General-purpose chatbot通用聊天机器人多领域综合咨询服务Categorize + QWeather + AkShare + WenCai + 多个搜索引擎智能分类处理(天气、金融、医疗、闲聊等5大类)
Medical consultation医疗咨询助手医疗健康问题咨询Retrieval + PubMed + 多语言翻译结合医学知识库和PubMed文献搜索,支持中英翻译
Investment advisor智能投资顾问金融投资建议和实时行情WenCai + AkShare + KeywordExtract专注国内金融数据,整合同花顺问财和AkShare
Text To SQL文本转SQL工具自然语言转数据库查询3个Retrieval(DDL、示例、描述) + Generate需要3个知识库:DDL定义、SQL示例、数据库描述
Customer service客户服务机器人客户咨询和投诉处理Categorize + Message + Retrieval智能分类处理(联系方式、闲聊、投诉、产品相关)
Research report generator研究报告生成器自动生成研究报告Iteration + Baidu + Template支持多语言,自动分解主题并生成结构化报告
SEO Blog GeneratorSEO博客生成器SEO优化内容创作Switch + Baidu + Template基于关键词和标题自动生成SEO优化的博客内容
Interpreter智能翻译助手高质量文档翻译反思式翻译工作流(3步翻译-反思-改进)基于Andrew Ng项目,实现专业翻译的迭代优化
HR recruitment pitch (中文)HR招聘助手候选人沟通和招聘推介Categorize + Retrieval + 多个Generate专为中文招聘场景设计,智能处理各种候选人反馈
DB Assistant数据库助手高级SQL查询和执行Text2SQL + ExeSQL + RewriteQuestion不仅生成SQL,还能执行查询并返回结果

agentic_reasoning

RAGFlow 的DeepResearch 处理流程图

     RAGFlow 的deepResearch(深度研究)功能自 v0.17.0 版本起,支持在 AI 聊天中集成智能推理能力,极大地增强了系统在复杂问题处理上的能力。在这里我们再根据上述的RAGFlow 的DeepResearch 处理流程图总结下DeepResearch 的处理步骤。

处理流程
  • 初始化: 触发 deepResearch 后,先完成基础准备,初始化变量(如推理步骤计数、检索结果存储等)和消息历史(用于记录对话上下文)。

  • 核心推理循环:每次循环完成一轮 “推理→检索→整合→反馈” 流程,具体步骤如下:

    • 生成推理步骤:基于当前消息历史(含用户问题、之前的推理记录),调用大模型生成推理思路,拆解问题解决路径(比如细化子问题、明确需要补充的知识)。

    • 提取搜索查询:从推理结果中解析出具体搜索需求(可能是 1 个或多个子问题),作为后续检索的目标。若未提取到有效查询且非首次循环,可提前终止本轮检索。

    • 处理搜索查询

      • 去重校验:检查查询是否已执行过,若重复则直接复用历史检索结果,避免冗余操作。

      • 多源检索(若查询有效且未执行过):

        • 知识库检索:从本地 / 业务知识库中匹配相关文档片段(Chunk);

        • 网络搜索(如对接 Tavily 等工具):获取公网公开知识;

        • 知识图谱检索(若配置):基于图谱结构挖掘关联实体、关系;

        • 结果整合:合并多源检索内容,去重后更新知识块信息(Chunk Info)。

    • 信息提取与总结:用大模型对检索到的知识进行筛选、提炼,聚焦与当前推理步骤相关的内容,生成简洁的总结(如关键事实、数据、结论),并更新消息历史。

  • 终止条件与结果输出

    • 循环终止:若达到 MAX_SEARCH_LIMIT 次循环,返回 “超出搜索限制” 提示;若所有查询处理完毕且无新问题,结束循环。

    • 最终输出:整合多轮推理、检索的信息,生成最终思考结果(含推理过程、知识引用、结论),反馈给用户或下游模块。

特点
  • 闭环迭代:通过 “推理→检索→总结→再推理” 循环,模拟人类解决复杂问题的思路,逐步深化对问题的理解;

  • 多源融合:打通知识库、网络、知识图谱,覆盖企业私有知识与公网公开信息;

  • 效率优化:检索去重、循环限制等设计,平衡深度推理与资源消耗,适配实际业务场景;

graphRAG

        RAGFlow 的 graphRAG 模块是一个强大且灵活的组件,在配置开启后,能在 RAGFlow 生成索引的过程中发挥关键作用,生成图查询结构以提升查询的相关性和准确性。

        graphRAG 模块主要用于构建和管理知识图谱,以支持复杂的多跳问答任务。通过对文档内容的语义分析和实体关系提取,它能够生成知识图谱,并将其整合到 RAGFlow 的检索流程中,从而提供更准确、全面的答案。

graphRAG 的工作流程
  • 子图生成:主要负责从文档中提取实体和关系,并生成对应的子图

    • 检查图中是否已经包含该文档,如果包含则直接返回 None

    • 根据配置选择合适的提取器(LightKGExt 或 GeneralKGExt)。

    • 调用提取器的方法,从文档的各个块中提取实体和关系。

    • 将提取的实体和关系添加到子图中,并进行必要的清理和验证。

    • 将子图存储到文档存储中。

  • 子图合并:此函数用于将生成的子图合并到全局图中,并更新图的 PageRank 值。

    • 获取旧的全局图,如果存在则进行清理和验证。

    • 将子图合并到旧的全局图中,记录图的变化。

    • 计算合并后图的 PageRank 值,并更新节点的属性。

    • 将更新后的图存储到文档存储中。

  •  实体解析:该函数用于对图中的实体进行解析,消除实体的歧义。

    • 初始化实体解析器。

    • 调用解析器的方法,对图中的实体进行解析,并记录图的变化。

    • 更新图的 PageRank 值。

    • 将更新后的图存储到文档存储中。

  • 社区提取:此函数用于从图中提取社区结构,并生成社区报告。

    • 初始化社区报告提取器。

    • 调用提取器的方法,从图中提取社区结构和报告。

    • 将社区报告存储到文档存储中。

注意事项
  • 资源消耗:构建知识图谱需要大量的内存、计算资源和令牌,因此在使用 graphRAG 模块时需要注意资源的消耗。

  • 配置选择:不同的配置选项会影响知识图谱的构建和查询效果,并不是所有的场景都适合DeepResearch,需要根据具体的应用场景进行合理的配置。

应用场景传统RAGDeep Research优势
简单问答✅ 适用⚠️ 过度设计传统RAG更高效
复杂推理❌ 信息不足✅ 多轮深入能处理多步推理问题
实时信息❌ 知识库滞后✅ 网络搜索获取最新信息
跨领域查询❌ 单一知识源✅ 多源整合信息更全面
探索性研究❌ 线性检索✅ 自主探索发现隐藏关联

RAGFlow 的使用方式

前端交互

        RAGFlow 提供了配套设计的前端代码实现,用户可以登录https://demo.ragflow.io 试用 RAGFlow 的 demo,直观感受其功能。

  • 嵌入聊天助手到网页:RAGFlow 支持使用 iframe 将创建的聊天助手嵌入到第三方网页。具体步骤如下:

  1. 先获取API 密钥,否则会出现错误消息。
  2. 将鼠标悬停在目标聊天助手上,点击 Edit 以显示 iframe 窗口。
  3. 复制 iframe 代码并嵌入到网页的指定位置。
核心功能模块
模块功能描述使用场景
知识库管理创建、配置、上传文档,进行解析和分块企业文档管理、知识沉淀
Chat对话基于知识库的问答、多轮对话智能客服、知识问答
Agent工作流可视化拖拽构建复杂业务流程复杂业务自动化
文件管理统一的文件上传、预览、管理文档中心化管理

MCP交互

        在RAGFlow 项目源码中的mcp 文件夹下,RAGFlow 包含一套MCP 服务器和MCP 客户端的处理代码。通过MCP协议的方式,我们就可以轻松实现业务系统远程调用RAGFlow 系统,实现复杂检索。

        RAGFlow 的mcp 组件支持sse,和http_streamable 两种基于HTTP的连接方式,包含一个mcp工具ragflow_retrieval。

 name="ragflow_retrieval",
 description="Retrieve relevant chunks from the RAGFlow retrieve interface based on the question, using the specified dataset_ids and optionally document_ids. Below is the list of all available datasets, including their descriptions and IDs. If you're unsure which datasets are relevant to the question, simply pass all dataset IDs to the function."
 + dataset_description,
 inputSchema={
                "type": "object",
                "properties": {
                    "dataset_ids": {
                        "type": "array",
                        "items": {"type": "string"},
                    },
                    "document_ids": {
                        "type": "array",
                        "items": {"type": "string"},
                    },
                    "question": {"type": "string"},
                },
                "required": ["dataset_ids", "question"],
            },

sdk

        RAGFlow 提供 Python SDK,使用前需确保已获取RAGFlow API密钥用于身份验证。可以运行以下命令下载 Python SDK:

pip install ragflow-sdk

        

        在RAGFlow 项目源码中的sdk\python\test\test_sdk_api 文件夹下,包含了使用ragflow-sdk 库的测试文件,在此不再进行阐述,需要demo 的小伙伴可以自行到RAGFlow 的源码中获取这些测试Demo。

RAG-flow + ChatGPT-on-WeChat聊天插件

        该插件可将 RAGFlow 的知识检索能力集成到微信聊天交互中,使用步骤如下:

  • 安装和配置依赖项目
    • 安装并配置 ChatGPT-on-WeChat。ChatGPT-on-WeChat 也是一个开源项目,项目地址如下:https://github.com/zhayujie/chatgpt-on-wechat

    • 部署并运行 RAGFlow 服务器。

  • 配置插件:确保 config.json 文件
    (ChatGPT-on-WeChat 和 RAGFlow Chat 插件)都根据示例正确设置。ragflow_chat 插件的 config.json 示例如下:
{
  "ragflow_api_key": "YOUR_API_KEY",
  "ragflow_host": "127.0.0.1:80"
}

  • 使用插件进行聊天:插件会在接收到用户的文本消息后,调用 RAGFlow API 获取回复,并将回复显示在聊天界面中。如果配置不完整或调用 API 失败,会给出相应的错误提示。相关代码实现如下:
import logging
import requests
from bridge.context import ContextType
from bridge.reply import Reply, ReplyType
from plugins import Plugin, register
from plugins.event import Event, EventContext, EventAction

@register(name="RAGFlowChat", desc="Use RAGFlow API to chat", version="1.0", author="Your Name")
class RAGFlowChat(Plugin):
    def __init__(self):
        super().__init__()
        self.cfg = self.load_config()
        self.handlers[Event.ON_HANDLE_CONTEXT] = self.on_handle_context
        self.conversations = {}
        logging.info("[RAGFlowChat] Plugin initialized")

    def on_handle_context(self, e_context: EventContext):
        context = e_context['context']
        if context.type != ContextType.TEXT:
            return
        user_input = context.content.strip()
        session_id = context['session_id']
        reply_text = self.get_ragflow_reply(user_input, session_id)
        if reply_text:
            reply = Reply()
            reply.type = ReplyType.TEXT
            reply.content = reply_text
            e_context['reply'] = reply
            e_context.action = EventAction.BREAK_PASS
        else:
            e_context.action = EventAction.CONTINUE

    def get_ragflow_reply(self, user_input, session_id):
        api_key = self.cfg.get("api_key")
        host_address = self.cfg.get("host_address")
        user_id = session_id
        if not api_key or not host_address:
            logging.error("[RAGFlowChat] Missing configuration")
            return "The plugin configuration is incomplete. Please check the configuration."
        headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
        conversation_id = self.conversations.get(user_id)
        if not conversation_id:
            url_new_conversation = f"http://{host_address}/v1/api/new_conversation"
            params_new_conversation = {
                "user_id": user_id
            }
            try:
                response = requests.get(url_new_conversation, headers=headers, params=params_new_conversation)
                logging.debug(f"[RAGFlowChat] New conversation response: {response.text}")
                if response.status_code == 200:
                    data = response.json()
                    if data.get("code") == 0:
                        conversation_id = data["data"]["id"]
                        self.conversations[user_id] = conversation_id
                    else:
                        logging.error(f"[RAGFlowChat] Failed to create conversation: {data.get('message')}")
                        return f"Sorry, unable to create a conversation: {data.get('message')}"
                else:
                    logging.error(f"[RAGFlowChat] HTTP error when creating conversation: {response.status_code}")
                    return f"Sorry, unable to connect to RAGFlow API (create conversation). HTTP status code: {response.status_code}"
            except Exception as e:
                logging.exception("[RAGFlowChat] Exception when creating conversation")
                return f"Sorry, an internal error occurred: {str(e)}"
        url_completion = f"http://{host_address}/v1/api/completion"
        payload_completion = {
            "conversation_id": conversation_id,
            "messages": [
                {
                    "role": "user",
                    "content": user_input
                }
            ],
            "quote": False,
            "stream": False
        }
        try:
            response = requests.post(url_completion, headers=headers, json=payload_completion)
            logging.debug(f"[RAGFlowChat] Completion response: {response.text}")
            if response.status_code == 200:
                data = response.json()
                if data.get("code") == 0:
                    answer = data["data"]["answer"]
                    return answer
                else:
                    logging.error(f"[RAGFlowChat] Failed to get answer: {data.get('message')}")
                    return f"Sorry, unable to get a reply: {data.get('message')}"
            else:
                logging.error(f"[RAGFlowChat] HTTP error when getting answer: {response.status_code}")
                return f"Sorry, unable to connect to RAGFlow API (get reply). HTTP status code: {response.status_code}"
        except Exception as e:
            logging.exception("[RAGFlowChat] Exception when getting answer")
            return f"Sorry, an internal error occurred: {str(e)}"

参考文献

https://github.com/infiniflow/ragflow

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

找了一圈尾巴

你的鼓励将是我创作的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值