news 2026/7/12 23:08:50

Markdown文本切割方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Markdown文本切割方案

对 Markdown 文本进行切分,LangChain 提供了两种核心方案,分别适用于不同的场景。最推荐且最灵活的方式是组合使用它们:先用MarkdownHeaderTextSplitter按标题结构切分,再用RecursiveCharacterTextSplitter控制块大小。

下面我来详细分析这两种方案,并给出完整的代码示例。

🔍 两种核心切分方案对比

方案

核心原理

优势

适用场景

MarkdownHeaderTextSplitter

根据 Markdown 标题(如#,##)来分割文档,将同一标题层级下的内容聚合为一个块,并将标题信息存储为元数据(Metadata)。

最大限度地保留文档的语义结构和上下文。检索时可以根据标题元数据进行过滤,精确找到特定章节的内容。

需要利用文档结构进行检索的 RAG 应用,例如基于技术文档、产品手册的问答系统。

RecursiveCharacterTextSplitter(withmarkdownlanguage)

通过一个包含 Markdown 语法特定分隔符(如\n\n,\n, , "")的列表,递归地尝试分割文本,优先保持段落、句子等语义单元的完整性。

实现简单,能有效控制块的大小,防止单个块过大或过小,通用性强。

对文档结构要求不高,主要目标是控制输入大模型文本长度的场景。

🚀 最佳实践方案:组合切分

在实际应用中,通常将两者结合,以达到最佳效果:

  1. 第一阶段:按标题切分- 使用MarkdownHeaderTextSplitter将文档按标题层级分割成大的语义块,并提取元数据。

  2. 第二阶段:按字符递归切分- 对每个大的语义块,使用RecursiveCharacterTextSplitter进一步切分成适合嵌入(Embedding)和检索的小块,并继承第一阶段的元数据。

代码示例

以下是一个完整的 Python 代码示例,演示了如何对 Markdown 文档进行组合切分,并查看结果。

# 首先,安装必要的库 (如果尚未安装) # pip install langchain langchain-text-splitters from langchain.text_splitter import MarkdownHeaderTextSplitter, RecursiveCharacterTextSplitter # 1. 准备一个示例 Markdown 文档 markdown_document = """ # 人工智能简介 人工智能(AI)是计算机科学的一个分支,它致力于创建能够执行通常需要人类智能的任务的系统。 ## 机器学习 机器学习是 AI 的一个子集,它使系统能够从数据中学习并改进,而无需明确编程。 ### 监督学习 监督学习使用标记数据集来训练算法,以分类数据或预测结果。 ### 无监督学习 无监督学习使用未标记的数据,算法必须自己找到数据中的模式和关系。 ## 深度学习 深度学习是机器学习的子集,它使用包含多个层的神经网络。这也被称为深度神经网络。 # AI 的应用领域 ## 自然语言处理 自然语言处理(NLP)使计算机能够理解、解释和生成人类语言。 ## 计算机视觉 计算机视觉赋予计算机“看”和理解视觉世界的能力。 """ # 2. 第一阶段:定义我们想要切分的标题层级和对应的元数据键名 headers_to_split_on = [ ("#", "H1"), # 一级标题 ("##", "H2"), # 二级标题 ("###", "H3"), # 三级标题 ] # 创建 MarkdownHeaderTextSplitter 实例 # strip_headers=False 表示保留标题文本在内容中,True 则移除标题文本 markdown_splitter = MarkdownHeaderTextSplitter( headers_to_split_on=headers_to_split_on, strip_headers=False ) # 按标题进行切分,返回一个 Document 列表,每个 Document 都带有 metadata md_header_splits = markdown_splitter.split_text(markdown_document) print("="*30) print("第一阶段切分结果:") print("="*30) for i, doc in enumerate(md_header_splits): print(f"Chunk {i+1}:") print(f" Metadata: {doc.metadata}") print(f" Content Preview: {doc.page_content[:50]}...") print("-"*20) # 3. 第二阶段:对每个标题块进一步进行递归字符切分 # 设置目标块大小和重叠量 chunk_size = 100 chunk_overlap = 20 text_splitter = RecursiveCharacterTextSplitter( chunk_size=chunk_size, chunk_overlap=chunk_overlap, # 可以自定义分隔符列表,例如添加中文句号以优化中文分割 separators=["\n\n", "\n", "。", "!", "?", ";", ",", " ", ""] ) # 对按标题切分后的文档列表进行递归切分,每个小块会继承其来源的标题元数据 final_chunks = text_splitter.split_documents(md_header_splits) print("\n" + "="*30) print("第二阶段(最终)切分结果:") print("="*30) for i, chunk in enumerate(final_chunks): print(f"Final Chunk {i+1}:") print(f" Metadata: {chunk.metadata}") print(f" Length: {len(chunk.page_content)} chars") print(f" Content: {repr(chunk.page_content)}") print("-"*30)
代码输出示例
============================== 第一阶段切分结果: ============================== Chunk 1: Metadata: {'H1': '人工智能简介'} Content Preview: # 人工智能简介 人工智能(AI)是计算机科学的一个分支... -------------------- Chunk 2: Metadata: {'H1': '人工智能简介', 'H2': '机器学习'} Content Preview: ## 机器学习 机器学习是 AI 的一个子集,它使... -------------------- Chunk 3: Metadata: {'H1': '人工智能简介', 'H2': '机器学习', 'H3': '监督学习'} Content Preview: ### 监督学习 监督学习使用标记数据集来训... -------------------- Chunk 4: Metadata: {'H1': '人工智能简介', 'H2': '机器学习', 'H3': '无监督学习'} Content Preview: ### 无监督学习 无监督学习使用未标记的数据,算... -------------------- Chunk 5: Metadata: {'H1': '人工智能简介', 'H2': '深度学习'} Content Preview: ## 深度学习 深度学习是机器学习的子集,它使... -------------------- Chunk 6: Metadata: {'H1': 'AI 的应用领域'} Content Preview: # AI 的应用领域 ## 自然语言处理 自然语言处理(NLP)... -------------------- Chunk 7: Metadata: {'H1': 'AI 的应用领域', 'H2': '自然语言处理'} Content Preview: ## 自然语言处理 自然语言处理(NLP)使计算机能... -------------------- Chunk 8: Metadata: {'H1': 'AI 的应用领域', 'H2': '计算机视觉'} Content Preview: ## 计算机视觉 计算机视觉赋予计算机“看”和理解... -------------------- ... (后续会展示第二阶段切分后的更小块)

💡 参数调优建议

  1. chunk_sizechunk_overlap:这是最关键的参数。chunk_size通常在500-1000个字符之间效果较好。chunk_overlap一般设置为chunk_size10%-20%,以防止关键信息在切分边界处丢失。

  2. separators优化:在处理中文文档时,可以在RecursiveCharacterTextSplitterseparators列表中添加中文句号()、感叹号()、问号()等,使切分更符合中文的语义边界。

  3. strip_headersMarkdownHeaderTextSplitter的参数。如果希望在最终块的内容中保留标题文本以便模型阅读上下文,设置为False;如果希望内容更纯净,仅将标题用于元数据过滤,设置为True

  4. return_each_lineMarkdownHeaderTextSplitter的参数。如果希望对每个文本行进行更精细的控制(例如,自定义聚合逻辑),可以启用此选项,让分割器返回单行文档。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/23 7:27:26

2026/3/21、

一、如何处理多返回值7、*结构体*/////////////////////////////////////1、c中方法在参数中增加多个引用,用他们接住要返回的值void classes (int a,int b,std::string& outc,std::string& outd){outcab;outdc-b;}2、new一个字符串数组接住std:…

作者头像 李华
网站建设 2026/3/23 7:24:36

MS1100 VOC气体传感器原理与RT-Thread嵌入式驱动实现

1. MS1100气体传感器技术解析与工程实现1.1 传感器原理与应用定位MS1100(亦称CJMCU-1100或MS-1100)是一款基于金属氧化物半导体(MOS)技术的宽谱挥发性有机化合物(VOC)气体传感器。其核心敏感材料在接触甲醛…

作者头像 李华
网站建设 2026/3/23 7:24:24

嵌入式电源防反接电路四大方案深度对比与选型指南

1. 电源防反接电路设计原理与工程选型分析在嵌入式硬件系统开发中,电源极性误接是导致板级损坏的最常见人为故障之一。尤其在工厂批量生产、现场调试或终端用户自行更换电源适配器的场景下,操作人员可能因疏忽将正负极反向接入供电端子。这种看似低级的错…

作者头像 李华
网站建设 2026/3/23 7:24:20

嵌入式总线错误与内存对齐深度解析

1. 嵌入式总线错误深度剖析:从原理到实践的系统性排查指南在嵌入式系统开发实践中,程序异常终止是工程师最常遭遇的挑战之一。其中,总线错误(Bus Error)因其触发条件隐蔽、表现形式多变、平台差异显著等特点&#xff0…

作者头像 李华
网站建设 2026/3/23 7:18:30

SF32LB52黄山派开发板:面向可穿戴设备的低功耗高集成硬件平台

1. 项目概述SF32LB52黄山派开发板是一款面向可穿戴设备原型开发的高性能嵌入式硬件平台,其核心定位为智能手表与手环类产品的功能验证与快速迭代载体。该开发板并非通用型评估板,而是以终端产品形态为设计导向——集成完整人机交互链路(显示、…

作者头像 李华