LangChain 文档转换器与文本分割器组件学习总结

26 阅读7分钟

LangChain 文档转换器与文本分割器组件学习总结

目录

  1. 字符文本分割器
  2. 递归字符文本分割器
  3. 程序代码递归分割器
  4. 语义分割器
  5. HTML标题分割器
  6. JSON分割器
  7. 自定义分割器
  8. 中英文混合文本分割
  9. 分割器选择指南
  10. 核心概念

1. 字符文本分割器

是什么

最基础的文本分割器,按照指定的分隔符将文本分割成块

有什么用

  • 简单的文本分割场景
  • 按固定分隔符(如换行符)切分文档

核心类

  • CharacterTextSplitter (from langchain_text_splitters)

核心参数

CharacterTextSplitter(
    separator="\n\n",          # 分隔符
    chunk_size=500,            # 每块大小
    chunk_overlap=50,          # 块之间重叠大小
    add_start_index=True       # 添加起始索引
)

示例代码

from langchain_text_splitters import CharacterTextSplitter
from langchain_community.document_loaders import UnstructuredMarkdownLoader

loader = UnstructuredMarkdownLoader(file_path)
documents = loader.load()

text_splitter = CharacterTextSplitter(
    separator="\n\n",
    chunk_size=500,
    chunk_overlap=50,
    add_start_index=True,
)

chunks = text_splitter.split_documents(documents)

for chunk in chunks:
    print(f"块大小:{len(chunk.page_content)}, 元数据:{chunk.metadata}")

2. 递归字符文本分割器(推荐)

是什么

更智能的分割器,会按多个分隔符顺序尝试分割,直到满足块大小要求

有什么用

  • 适用于大多数通用文本分割场景
  • 能够保持段落的完整性,不会在句子中间切分
  • 默认分隔符顺序:["\n\n", "\n", " ", ""]

核心类

  • RecursiveCharacterTextSplitter (from langchain_text_splitters)

核心参数

RecursiveCharacterTextSplitter(
    chunk_size=500,             # 每块大小
    chunk_overlap=50,           # 块之间重叠大小
    add_start_index=True,       # 添加起始索引
    separators=["\n\n", "\n", " ", ""]  # 可自定义分隔符列表
)

示例代码

from langchain_text_splitters import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,
    chunk_overlap=50,
    add_start_index=True,
)

chunks = text_splitter.split_documents(documents)

for chunk in chunks:
    print(f"块大小: {len(chunk.page_content)}, 元数据: {chunk.metadata}")

3. 程序代码递归分割器

是什么

专门用于编程代码的分割器,针对不同编程语言优化

有什么用

  • 保留代码的完整性和语义
  • 按函数、类等代码结构切分
  • 避免在代码逻辑中间切分

核心类

  • RecursiveCharacterTextSplitter.from_language()
  • Language 枚举类

支持的语言

Python, JS, TypeScript, Java, C++, C, Go, PHP, Ruby, Rust, Swift, Markdown, LaTeX, HTML 等

示例代码

from langchain_text_splitters import RecursiveCharacterTextSplitter, Language

text_splitter = RecursiveCharacterTextSplitter.from_language(
    language=Language.PYTHON,
    chunk_size=500,
    chunk_overlap=50,
    add_start_index=True,
)

chunks = text_splitter.split_documents(documents)

for chunk in chunks:
    print(f"块大小: {len(chunk.page_content)}, 元数据: {chunk.metadata}")

print(chunks[2].page_content)  # 查看具体的代码块

4. 语义分割器

是什么

基于语义相似度的分割器,使用embedding模型计算文本语义边界

有什么用

  • 按语义相关性分割,保持语义连贯性
  • 适合需要理解文本含义的场景
  • 能够识别话题变化点

核心类

  • SemanticChunker (from langchain_experimental.text_splitter)

核心参数

SemanticChunker(
    embeddings=QianfanEmbeddingsEndpoint(),  # 嵌入模型
    number_of_chunks=10,                      # 分割块数
    add_start_index=True,
    sentence_split_regex=r"(?<=[。?!.?!])"  # 句子分割正则
)

示例代码

from langchain_experimental.text_splitter import SemanticChunker
from langchain_community.embeddings.baidu_qianfan_endpoint import QianfanEmbeddingsEndpoint
import dotenv

dotenv.load_dotenv()

text_splitter = SemanticChunker(
    embeddings=QianfanEmbeddingsEndpoint(),
    number_of_chunks=10,
    add_start_index=True,
    sentence_split_regex=r"(?<=[。?!.?!])"
)

documents = loader.load()
chunks = text_splitter.split_documents(documents)

for chunk in chunks:
    print(f"块大小: {len(chunk.page_content)}, 元数据: {chunk.metadata}")

print(chunks[0].page_content)

5. HTML标题分割器

是什么

专门用于HTML文档的分割器,按照HTML标题层级切分

有什么用

  • 保留HTML文档的结构层次
  • 适合处理网页、博客文章等HTML内容
  • 自动保留标题元数据

核心类

  • HTMLHeaderTextSplitter (from langchain_text_splitters)

核心参数

headers_to_split_on = [
    ("h1", "一级标题"),
    ("h2", "二级标题"),
    ("h3", "三级标题"),
]

示例代码

from langchain_text_splitters import HTMLHeaderTextSplitter

html_string = """
<!DOCTYPE html>
<html>
<body>
    <div>
        <h1>标题1</h1>
        <p>关于标题1的一些介绍文本。</p>
        <div>
            <h2>子标题1</h2>
            <p>关于子标题1的一些介绍文本。</p>
        </div>
    </div>
</body>
</html>
"""

headers_to_split_on = [
    ("h1", "一级标题"),
    ("h2", "二级标题"),
    ("h3", "三级标题"),
]

text_splitter = HTMLHeaderTextSplitter(headers_to_split_on)
chunks = text_splitter.split_text(html_string)

for chunk in chunks:
    print(chunk)

6. JSON分割器

是什么

递归分割JSON数据的分割器,可以处理嵌套的JSON结构

有什么用

  • 处理大型JSON文件或API响应
  • 保留JSON的层次结构
  • 避免破坏JSON数据的完整性

核心类

  • RecursiveJsonSplitter (from langchain_text_splitters)

核心参数

RecursiveJsonSplitter(max_chunk_size=300)  # 最大块大小

示例代码

from langchain_text_splitters import RecursiveJsonSplitter
import requests
import json

# 获取JSON数据
url = "https://api.smith.langchain.com/openapi.json"
json_data = requests.get(url).json()
print(f"原始JSON大小: {len(json.dumps(json_data))}")

# 创建分割器
text_splitter = RecursiveJsonSplitter(max_chunk_size=300)

# 分割JSON数据
json_chunks = text_splitter.split_json(json_data)
chunks = text_splitter.create_documents(json_chunks)

# 输出结果
total_size = sum(len(chunk.page_content) for chunk in chunks)
print(f"分割后总大小: {total_size}")

7. 自定义分割器

是什么

继承TextSplitter基类,实现自定义的分割逻辑

有什么用

  • 特殊需求场景
  • 结合jieba等工具实现中文关键词提取等定制功能
  • 实现特定业务逻辑的文本处理

核心类

  • TextSplitter (基类)

关键方法

def split_text(self, text: str) -> List[str]:
    # 必须实现此方法
    pass

示例代码

from typing import List
from langchain_text_splitters import TextSplitter
import jieba.analyse

class CustomTextSplitter(TextSplitter):
    def __init__(self, separator: str = "\n\n", top_k: int = 10, **kwargs):
        super().__init__(**kwargs)
        self.separator = separator
        self.top_k = top_k

    def split_text(self, text: str) -> List[str]:
        # 按分隔符切分
        split_texts = text.split(self.separator)
        text_keywords = []

        # 对每段提取关键词
        for split_text in split_texts:
            keywords = jieba.analyse.extract_tags(split_text, topK=self.top_k)
            text_keywords.append(keywords)

        # 返回关键词字符串
        return [' '.join(keywords) for keywords in text_keywords]

# 使用自定义分割器
loader = UnstructuredFileLoader(file_path)
text_splitter = CustomTextSplitter("\n\n", 10)

documents = loader.load()
chunks = text_splitter.split_documents(documents)

for chunk in chunks:
    print(chunk.page_content)

8. 中英文混合文本分割

是什么

配置多个分隔符来处理中英文混合场景

有什么用

  • 处理中英文混合文档
  • 适配不同语言的标点符号
  • 保证分割后的文本块语义完整

分隔符配置示例

separators = [
    "\n\n",                # 段落分隔
    "\n",                  # 行分隔
    "。|!|?",            # 中文句号
    "\.\s|\!\s|\?\s",      # 英文标点+空格
    ";|;\s",              # 分号
    ",|,\s",              # 逗号
    " ",                   # 空格
    ""                     # 字符级别(最后手段)
]

示例代码

from langchain_text_splitters import RecursiveCharacterTextSplitter

separators = [
    "\n\n",
    "\n",
    "。|!|?",
    "\.\s|\!\s|\?\s",  # 英文标点符号后面通常需要加空格
    ";|;\s",
    ",|,\s",
    " ",
    ""
]

text_splitter = RecursiveCharacterTextSplitter(
    separators=separators,
    is_separator_regex=True,  # 启用正则表达式
    chunk_size=500,
    chunk_overlap=50,
    add_start_index=True,
)

documents = loader.load()
chunks = text_splitter.split_documents(documents)

for chunk in chunks:
    print(f"块大小: {len(chunk.page_content)}, 元数据: {chunk.metadata}")

分割器选择指南

场景推荐分割器说明
通用文本RecursiveCharacterTextSplitter最常用的选择,智能分割
代码文件RecursiveCharacterTextSplitter.from_language()保留代码结构
语义分割SemanticChunker基于语义相似度,需要embedding模型
HTML文档HTMLHeaderTextSplitter按标题层级分割
JSON数据RecursiveJsonSplitter处理嵌套JSON
简单分割CharacterTextSplitter基础固定分隔符
特殊需求自定义 TextSplitter实现特定逻辑
中英文混合RecursiveCharacterTextSplitter + 自定义separators配合正则表达式

核心概念

通用参数说明

参数说明推荐值
chunk_size每个文本块的目标字符数500-1000
chunk_overlap相邻块之间的重叠字符数50-200
separator用于分割的分隔符"\n\n", "\n"
separators分隔符列表(按优先级)见上方配置
add_start_index是否在元数据中记录起始位置True
is_separator_regex是否将分隔符作为正则表达式True/False

chunk_overlap 的作用

  • 保持上下文连贯:避免关键信息被分割到两个块的边界
  • 提高检索质量:重叠部分可以作为检索的冗余信息
  • 推荐设置:一般为 chunk_size 的 10%-20%

chunk_size 的选择

  • 太小:上下文不足,语义不完整
  • 太大:超出模型上下文窗口,检索精度下降
  • 推荐
    • 短文本:200-500
    • 中等文本:500-1000
    • 长文本:1000-2000

最佳实践

1. 优先使用递归分割器

# 推荐
RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)

# 不推荐(容易在句子中间切分)
CharacterTextSplitter(separator="\n", chunk_size=500)

2. 根据文档类型选择

# 代码文档
RecursiveCharacterTextSplitter.from_language(
    language=Language.PYTHON,
    chunk_size=1000
)

# HTML文档
HTMLHeaderTextSplitter(headers_to_split_on)

# API响应
RecursiveJsonSplitter(max_chunk_size=300)

3. 中英文场景处理

# 使用正则表达式分隔符
separators = [
    "\n\n",
    "\n",
    "。|!|?",
    "\.\s|\!\s|\?\s",
]
text_splitter = RecursiveCharacterTextSplitter(
    separators=separators,
    is_separator_regex=True
)

4. 保留元数据

# 始终添加起始索引
text_splitter = RecursiveCharacterTextSplitter(
    add_start_index=True  # 便于追溯原文位置
)

相关资源