RAG中如何切分文档
本文介绍的是本人实习期间做过的内容跟大家分享一下。解决的任务如何将带有图片和表格的pdf、docx文档进行切分。步骤1使用mineru解析工具进入mineru官网了解api的使用使用这个工具将上述文档解析成md文件以及多个其他文件文件目录如下具体的代码可以参考下方代码通过api将文件批量转换然后将解析后的结果下载到本地。# --- 配置区 --- TOKEN mineru的API替换成你的 INPUT_DIR 所要解析的文件夹路径 # 放待解析文件的文件夹 OUTPUT_ROOT ../RAG_Chunk/output # 结果存放根目录 CHUNK_SIZE 800 # 文本切片长度字符 HEADERS { Authorization: fBearer {TOKEN}, Content-Type: application/json } def process_files(): # 1. 扫描文件 files_to_process [f for f in os.listdir(INPUT_DIR) if f.lower().endswith((.pdf, .docx))] if not files_to_process: print(未发现 PDF 或 DOCX 文件。) return # 2. 申请上传 URL apply_url https://mineru.net/api/v4/file-urls/batch payload { files: [{name: f, data_id: f} for f in files_to_process], model_version: vlm } resp requests.post(apply_url, headersHEADERS, jsonpayload) res_data resp.json() if res_data.get(code) ! 0: print(f申请 URL 失败: {res_data.get(msg)}) return batch_id res_data[data][batch_id] file_urls res_data[data][file_urls] # 3. 执行文件上传 for idx, f_name in enumerate(files_to_process): file_path os.path.join(INPUT_DIR, f_name) with open(file_path, rb) as f: up_resp requests.put(file_urls[idx], dataf) if up_resp.status_code 200: print(f已上传: {f_name}) else: print(f上传失败: {f_name}) # 4. 轮询结果 print(f正在等待解析结果 (Batch ID: {batch_id})...) result_url fhttps://mineru.net/api/v4/extract-results/batch/{batch_id} while True: time.sleep(10) # 每10秒询问一次 try: response requests.get(result_url, headersHEADERS) res_poll response.json() if res_poll.get(code) 0: extract_data res_poll.get(data, {}) results_list extract_data.get(extract_result, []) if not results_list: print(服务器正在排队初始化...) continue # 检查是否所有文件都已经完成 (state done) # 如果有一个文件还是 running 或 pendingall_finished 就会是 False all_finished all(item.get(state) done for item in results_list) # 打印一下当前的进度方便你观察 for item in results_list: file_name item.get(file_name, 未知文件) state item.get(state) progress item.get(extract_progress, {}) pages f{progress.get(extracted_pages, 0)}/{progress.get(total_pages, 0)} print(f任务状态: [{state}] | 进度: {pages} | 文件: {file_name}) if all_finished: print(--- 所有文件解析完成开始执行后续处理 ---) handle_results(results_list) # 此时 results_list 里的 item 才会包含结果链接/内容 break else: print(部分文件仍在解析中请稍候...) else: print(f接口报错: {res_poll.get(msg)}) except Exception as e: print(f轮询发生异常: {e}) def handle_results(results_list): 下载 ZIP 并完整解压到对应文件夹随后对其中的 Markdown 进行切片 if not os.path.exists(OUTPUT_ROOT): os.makedirs(OUTPUT_ROOT) for item in results_list: file_name item.get(file_name, 未知文件) # 1. 创建对应的子文件夹例如附件2数据治理... folder_name os.path.splitext(file_name)[0] target_dir os.path.join(OUTPUT_ROOT, folder_name) os.makedirs(target_dir, exist_okTrue) # 2. 获取下载链接 zip_url item.get(full_zip_url) if not zip_url: print(f跳过 {file_name}未发现下载链接。) continue print(f正在下载并全量解压: {file_name}...) try: # 3. 下载 ZIP r requests.get(zip_url) r.raise_for_status() # 4. 完整解压到 target_dir with zipfile.ZipFile(io.BytesIO(r.content)) as z: z.extractall(target_dir) print(f已解压所有文件至: {target_dir}) # 5. 寻找解压后的 Markdown 文件用于切片 md_files [f for f in z.namelist() if f.endswith(.md)] if md_files: # 读取第一个找到的 md 文件内容 md_path os.path.join(target_dir, md_files[0]) with open(md_path, r, encodingutf-8) as f: content f.read() fix_content fix_markdown_headings(content) # 执行切片逻辑 perform_chunking(fix_content, target_dir, folder_name) else: print(f提示{file_name} 压缩包内没找到 .md 文件跳过切片。) except Exception as e: print(f处理文件 {file_name} 时出错: {e})步骤2对解析后的md文件正则化因为解析后的md文件所有的标题都变成了一级标题如果按照标题去切分的话再远数据中是看不到标题的层级关系的所以为了解决这个问题我们应该针对md文件编写一个正则化函数将其中的一级二级三级...标题的格式改正确下边是代码示例注意不同的文件应该对应写正则化函数下边的只能作为参考def fix_markdown_headings(text): lines text.split(\n) fixed_lines [] for line in lines: original_line line.strip() if not original_line: fixed_lines.append() continue # 剥洋葱去掉原本乱掉的 # core_content original_line.lstrip(#).strip() # --- 匹配逻辑 (按层级深度从 5 到 1 反向匹配或严格区分) --- # 1. 五级标题(1) 现场应用 if re.match(r^[\(]\d[\)], core_content): fixed_lines.append(f##### {core_content}) # 2. 四级标题2、智慧工地 (数字 顿号) elif re.match(r^\d、, core_content): fixed_lines.append(f#### {core_content}) # 3. 三级标题任务 2... 或 (一) 第一阶段 # 匹配 任务 开头 或 (一) 开头 elif re.match(r^任务\s*\d, core_content) or re.match(r^[\(][一二三四五六七八九十][\)], core_content): fixed_lines.append(f### {core_content}) # 4. 二级标题一、基础管理提升工程 elif re.match(r^[一二三四五六七八九十]、, core_content): fixed_lines.append(f## {core_content}) # 5. 一级标题第五章 重点任务 elif re.match(r^第[一二三四五六七八九十百][章部分], core_content): fixed_lines.append(f# {core_content}) else: # 不符合上述特征的保持原样 fixed_lines.append(original_line) return \n.join(fixed_lines)步骤三切分文档就是先按照标题切分Chunk然后如果当前块的大小超过了阈值就用字符切分最后保存成json文件代码如下def perform_chunking(content, target_dir, folder_name): 使用 LangChain 的两步走策略进行切片并保存为 JSON 格式 if not content: print(f内容为空跳过切片。) return # 1. 第一步按 Markdown 标题层级切分 headers_to_split_on [ (#, Header 1), (##, Header 2), (###, Header 3), (####, Header 4), (#####, Header 5), ] header_splitter MarkdownHeaderTextSplitter(headers_to_split_onheaders_to_split_on) header_action_chunks header_splitter.split_text(content) # 2. 第二步二次递归切分控制在 800 字符以内重叠 100 字符 text_splitter RecursiveCharacterTextSplitter( chunk_size800, chunk_overlap100 ) final_docs text_splitter.split_documents(header_action_chunks) # 3. 构造 JSON 数据结构 chunks_data [] for i, doc in enumerate(final_docs): chunks_data.append({ chunk_id: i 1, metadata: doc.metadata, # 包含 Header 1, Header 2 等层级信息 page_content: doc.page_content # 文本内容 }) # 4. 准备保存路径保存在对应的文件夹内 # 如果你希望所有 JSON 都在同一个根目录下可以修改这里的路径逻辑 json_file_path os.path.join(target_dir, f{folder_name}.json) # 5. 写入 JSON 文件 try: with open(json_file_path, w, encodingutf-8) as f: # ensure_asciiFalse 保证中文字符正常显示indent4 方便人类阅读 json.dump(chunks_data, f, ensure_asciiFalse, indent4) print(f[{folder_name}] 切片完成已生成 {len(chunks_data)} 个切片保存至 {json_file_path}) except Exception as e: print(f[{folder_name}] 保存 JSON 出错: {e})

相关新闻

2026年名义雇主服务EOR海外用工人力资源解决方案品牌排行榜,助力企业全球布局

2026年名义雇主服务EOR海外用工人力资源解决方案品牌排行榜,助力企业全球布局

在全球化的背景下,名义雇主服务(EOR人力资源解决方案)为企业提供了一种高效的海外用工方案,帮助他们快速适应不同国家的劳动法规。随着市场竞争的加剧,众多服务商不断涌现,为满足企业的国际化需求而努力。在…

2026/5/17 11:53:28 阅读更多 →
OpenAI收购Promptfoo 强化AI应用测试与安全评估能力

OpenAI收购Promptfoo 强化AI应用测试与安全评估能力

OpenAI Group PBC今日宣布,计划收购人工智能应用测试和安全评估平台初创公司Promptfoo Inc.,收购价格未披露。Promptfoo成立于2024年,最初是一个用于评估AI提示词和模型行为的开源框架。后来扩展为商业平台,为开发者和企业安全团队…

2026/5/17 11:53:29 阅读更多 →
第五节课所学内容

第五节课所学内容

for循环 for(表达式1; 表达式2; 表达式3) 表达式1 ⽤于循环变量的初始化 表达式2 ⽤于循环结束条件的判断 表达式3 ⽤于循环变量的调整 for(i 1; i < 10; i) 创建变量/条件/执行 如果for循环底下还有一个if语句 先判断条件&#xff0c;再if语句&#xff0c;最后执行 如果if…

2026/5/17 11:53:27 阅读更多 →

最新新闻

自动整列机PLC控制系统验证方案设计与ALCOA+实现

自动整列机PLC控制系统验证方案设计与ALCOA+实现

在制药行业&#xff0c;计算机化系统验证&#xff08;CSV&#xff09;是设备合规投入生产的必要环节。对于产线后端的自动整列机&#xff08;或称自动码盘机、整列收瓶机&#xff09;而言&#xff0c;其PLC控制系统的验证需要覆盖硬件确认、软件功能测试、数据完整性验证等多个…

2026/7/3 17:56:05 阅读更多 →
中外大模型能力对比分析

中外大模型能力对比分析

中外大模型能力差距&#xff1a;结构性成因的深度分析属性说明文档版本v1.0撰写日期2026-07-02文档类型技术战略分析分析视角机制解释&#xff0c;而非榜单罗列 摘要 「国产大模型不如国外」是一个过于粗糙的命题。截至 2026 年上半年&#xff0c;斯坦福 HAI《AI Index 2026》指…

2026/7/3 17:52:04 阅读更多 →
GHelper:如何用开源工具彻底解放你的华硕笔记本性能潜力?

GHelper:如何用开源工具彻底解放你的华硕笔记本性能潜力?

GHelper&#xff1a;如何用开源工具彻底解放你的华硕笔记本性能潜力&#xff1f; 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vivoboo…

2026/7/3 17:52:04 阅读更多 →
LENA-R8与PIC18LF45K40的嵌入式通信与精确定位方案

LENA-R8与PIC18LF45K40的嵌入式通信与精确定位方案

1. LENA-R8与PIC18LF45K40的硬件组合解析这个组合的核心价值在于将蜂窝通信与精确定位能力集成到嵌入式系统中。LENA-R8是u-blox推出的多模LTE Cat 1模块&#xff0c;支持14个LTE频段和4个GSM/GPRS频段&#xff0c;这意味着它能在全球绝大多数地区实现网络连接。其内置的u-blox…

2026/7/3 17:52:04 阅读更多 →
心电自监督分类论文分享(1)-read your heart

心电自监督分类论文分享(1)-read your heart

READING YOUR HEART 研究背景与动机 现有心电自监督学习分为对比学习、重构学习两类&#xff0c;但全部把心电当做普通时序信号&#xff0c;采用固定窗口、固定步长切割波形&#xff0c;存在两个核心缺陷&#xff1a; 丢失心电专属形态、节律特征破坏心跳间潜在语义关系 为…

2026/7/3 17:50:04 阅读更多 →
AI编程高效学习路径:从Python速成到文本分类实战

AI编程高效学习路径:从Python速成到文本分类实战

1. 为什么选择这条AI编程学习路径&#xff1f;我见过太多人被AI编程的学习门槛劝退。要么被复杂的数学公式吓跑&#xff0c;要么在环境配置阶段就耗尽耐心&#xff0c;还有人在工具选择上反复折腾却始终无法开始真正编码。经过三年多的AI教学实践&#xff0c;我总结出一条最适合…

2026/7/3 17:50:04 阅读更多 →

日新闻

Nginx防御TLS重协商攻击实战:从原理到配置与监控

Nginx防御TLS重协商攻击实战:从原理到配置与监控

1. 项目概述&#xff1a;为什么TLS重协商攻击至今仍需警惕十多年前的CVE-2011-1473&#xff0c;一个关于TLS/SSL协议重协商机制的漏洞&#xff0c;现在提起来还有必要吗&#xff1f;很多运维和开发朋友可能会觉得&#xff0c;这都老掉牙了&#xff0c;现代服务器和客户端不都默…

2026/7/3 0:03:59 阅读更多 →
华为防火墙双通道远程管理实战:Web与SSH配置详解

华为防火墙双通道远程管理实战:Web与SSH配置详解

1. 项目概述&#xff1a;为什么需要双通道远程管理防火墙&#xff1f;在任何一个稍具规模的企业网络里&#xff0c;防火墙都是那个默默守护在边界的关键角色。作为网络工程师&#xff0c;我们不可能每次都跑到机房&#xff0c;插上console线去配置它。远程管理能力&#xff0c;…

2026/7/3 0:03:59 阅读更多 →
AD74413R与PIC18F65K40的高精度工业数据采集方案

AD74413R与PIC18F65K40的高精度工业数据采集方案

1. 项目概述&#xff1a;AD74413R与PIC18F65K40的协同工作在工业自动化和精密测量领域&#xff0c;同时实现高精度模数转换(ADC)和数模转换(DAC)功能是许多复杂系统的核心需求。AD74413R作为一款四通道可配置模拟输入/输出器件&#xff0c;与PIC18F65K40微控制器的组合&#xf…

2026/7/3 0:05:59 阅读更多 →

周新闻

月新闻