深度拆解RAGFlow分片引擎之切片实现

上一篇深度拆解RAGFlow分片引擎!3大阶段+视觉增强,全网最硬核架构解析 讲了切片的整体流程,今天我们来拆下切片的实现。


我们在设置的时候,可以选择切片方法。这个参数是parser_id

在创建知识库的时候,选择对应的切片方法以后,我们可以看到右侧的切片介绍。

async def build_chunks(task, progress_callback):  # 根据配置获取到切片实现(策略)chunker = FACTORY[task["parser_id"].lower()]
async with chunk_limiter:  cks = await trio.to_thread.run_sync(lambda: chunker.chunk(task["name"], binary=binary, from_page=task["from_page"],  to_page=task["to_page"], lang=task["language"], callback=progress_callback,  kb_id=task["kb_id"], parser_config=task["parser_config"], tenant_id=task["tenant_id"]))
  • 在上面的代码里根据配置parser_idFACTORY中获取到对应的实现文件
  • 注意chunker.chunk 调用对应实现文件中的chunk方法
from rag.app import laws, paper, presentation, manual, qa, table, book, resume, picture, naive, one, audio, email, tag
# 策略注册(隐式接口)
FACTORY = {  "general": naive,   # 基础文本处理器ParserType.NAIVE.value: naive,  ParserType.PAPER.value: paper,  # 学术论文处理器ParserType.BOOK.value: book,  ParserType.PRESENTATION.value: presentation,  ParserType.MANUAL.value: manual,  ParserType.LAWS.value: laws,  ParserType.QA.value: qa,  ParserType.TABLE.value: table,  # 表格专用处理器ParserType.RESUME.value: resume,  ParserType.PICTURE.value: picture,  ParserType.ONE.value: one,  ParserType.AUDIO.value: audio,  ParserType.EMAIL.value: email,  ParserType.KG.value: naive,  ParserType.TAG.value: tag  
}
  • FACTORY 对应的 实现,就是一个配置映射,根据前端的配置,然后映射到对应的方法
  • 我们可以看到对应的是从rag.app导入的

    看下代码结构,都是对应的类文件。引入的类文件每个都有一个相同的chunk方法

这块代码就是一个典型的策略模式实现。

这里要吐槽下python的隐式接口,不是自己写的代码,一不小心得来回翻几遍代码。等我过两天给它接口显式实现。

整块代码逻辑如下:

策略工厂FACTORY
general/naive
paper
table
...
统一chunk方法接口
naive.py
paper.py
table.py
...其他处理器
分片请求
parser_id参数
执行具体分片逻辑
返回结构化分片数据

在上一篇中我们简单的画了下naive的处理流程,也就是前端选择的general。我把流程复制过来。

DOCX
PDF
Excel
TXT/Code
Markdown
HTML/JSON
输入文件
格式判断
DOCX解析器
PDF解析器+布局识别
表格解析器
文本分割器
MD表格提取
结构化解析
原始分片生成
是否视觉增强?
视觉模型处理图表
基础分片处理
分片合并
Token化处理
输出结构化分片

通用方法里,针对不同的文件类型,有对应的实现。

接下来,我们拆解几个定向的分片实现。

Manual


前端显示仅支持pdf,后端代码支持pdfdocx。这块代码的整体处理逻辑如下

PDF
DOCX
文件输入
文件类型判断
PDF解析器
DOCX解析器
OCR+布局分析
表格识别
段落结构解析
表格HTML转换
分块处理
Token化输出


manual中,并没有抽取图片,只抽取了表格,而且类似的代码写了两遍。


我又对比了manualnaive下pdf的处理代码。

  • manual 中注重的是文档结构化,其他的并没有增强
  • 反而在naive模式下,通过视觉模型对图片进行了增强
  • 所以manual只适合没有图片的,有表格的pdf

laws

  • 法律文本的处理,在pdf上 处理上,唯一特殊的地方只有一个垂直合并

合并逻辑如下:

排序文本块
遍历相邻块
是否跨页且无意义文本?
删除当前块
是否空文本块?
计算合并特征
满足禁止合并条件?
跳过合并
执行垂直合并

book

我们看了几个,特殊场景的处理,其实最后都是通过pdf的差异化处理实现的。

resume 简历

  • 首先通过内部服务,会进行简历的处理,通过上下文,可以看到是对简历进行了结构化处理。

这个需要注意下,如果你源码部署,一定要注意这个,否则就趟坑了。

然后通过结构化的关键词,构建一个分片的数据结构。

qa

  
def rmPrefix(txt):  return re.sub(  r"^(问题|答案|回答|user|assistant|Q|A|Question|Answer|问|答)[\t:: ]+", "", txt.strip(), flags=re.IGNORECASE)  def beAdocPdf(d, q, a, eng, image, poss):  qprefix = "Question: " if eng else "问题:"  aprefix = "Answer: " if eng else "回答:"  d["content_with_weight"] = "\t".join(  [qprefix + rmPrefix(q), aprefix + rmPrefix(a)])  d["content_ltks"] = rag_tokenizer.tokenize(q)  d["content_sm_ltks"] = rag_tokenizer.fine_grained_tokenize(d["content_ltks"])  d["image"] = image  add_positions(d, poss)  return d  def beAdocDocx(d, q, a, eng, image, row_num=-1):  qprefix = "Question: " if eng else "问题:"  aprefix = "Answer: " if eng else "回答:"  d["content_with_weight"] = "\t".join(  [qprefix + rmPrefix(q), aprefix + rmPrefix(a)])  d["content_ltks"] = rag_tokenizer.tokenize(q)  d["content_sm_ltks"] = rag_tokenizer.fine_grained_tokenize(d["content_ltks"])  d["image"] = image  if row_num >= 0:  d["top_int"] = [row_num]  return d  def beAdoc(d, q, a, eng, row_num=-1):  qprefix = "Question: " if eng else "问题:"  aprefix = "Answer: " if eng else "回答:"  d["content_with_weight"] = "\t".join(  [qprefix + rmPrefix(q), aprefix + rmPrefix(a)])  d["content_ltks"] = rag_tokenizer.tokenize(q)  d["content_sm_ltks"] = rag_tokenizer.fine_grained_tokenize(d["content_ltks"])  if row_num >= 0:  d["top_int"] = [row_num]  return d

我们可以看到qa就是根据不同的结构解析出来问答对。

audio

def chunk(filename, binary, tenant_id, lang, callback=None, **kwargs):  doc = {  "docnm_kwd": filename,  "title_tks": rag_tokenizer.tokenize(re.sub(r"\.[a-zA-Z]+$", "", filename))  }  doc["title_sm_tks"] = rag_tokenizer.fine_grained_tokenize(doc["title_tks"])  # is it English  eng = lang.lower() == "english"  # is_english(sections)  try:  callback(0.1, "USE Sequence2Txt LLM to transcription the audio")  seq2txt_mdl = LLMBundle(tenant_id, LLMType.SPEECH2TEXT, lang=lang)  ans = seq2txt_mdl.transcription(binary)  callback(0.8, "Sequence2Txt LLM respond: %s ..." % ans[:32])  tokenize(doc, ans, eng)  return [doc]  except Exception as e:  callback(prog=-1, msg=str(e))  return []

这块的代码更简单,直接通过语音模型转成了文本,然后再进行处理。

picture

图片的解析是使用OCR处理,所以识别到的是图片上的文本内容。使用的是deepdoc之前测试,识别效果很一般。

图片识别有两种,一种是识别图片中的文本内容,一种是通过图片描述这个图片是什么。我们可以通过扩展,ocr+图片描述构建一个图片检索系统。

两种实现方案:

  • 直接改这块的源码,添加图片理解反推
  • 在外面将图片反推后,构建图片描述,后续我基于这个写个案例

后记

通过代码发现,专用处理有时候也蛮鸡肋的,如果我们在外面将文档都结构化了,很多通过一些分片策略,我们可以忽略一些专用类型。

底层的处理最后都是deepdoc中的几个文件。后续会针对这个再做一些源码分析。

rag玩的是对文档的了解,怎么能拆解出合适的分片,这个是关键。

市面上应该有一些处理文档的专有模型,到时候找下看看。

系列文章

uv配置环境

dify相关

DeepSeek+dify 本地知识库:真的太香了
Deepseek+Dify本地知识库相关问题汇总
dify的sandbox机制,安全隔离限制
DeepSeek+dify 本地知识库:高级应用Agent+工作流
DeepSeek+dify知识库,查询数据库的两种方式(api+直连)
DeepSeek+dify 工作流应用,自然语言查询数据库信息并展示
聊聊dify权限验证的三种方案及实现
dify1.0.0版本升级及新功能预览
Dify 1.1.0史诗级更新!新增"灵魂功能"元数据,实测竟藏致命Bug?手把手教你避坑
【避坑血泪史】80次调试!我用Dify爬虫搭建个人知识库全记录
手撕Dify1.x插件报错!从配置到网络到Pip镜像,一条龙排雷实录
dify1.2.0升级,全新循环节点优化,长文写作案例
dify1.x无网环境安装插件
dify项目结构说明与win11本地部署
Dify 深度拆解(二):后端架构设计与启动流程全景图
dify应用:另类的关键词检索

ragflow相关

DeepSeek+ragflow构建企业知识库:突然觉的dify不香了(1)
DeepSeek+ragflow构建企业知识库之工作流,突然觉的dify又香了
DeepSeek+ragflow构建企业知识库:高级应用篇,越折腾越觉得ragflow好玩
RAGFlow爬虫组件使用及ragflow vs dify 组件设计对比
从8550秒到608秒!RAGFlow最新版本让知识图谱生成效率狂飙,终于不用通宵等结果了
以为发现的ragflow的宝藏接口,其实是一个天坑、Chrome/Selenium版本地狱
NLTK三重降噪内幕!RAGFlow检索强悍竟是靠这三板斧
从代码逆向RAGFlow架构:藏在18张表里的AI知识库设计哲学
解剖RAGFlow!全网最硬核源码架构解析
深度拆解RAGFlow分片引擎!3大阶段+视觉增强,全网最硬核架构解析
深度拆解RAGFlow分片引擎之切片实现
RAGFlow核心引擎DeepDoc之PDF解析大起底:黑客级PDF解析术与致命漏洞
RAGFlow 0.18.0 实战解读:从 MCP 支持到插件配置的全流程揭秘
ragflow 0.19.0 图文混排功能支持

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/84786.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/84786.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSS平滑滚动效果实现方法

一、纯CSS实现方案 使用 scroll-behavior 属性 属性值 auto (默认值):滚动框立即滚动smooth:滚动框以平滑的方式滚动 /* 全局平滑滚动 */ html {scroll-behavior: smooth; }/* 特定容器平滑滚动 */ .scroll-container {scroll-behavior: smooth;over…

李沐动手深度学习(pycharm中运行笔记)——12.权重衰退

12.权重衰退(与课程对应) 目录 一、权重衰退 1、使用均方范数作为硬性限制 2、使用均方范数作为柔性限制(通常这么做) 3、演示对最优解的影响 4、参数更新法则 5、总结 二、代码实现从零实现 三、代码实现简介实现 一、权重…

React Native【实战范例】同步跟随滚动

最终效果 实现原理 主动滚动区触发滚动事件,原生监听滚动值的变化,并用动画的方式实时同步到跟随滚动区 技术要点 使用 Animated.ScrollView 使用动画变量 const scrollY useRef(new Animated.Value(0)).current;主动滚动触发 onScroll,用 …

如何仅用AI开发完整的小程序<3>—创建小程序基础框架

1、启动小程序开发者工具-选择小程序,点击 2、创建一个项目工程 项目名称:自己填默认的也行,最好不要中文,拼音也行 目录:选择你的项目创建路径 AppID:可以先点测试号,后面再替换自己的AppID就…

SQL等价改写优化

or 与 union all的优化 在SQL开发中,我们经常会遇到这样的情况:需要组合多个相似但略有不同的查询结果。大多数开发者本能地使用UNION/UNION ALL来解决,这种方式直观易懂,但在特定场景下却隐藏着巨大的性能浪费。 本案例将从执行…

【已解决】 数据库INSERT操作时,Column count doesn’t match value count at row 1

【已解决】数据库INSERT操作时,ColumnColumn count doesn’t match value count at row 1 在开发过程中,我们经常会遇到数据库操作错误,其中之一就是 MySQL 中的 “Column count doesn’t match value count at row1” 错误。这个错误通常发…

管件接头的无序抓取

文章目录 1,目的2,过程3,易混易错点4,代码详解4.1,初始化窗口4.2,创建多视角立体视觉模型。4.3,创建表面匹配模型4.4,多视角立体视觉重建管件堆表面模型4.5,管道接头查找…

移远通信 × 紫光展锐,推动FWA “5G+AI”新体验

6月19日,在2025 MWC上海期间,移远通信宣布,携手紫光展锐,推出面向下一代CPE应用的“5GAI”融合解决方案。目前双方正联合多家CPE厂商开展方案深度调优,以加速5GAI CPE终端的产业化落地进程。 该方案以移远5G模组RG620…

深入理解Grad-CAM:用梯度可视化神经网络的“注意力“

深入理解Grad-CAM:用梯度可视化神经网络的"注意力" 引言 在深度学习的发展过程中,模型的可解释性一直是一个重要的研究方向。尽管现代神经网络在图像识别、自然语言处理等任务上取得了令人瞩目的成果,但它们往往被称为"黑盒…

离线环境jenkins构建前端部署镜像

gitlabjenkins 实现前端项目打包成 docker 镜像;gitlab部署就不赘述了;因部署的gitlab版本的webhooks有问题,无法进行配置,所以文章的构建是手动触发的。并且nodejs部署应该也能跟docker一样直接安装进jenkins的镜像(但是多版本可能就有其他问…

案例:塔能科技×某市智能照明——从传统亮化到智慧光生态的跨越

在城市发展的滚滚浪潮中,市政照明不仅是驱散黑夜的光明使者,更是衡量城市智能化水平的关键标尺。贵州某市的城市照明系统正经历一场意义深远的革新,塔能科技以创新科技为核心驱动力,为这座城市的夜间照明生态注入全新活力。通过智…

LeapMotion-HandPoseRecorder 脚本详解

HandPoseRecorder 脚本详解 这个脚本是一个用于在 Unity 中录制和保存 Leap Motion 手部姿势的工具。下面我将详细解释脚本的各个部分: 核心功能 该脚本的主要作用是: 从 Leap Motion 设备捕获当前手部姿势数据 将姿势数据序列化为可重用的 ScriptableObject 在 Unity 项目…

【Guava】0.做自己的编程语言

【Guava】0.做自己的编程语言 0.前言1.明确你的目标1.2.设计1.3.写一个介绍 2.开始吧! 0.前言 DO WHAT THE F**K YOU WANT TO DO 我相信,网上有许多各式各样的做自己的编程语言教程,but 都是这样 收费 shit 本教程教你真正教你实现一个名叫G…

【软考高级系统架构论文】论无服务器架构及其应用

论文真题 近年来,随着信息技术的迅猛发展和 应用需求的快速更迭,传统的多层企业应用系统架构面临越来越多的挑战,已经难以适应这种变化。在这一背景下,无服务器架构(Serverless Architecture) 逐渐流行,它强调业务逻辑…

国产MCU A\B SWAP原理及实操

看到有读者留言说还是没理清A\B SWAP的原理。 今天就以某国产MCU为例,实际演示一番,看看大家在芯片设计时思路是什么。 我们首先回顾下SWAP的基本思想。 SWAP的基本思想是将PFLASH分成两组Bank,Bank A(假设是active)和Bank B(假设是inacti…

目标检测neck经典算法之FPN的源码实现

┌────────────────────────────────────────────────────┐│ 初始化构造 (__init__) │└─────────────────────────────────────────────…

extern关键字:C/C++跨文件编程利器

在 C 和 C 中,extern 是一个关键字,用于声明变量或函数是在其他文件中定义的。它主要用于实现多个源文件之间的符号共享。 目录 📌 一、C语言中的 extern 1. 基本作用 2. 示例说明 定义全局变量(只在一个 .c 文件中&#xff…

编程语言的演化与选择:技术浪潮中的理性决策

📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、引言:为什么“选对语言”比“掌握语言”更重要? 在软件开发的世界里,语言是一切的基础。…

【StarRocks系列】StarRocks vs Mysql

目录 StarRocks 简介 核心特性 典型应用场景 StarRocks vs MySQL:核心区别详解 关键差异总结 如何选择? StarRocks 简介 StarRocks 是一款高性能、全场景、分布式、实时分析型的数据库(MPP - 大规模并行处理)。它诞生于解决…

Axios 知识点全面总结

文章目录 Axios 知识点全面总结一、Axios 基础概念1. 什么是 Axios?2. 核心特性 二、安装与基本用法1. 安装2. 基本请求示例 三、请求方法与参数四、请求配置选项(config)五、拦截器(Interceptors)六、错误处理七、取消…