当前位置: 首页 > news >正文

MaxKB+MinerU:通过API实现PDF文档解析并存储至知识库

MinerU是一款开源的高质量数据提取工具,能够将PDF文档转换为Markdown和JSON格式。2025年6月13日,MinerU发布了v2.0版本,相较于v1.0版本实现了架构和功能的全面重构与升级。在优化代码结构和交互方式的同时,v2.0版本还集成了小参数量、高性能多模态文档解析模型,能够实现端到端的高速、高精度文档理解。实际测试表明,新版本对复杂图表的解析效果较上一版本有明显提升,目前已经能够满足90%以上的复杂文档解析需求。

值得一提的是,MinerU出色的PDF文档解析能力特别适合与MaxKB开源项目配合使用。通过"MinerU+MaxKB"的组合方案,用户不仅能够获得高质量的文档解析效果,还能显著提升知识库问答系统的性能。为方便用户集成,MinerU项目现已提供API对接服务(https://mineru.net/apiManage)。接下来,本文将详细介绍如何通过MinerU在线API实现与MaxKB的对接。

一、实现方法

当用户提供文件地址后,系统会将该地址赋值给file_url变量,并作为参数传递给MinerU文件解析服务。MinerU在完成文件解析后,会返回一个任务ID(task_id)。系统会将其传入MinerU的查询接口,当检测到任务处理完成时,自动获取结果文件的下载链接(full_url)。随后,系统执行文件下载操作,将结果文件保存到MaxKB容器的/opt/maxkb/download目录下。最后,系统会自动完成文件上传和智能分段处理,将内容存储到知识库中。
在这里插入图片描述

二、MaxKB函数创建

我们需要在MaxKB的函数库中创建四个核心功能函数,其用途分别为:

1.调用MinerU单个文件解析;

2.从MinerU获取任务结果;

3.通过URL链接下载文件至服务器;

4.将解析后的ZIP文件上传至知识库。

相关的代码说明如下:

■ MinerU单个文件解析函数:负责调用MinerU的单文件解析服务,通过传入PDF文档的在线地址来创建解析任务,并返回对应的task_id;

import requestsdef create_task(file_url):url = 'https://mineru.net/api/v4/extract/task'token = '自己申请的 Token'header = {'Content-Type': 'application/json','Authorization': f'Bearer {token}'}data = {'url': file_url,'is_ocr': True,  #是否启动 ocr 功能,默认 false'enable_formula': True,  #是否开启公式识别,默认 true'enable_table': True,    #是否开启表格识别,默认 true'language': "ch",    #指定文档语言,默认 ch,可以设置为auto'model_version': "v2",  #mineru模型版本,两个选项:v1、v2,默认v1。}res = requests.post(url,headers=header,json=data,timeout=5)res_data = res.json()task_id_data = res_data["data"]["task_id"]return task_id_data

在这里插入图片描述

■ MinerU获取任务结果函数:用于查询任务状态,通过传入task_id获取解析结果,成功后将返回ZIP格式解析文件的下载地址;

import time
import requests
def querybyid(task_id,max_retries=100,retry_interval=5):url = f'https://mineru.net/api/v4/extract/task/{task_id}'token = '申请的Token'header = {'Content-Type': 'application/json','Authorization': f'Bearer {token}'}retries = 0while retries < max_retries:try:res = requests.get(url, headers=header, timeout=5)res.raise_for_status()  # 检查请求是否成功data = res.json()if "data" in data and "full_zip_url" in data["data"] and data["data"]["full_zip_url"]:return data["data"]["full_zip_url"]else:print(f"full_zip_url 为空,正在等待任务完成。已重试 {retries + 1} 次,共 {max_retries} 次。")time.sleep(retry_interval)retries += 1except requests.exceptions.RequestException as e:print(f"请求失败,错误信息:{e}。正在重试...")time.sleep(retry_interval)retries += 1raise Exception(f"在 {max_retries} 次重试后,仍未获取到有效的 full_zip_url。")

在这里插入图片描述

■ 文件下载函数:根据提供的ZIP文件下载链接,将文件保存至容器内的/opt/maxkb/download目录。需要注意的是,MaxKB默认使用sandbox用户运行,需确保该用户对/opt/maxkb/download目录有读写权限;

import os
import requests
from urllib.parse import urlparsedef download_file(download_url, save_dir='/opt/maxkb/download'):os.makedirs(save_dir, exist_ok=True)# 获取文件名parsed_url = urlparse(download_url)filename = os.path.basename(parsed_url.path)save_path = os.path.join(save_dir, filename) # 文件下载后保存的目录,需要默认用户对此目录有读写权限# 下载文件try:response = requests.get(download_url, stream=True)response.raise_for_status()  # 检查请求是否成功total_size = int(response.headers.get('content-length', 0))block_size = 1024  # 1KBprogress = 0print(f"开始下载 {filename} 到 {save_dir}")with open(save_path, 'wb') as f:for data in response.iter_content(block_size):f.write(data)progress += len(data)# 打印下载进度print(f"下载进度: {progress / total_size * 100:.2f}%", end='\r')print(f"\n下载完成: {save_path}")return save_pathexcept requests.exceptions.RequestException as e:print(f"下载失败: {e}")return None

在这里插入图片描述

■ ZIP文件上传至知识库:通过MaxKB API将服务器上的ZIP解析文件上传至知识库存储。

import json
import logging
import requests
# 配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')def initialize(file_path):config = {# MaxKB API密钥'authorization_apikey': 'user-ac86ec515de17969f2f8a9c8ab21e52f',    # 文件分段处理的API地址'split_url': 'http://10.1.11.58:8080/api/dataset/document/split',# 目标知识库的API地址'upload_url': 'http://10.1.11.58:8080/api/dataset/3d1d5d4e-5576-11f0-bc5c-0242ac120003/document/_bach','file_path': rf'{file_path}','file_name': '函数库上传文档分段'}return configdef upload_file(config):headers = {'accept': 'application/json','AUTHORIZATION': f'{config["authorization_apikey"]}'}try:files = {'file': open(config["file_path"], 'rb')}response = requests.post(config["split_url"], headers=headers, files=files)response.raise_for_status()response_data = response.json()map_content = {}for item in response_data.get("data", []):for content_item in item.get("content", []):map_content[content_item.get("title", "")] = content_item.get("content", "")return map_contentexcept requests.exceptions.RequestException as e:logging.error(f"文件分段上传失败: {e}")return {}except Exception as e:logging.error(f"处理文件内容时出错: {e}")return {}def send_post_request(config, map_content):headers = {"Content-Type": "application/json","Authorization": f'{config["authorization_apikey"]}'}paragraphs = [{"title": key, "content": value} for key, value in map_content.items()]document_wrapper = {"name": config["file_name"],"paragraphs": paragraphs}json_body = json.dumps([document_wrapper])try:response = requests.post(config["upload_url"], headers=headers, data=json_body)response.raise_for_status()logging.info(f"上传文件响应: {response.text}")return Trueexcept requests.exceptions.RequestException as e:logging.error(f"上传文件失败: {e}")return Falsedef main(file_path):config = initialize(file_path)map_content = upload_file(config)if not map_content:logging.error("文件分段上传失败或内容为空,程序终止")return Falseif not send_post_request(config, map_content):logging.error("文件上传失败,程序终止")return Falsereturn "文件已上传成功,并保持在知识库中"

在这里插入图片描述

三、在MaxKB中创建应用

在上述四个函数创建完成后,我们可以在MaxKB中尝试创建高级应用。输入或提取上传文件的链接后,按照前文顺序依次添加MinerU单个文件解析函数节点→从MinerU获取任务结果函数节点→下载文件函数节点→文件上传函数节点。
在这里插入图片描述

小助手提示“文件上传成功”,即可回到知识库页面,在目标知识库中看到新上传的文档。
在这里插入图片描述
在这里插入图片描述

总结来说,MinerU v2.0是一款开源、高性能的PDF文档解析工具,具备强大的多模态处理能力。通过MaxKB与MinerU的深度联动,可以基于函数调用构建清晰高效的 “文件地址→解析→下载→上传” 自动化流程,无缝衔接原始文档与结构化知识库的构建。

“MinerU+MaxKB”的组合方案,不仅可以显著提升文档解析的精度与效率,更能大幅增强知识库问答系统的能力与效果。

如果您对我们的项目感兴趣,欢迎下载并体验MaxKB!

http://www.lryc.cn/news/605013.html

相关文章:

  • 梳理Ego-Planner模式下5通道、6通道与无人机模式的关系
  • Camera相机人脸识别系列专题分析之十九:MTK ISP6S平台FDNode传递三方FFD到APP流程解析
  • 不可变类字段修复建议
  • 如何解决pip安装报错ModuleNotFoundError: No module named ‘dash’问题
  • Python 程序设计讲义(43):组合数据类型——元组类型:元组的常用操作
  • WSL2搭建基于Docker的ESP32开发环境
  • 机器学习项目完整流程详解
  • 基于C-MTEB/CMedQAv2-rerankingv的Qwen3-1.7b模型微调-demo
  • Android基础(二)了解Android项目
  • 端侧大模型迎来“轻”革命!移远通信 × RWKV 打造“轻量AI大脑”
  • 单片机电路基础
  • 【NCS随笔】如何在hello_world添加蓝牙功能(一)
  • sqli-labs:Less-7关卡详细解析
  • 国内数据集成厂商有哪些?如何选择最适合的数据集成平台?
  • Qt 与物联网(IoT)开发
  • 【Linux】重生之从零开始学习运维之备份恢复
  • String模拟实现的补充说明
  • 第1课:向量与矩阵运算
  • QT中QTableView+Model+Delegate实现一个demo
  • 【ESP32设备通信】-LAN8720与ESP32集成
  • 如何设计一个站内消息系统:架构设计合集(八)
  • 订单识别技术原理及场景应用
  • 【音视频】WebRTC 开发环境搭建-Web端
  • MYSQL:视图
  • Qt 下载说明
  • uniApp实战六:Echart图表集成
  • 实现implements InitializingBean, DisposableBean 有什么用
  • 【MATLAB/Simulink】查看MATLAB以往版本的帮助文档
  • 牛顿-拉夫森法求解非线性方程组
  • 无人机惯性导航模块运行与技术难点!