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

RAG基础:基于markdown_split的Markdown文本分割实战

一、要求实现如下功能:

功能:

  • headers_to_split_on

  • 支出混合的拆块(支持 chunk_size、chunk_overlap)

  • 支持 chunk 元数据

  • markdown 中的代码不拆分

  • 支持strip_headers 参数设置

二、题解

思路解析:

实现思路
1. 分层处理策略 :
- 第一层:使用 MarkdownHeaderTextSplitter 按标题级别分割文本,保留标题结构
- 第二层:对非代码块内容使用 RecursiveCharacterTextSplitter 进行语义分割
- 特殊处理:识别并完整保留代码块,不进行拆分

2. 核心功能实现 :
- 标题分割 :通过 headers_to_split_on 参数定义要分割的标题级别
- 混合拆块 :结合标题分割和字符分割,支持 chunk_size 和 chunk_overlap 参数
- 元数据保留 :在分割过程中传递和保留文档元数据
- 代码块保护 :通过检测代码块标记(```),确保代码块完整性

3. 技术要点 :
- 使用状态机识别代码块的开始和结束
- 对普通文本和代码块采用不同的处理策略
- 保留原始文档的元数据信息
- 支持自定义标题级别和分割参数

代码:

from langchain_text_splitters import MarkdownHeaderTextSplitter,RecursiveCharacterTextSplitter def markdown_split( markdown_text, # 输入的Markdown文本 headers_to_split_on=None, # 要分割的标题级别 chunk_size=500, # 单个块最大字符数 chunk_overlap=100, # 相邻块重叠字符数 code_block_handling=True # 是否保留代码块完整性 ): """ Markdown文本分割函数 Args: markdown_text: 输入的Markdown文本 headers_to_split_on: 要分割的标题级别,格式为[(\"#\", \"一级标题\"), (\"##\", \"二级标题\")] chunk_size: 单个块最大字符数 chunk_overlap: 相邻块重叠字符数 code_block_handling: 是否保留代码块完整性 Returns: 分割后的Document对象列表 """ # 默认标题级别 if headers_to_split_on is None: headers_to_split_on = [ ("#", "一级标题"), ("##", "二级标题"), ("###", "三级标题"), ] # 1. 使用MarkdownHeaderTextSplitter按标题分割 markdown_splitter = MarkdownHeaderTextSplitter( headers_to_split_on=headers_to_split_on, strip_headers=False, return_each_line=False ) # 执行标题分割 header_split_docs = markdown_splitter.split_text(markdown_text) # 2. 初始化递归字符分割器,用于二次分割长内容 text_splitter = RecursiveCharacterTextSplitter( chunk_size=chunk_size, chunk_overlap=chunk_overlap, separators=["\n\n", "\n", "。", "!", "?", ";", ",", " "], length_function=len, is_separator_regex=False ) # 3. 处理每个标题分割后的部分 final_docs = [] for doc in header_split_docs: content = doc.page_content metadata = doc.metadata.copy() # 如果需要保留代码块完整性 if code_block_handling and "```" in content: # 分割代码块和普通文本 parts = [] # current_part = "" in_code_block = False for line in content.split("\n"): if line.startswith("```"): if in_code_block: # 代码块结束 current_part += line + "\n" parts.append((current_part, True)) # True表示是代码块 current_part = "" in_code_block = False else: # 代码块开始 if current_part: parts.append((current_part, False)) # False表示普通文本 current_part = line + "\n" in_code_block = True else: current_part += line + "\n" # 处理最后一个部分 if current_part: parts.append((current_part, False)) # 对普通文本进行分割,保留代码块完整 for part, is_code in parts: if is_code: # 代码块直接添加,不分割 final_docs.append(type(doc)(page_content=part, metadata=metadata)) else: # 普通文本使用递归分割器 sub_docs = text_splitter.create_documents([part]) for sub_doc in sub_docs: # 保留原始元数据 sub_doc.metadata = metadata.copy() final_docs.append(sub_doc) else: # 不需要保留代码块完整性,直接使用递归分割器 sub_docs = text_splitter.create_documents([content]) for sub_doc in sub_docs: # 保留原始元数据 sub_doc.metadata = metadata.copy() final_docs.append(sub_doc) return final_docs with open("测试数据.md",'r',encoding='utf-8')as f: test_markdown=f.read() # 执行分割 result_docs = markdown_split( test_markdown, chunk_size=200, chunk_overlap=50 ) # 输出结果 print("=== markdown_split 分割结果 ===") for i, doc in enumerate(result_docs, 1): print(f"\n块 {i}:") print(f"字符数: {len(doc.page_content)}") print(f"元数据: {doc.metadata}") print(f"内容:\n{doc.page_content}") print("-" * 80)

运行结果:

数据样例已上传。

http://www.jsqmd.com/news/338307/

相关文章:

  • 高客单价品牌如何选择GEO合作商?推荐这家“决策工程师” - 资讯焦点
  • 每日AI分享-2月3日(提示词管理插件+AI对话记录+Skills认识)
  • 同程国际机票出票速度解析:智能系统如何优化全球票务效率 - 资讯焦点
  • 汽车制造数字化转型如何选择靠谱的产业链服务商?
  • 2026年特种设备认证咨询优质机构推荐榜 - 优质品牌商家
  • 想学好免费公众号SVG教程,新手掌握这3个微信图文排版技巧不就够了?丨svg制作工具推荐 - peipei33
  • 2 月做题记录
  • 反检测浏览器有什么用?怎么选择适合的反检测浏览器? - Roxy指纹浏览器
  • 1/19
  • 同程国际航班改签通知体系:从被动等待到主动守护的智能化升级 - 资讯焦点
  • 基于深度学习YOLOv11的密集行人识别检测系统(YOLOv11+YOLO数据集+UI界面+登录注册界面+Python项目源码+模型)
  • 千匠网络B2B电商解决方案,赋能家居建材行业经销业务 - 圆圆小达人
  • 2026年高端安保服务优质机构推荐榜:王牌保镖、男保镖、专业保镖、临时保镖雇佣、保镖公司服务、保镖司机助理、保镖雇佣选择指南 - 优质品牌商家
  • 留学中介排行榜TOP10,港校申请提速开挂 - 博客湾
  • 新能源改装国产卡钳机电协同评测报告 - 改装小龙
  • 金属检测机的核心原理与技术指标解析
  • 拒绝盲目跟风,上海十大留学中介精准择校 - 博客湾
  • 香港留学机构排名TOP10,把好港校申请关 - 博客湾
  • 企业如何选择高效能的会员管理系统?
  • 【BiFormer】BiFormer: Vision Transformer with Bi-Level Routing Attention 译读笔记
  • Linux---进程概念(一)——冯诺依曼体系、操作强大的系统、进程、PCB的概念讲解
  • 食品金属检测机:生产线的最后一道安全哨兵
  • ArduPilot 概述
  • Java中基于角色的访问控制(RBAC)扩展:增加数据权限维度的实践与思考
  • 香港留学中介测评:哪家与港校关系最铁 衔接最顺畅? - 博客湾
  • 2026年评价高的出口变压器公司推荐:SCB12节能型干式电力变压器、S11油浸式铜芯变压器、S13型油浸式电力变压器选择指南 - 优质品牌商家
  • 蘑菇可食用性分类识别_YOLO11分割模型实现与优化_1
  • 大昌华嘉|抗老不烂脸的维A衍生视黄醇亚油酸酯 - 品牌排行榜
  • 香港留学中介测评:哪家文书个性化最强 拒绝模板化? - 博客湾
  • 合肥三十六行 (镇江) 分公司:四大平台领衔 镇江团购代运营增长引擎 - 野榜数据排行