LangChain 文本分块详解

本文介绍为什么要对文本进行分块,以及如何使用 LangChain 实现文本分割。

1. 为什么需要文本分块?

1.1 上下文窗口限制

大语言模型(LLM)有固定的上下文窗口限制,例如:

  • GPT-3.5 Turbo: 16,385 tokens
  • GPT-4: 128,000 tokens
  • Claude 3: 200,000 tokens

1.2 分块的优势

优势 说明
适应上下文限制 超过窗口限制的文本无法处理
提高检索精度 小块文本更容易匹配用户问题
降低 Token 成本 按需加载,减少不必要的消费
增强语义相关性 每块内容更聚焦,主题更明确

2. 安装依赖

!pip install langchain_text_splitters

3. 代码解析

3.1 完整代码

from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter

# 1. 加载文档
loader = TextLoader("./demo.txt", encoding="utf-8")
docs = loader.load()

# 2. 创建分块器
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,      # 每块的最大字符数
    chunk_overlap=40,    # 块之间的重叠字符数
    separators=["\n\n", "\n", "。", "!", "?", ",", "、", ""]
)

# 3. 执行分块
texts = text_splitter.split_documents(docs)

结果:
在这里插入图片描述

3.2 核心参数详解

参数 说明 推荐值
chunk_size 每块的最大字符数 300-1000
chunk_overlap 相邻块之间的重叠字符数 chunk_size 的 10-20%
separators 分隔符列表,按优先级排列 见下文

4. 分块策略

4.1 递归字符分块 (RecursiveCharacterTextSplitter)

RecursiveCharacterTextSplitter 是最常用的分块器,它会按顺序尝试每个分隔符:

separators=["\n\n", "\n", "。", "!", "?", ",", "、", ""]

分隔符优先级

优先级 分隔符 说明
1 \n\n 段落分隔(优先)
2 \n 换行符
3 句号
4 感叹号
5 问号
6 逗号
7 顿号
8 "" 单字符(最后兜底)

工作原理

  1. 先按 \n\n 分段
  2. 如果某段超过 chunk_size,按 \n 继续分割
  3. 如果还超限,按句子分隔符继续切割
  4. 最后按单字符分割

4.2 chunk_overlap 的作用

块1: [段落1 ....................] 500字符
块2: [..........40字符重叠.......段落2 ....] 500字符
块3: [..........40字符重叠.......段落3 ....]

为什么需要重叠?

  • 避免上下文丢失
  • 重要信息可能被切开,重叠能保证连续性

5. 其他分块器

5.1 简单字符分块

from langchain_text_splitters import CharacterTextSplitter

splitter = CharacterTextSplitter(
    separator="\n",
    chunk_size=500,
    chunk_overlap=40
)

5.2 按 Token 分块(更精确)

from langchain_text_splitters import TokenTextSplitter

splitter = TokenTextSplitter(
    chunk_size=100,  # 按 token 计算
    chunk_overlap=20
)

5.3 Markdown 分块

from langchain_text_splitters import MarkdownTextSplitter

splitter = MarkdownTextSplitter(chunk_size=500)

6. 分块大小选择

6.1 根据用途选择

用途 建议 chunk_size 说明
问答系统 500-1000 答案通常在几句话内
摘要生成 1000-2000 需要更多上下文
语义搜索 300-500 主题集中,检索更准

6.2 根据文档类型选择

文档类型 建议 chunk_size 建议 overlap
短文/新闻 300-500 20-50
技术文档 500-1000 50-100
书籍/长文 1000-2000 100-200

7. 完整示例

from langchain_community.document_loaders import TextLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter

# 1. 加载文档
loader = TextLoader("./demo.txt", encoding="utf-8")
docs = loader.load()

# 2. 配置分块器
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,
    chunk_overlap=40,
    separators=["\n\n", "\n", "。", "!", "?", ",", "、", ""]
)

# 3. 执行分块
texts = text_splitter.split_documents(docs)

# 4. 查看结果
print(f"共分成 {len(texts)} 个块")
print(texts[0].page_content)

8. 常见问题

Q1: chunk_size 设置多大合适?

从 500 开始,根据实际效果调整。太小丢失上下文,太大检索不精准。

Q2: chunk_overlap 必须设置吗?

不是必须的,但建议设置。0-20% 的重叠能保证语义连续性。

Q3: 如何选择分隔符?

  • 中文文档:使用中文标点符号
  • 英文文档:使用 \n\n, \n,
  • 代码文件:使用 \n, 函数/类定义分隔符

Q4: 分割后如何查看每块内容?

for i, text in enumerate(texts):
    print(f"=== 块 {i+1} ===")
    print(text.page_content)
    print()
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐