前言
KnowFlow 原先虽然支持了 MinerU/Dots OCR 引擎,但是通过在 RAGFlow 内直接对接 KnowFlow 独立后端服务。这样的设计本质上是脱离了 RAGFlow,无法复用 TaskQueue 以及自动关键词、关键问题、Raptor、知识图谱。
为了解决这个问题,我们彻底重构了 MinerU/Dots 集成方案,不再作为切块方法,而是遵循 RAGFlow 最佳实践,我们将 MinerU/Dots 定义为布局解析器,父子、语义、标题、正则分块策略调整为切片方法。
带来的好处在于能够充分复用 RAGFlow 已有的功能,同时技术架构设计上也更加合理,产品可维护性大大提升。
MinerU/Dots 全新架构设计
系统分层架构
数据存储层KnowFlow 服务层分块方法层解析器层 - PDF 解析器业务逻辑层前端层
HTTP
HTTP
RAGFlow 前端RAGFlow API ServerTask Executor异步任务队列DeepDoc原生解析器MinerU Parser基于 MinerU 2.xDOTS Parser基于 DOTS OCRnaive.py通用分块paper.py论文分块book.py书籍分块qa.py问答分块manual.py手册分块laws.py法律分块presentation.py演示文稿分块KnowFlow API端口: 5000MinerU FastAPI端口: 8888VLM Service端口: 30001Smart Chunk API/api/parse/smart_chunkMySQLElasticsearchMinIO
架构设计原则
核心设计理念:解析器与分块方法分离
- 1. 解析器职责(MinerU/DOTS/DeepDoc)
-
- • 将 PDF 转换为结构化的 markdown + 坐标信息
- • 返回格式:
[(text_with_position_tag, layout_type), ...] - • 示例:
("@@0\t100\t200\t50\t70##这是一段文本", "text")
- 2. 分块方法职责(naive/paper/book 等)
-
- • 接收解析器输出,按照语义规则进行分块
- • 处理格式:
[(text, position_tag), ...] - • 支持调用 Smart Chunk API 进行智能分块
- 3. Smart Chunk API 职责
-
- • 基于 middle.json 的精确坐标映射
- • 提供多种分块策略(smart、parent_child、regex 等)
- • 为每个 chunk 返回精确的坐标数组
实现细节
class MinerUParser(object):
def __init__(self):
# 从环境变量读取 KnowFlow Server URL
self.knowflow_server_url = os.getenv(
'KNOWFLOW_SERVER_URL',
'http://localhost:5000'
)
self.timeout = int(os.getenv('MINERU_PARSE_TIMEOUT', '300'))
def chunk(self, filename, binary=None, from_page=0, to_page=100000,
lang="Chinese", callback=None, kb_id=None, **kwargs):
"""
MinerU 文档解析入口
Returns:
List[dict]: [
{
"content_with_weight": str, # 文本内容
"positions": [[page, x0, x1, y0, y1], ...], # 坐标数组
"layout_type": str, # 布局类型
"image": PIL.Image (可选) # 图片对象
},
...
]
"""
# 1. 调用 KnowFlow API 进行 MinerU 解析
response = self._call_mineru_api(
binary, from_page, to_page, kb_id, callback
)
# 2. 获取结果
boxes = response['boxes'] # 语义块级别(用于 general 分块)
markdown_text = response['markdown'] # 逐行级别(用于 smart 分块)
coordinate_map = response['coordinate_map'] # 坐标映射
# 3. 转换为标准格式:(text_with_tag, layout_type)
sections = self._convert_to_sections(boxes)
return sections
格式转换示例:
# MinerU 输出格式(由 KnowFlow API 返回)
boxes = [
{
'text': '# 第一章 引言',
'page_number': 0,
'x0': 100, 'x1': 500, 'top': 50, 'bottom': 80,
'layout_type': 'title'
},
{
'text': '这是一段正文内容。',
'page_number': 0,
'x0': 100, 'x1': 500, 'top': 100, 'bottom': 120,
'layout_type': 'text'
}
]
# 转换为 sections 格式(传递给分块方法)
sections = [
("@@0\t100\t500\t50\t80##第一章 引言", "title"),
("@@0\t100\t500\t100\t120##这是一段正文内容。", "text")
]
值得一提的是坐标映射,对于语义分块/父子分块/标题分块等切块方法,通过解析 OCR block 数据,构建行级别的坐标映射关系。而对于 RAGFlow 已有的 naive/paper/book 等方法,我们提供了和 DeepDoc 类似的基于语义结构的 sections。这样的设计方案保障了 MinerU/Dots 支持 RAGFlow 原有的 naive/paper/book 等分块方法。
MinerU v2.5.4 适配
MinerU v2.5.4 相比于我们之前适配的 v2.1.0 版本差异巨大,去除了 sglang 模式,提供了 vllm 模式用于替代原先 sglang。
MinerU v2.5 默认参数下 vllm 显存占用 23G 左右,pipline 2G 左右。
现在已支持自动跨页表格功能合并。
实测下来 MinerU v2.5 识别效果在闭源离线模型中可谓是惊艳,强烈安利。
优化
- RBAC 权限检查优化为批量检查,提升网页响应速度
原先知识库列表页面,对于列表每一个知识库单独调用权限检查;现优化成统一批量接口进行批量权限检查,网页响应速度从 700ms 优化成 200ms.
- 分块预览支持 MarkDown ,支持标题、公式、列表渲染
修复
- 坐标映射从文本相似度调整为基于 block 数据按行映射,100% 准确
- 修复 flow 创建失败的问题
未来展望
本版本技术重构遵循了 RAGFlow 设计规范,从根本上提升了产品的易用性和可维护性。
下个版本我们将会围绕多模态场景进行开发,实现图文搜图文功能。
开源
本项目社区版已更新至 v2.0.8 版本,支持 RBAC 简略版以及适配 v0.20.1 版本。
欢迎关注公众号「KnowFlow 企业知识库」加入内部交流群,学习和分享 RAG 知识库。