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

02:文本分块策略详解

学习笔记:详述 RAG 系统中文本分块的核心原理、主流策略、优化技巧以及工程实践

目录

  • 为什么分块至关重要
  • 分块的基本概念
    • 分块的核心参数
    • 分块大小的影响
  • 分块策略详解
    • 固定长度分块
    • 递归字符分块
    • 语义分块
    • 结构分块
    • 标题层级分块
    • 句子分块
    • LLM 分块
  • 高级分块技术
    • 重叠分块
    • 父文档分块
    • 小结分块
  • 不同文档类型的分块策略
    • Markdown 文档
    • PDF 文档
    • 代码文件
    • HTML 文档
  • 分块优化实践
    • 如何选择合适的分块策略
    • 分块参数的动态调整
    • 评估分块效果
  • 常见问题与解决方案
  • 工程工具推荐
  • 参考资料

为什么分块至关重要

文本分块(Chunking)是 RAG 系统的第一道门槛,直接影响后续检索和生成的效果。

分块决定检索质量

分块问题检索后果
Chunk 太小上下文不完整,关键信息被切散
Chunk 太大引入噪声,稀释关键信息
分块方式不当语义单元被破坏,检索不到相关内容

分块影响生成质量

  • 上下文完整:合理的分块能保留完整的语义单元,LLM 更容易理解
  • 信息密度:高信息密度的 chunk 能提高生成质量
  • 引用追溯:清晰的 chunk 边界便于生成时引用原始文档

分块的基本概念

分块的核心参数

参数说明常用值
chunk_size每个 chunk 的最大长度256~2048 tokens
chunk_overlap相邻 chunk 之间的重叠 token 数10%~20% chunk_size
separator分隔符换行符、句子边界、段落标记
length_function长度计算方式token 数量、字符数

分块大小的影响

分块大小选择指南

场景推荐 chunk 大小理由
代码检索256~512 tokens代码逻辑紧凑,需要精确匹配
短问答256~512 tokens问题简单,不需要过多上下文
文档问答512~1024 tokens平衡上下文与精确度
长文档摘要1024~2048 tokens需要完整上下文
多步骤推理512~1024 tokens保留推理链条

分块策略详解

1. 固定长度分块

原理:按固定的字符数或 token 数切分文本

# 伪代码示例text="这是一段很长的文本..."chunk_size=500chunks=[]foriinrange(0,len(text),chunk_size):chunks.append(text[i:i+chunk_size])

优点

  • 实现简单,逻辑清晰
  • 处理速度快
  • 输出 chunk 大小一致,便于管理

缺点

  • 可能切断句子、段落等语义单元
  • 不考虑文本结构
  • 可能丢失关键上下文

适用场景

  • 文本格式单一、结构简单
  • 对处理速度要求高
  • 初步原型验证

改进方向

  • 尽量在句子边界切分
  • 保留一定的重叠

2. 递归字符分块

原理:按层级递归切分,尝试多种分隔符

LangChain 实现

fromlangchain.text_splitterimportRecursiveCharacterTextSplitter text_splitter=RecursiveCharacterTextSplitter(separators=["\n\n","\n","。","!","?"," ",""],chunk_size=500,chunk_overlap=50,length_function=len,)

分隔符优先级

优先级分隔符说明
1\n\n段落分隔,保持最大语义完整性
2\n换行符,常用于列表
3。!?句子结束符(中英文)
4.!?英文句子结束符
5单词边界
6""字符级别(兜底)

优点

  • 尽可能保持语义完整
  • 灵活适应不同文本结构
  • 业界最常用的分块策略

缺点

  • 参数调优需要经验
  • 对特殊文档格式效果可能不佳

适用场景

  • 通用文档处理
  • 文本结构多样
  • 生产环境首选

3. 语义分块

原理:基于文本语义相似性进行分块,将语义相近的内容聚合在一起

实现方式

方式说明优点缺点
Embedding 聚类用 Embedding 表示句子,聚类后分块语义准确计算成本高
滑动窗口滑动窗口计算局部相似度效率较高窗口大小难确定
LLM 判断用 LLM 判断是否应该分块效果好成本高、延迟大

LLM-as-a-Judge 分块示例

# 伪代码:使用 LLM 判断分块边界defshould_split(text_a,text_b):prompt=f""" 判断以下两段文本是否应该分开成不同的 chunk: 文本 A:{text_a}文本 B:{text_b}如果两段文本讨论的是不同主题或话题,返回 "YES"。 如果两段文本主题一致,只是内容展开,返回 "NO"。 """response=llm.invoke(prompt)return"YES"inresponse.text

优点

  • 分块边界更符合语义
  • 保留完整的主题内容
  • 检索质量更高

缺点

  • 计算成本较高
  • 实现复杂度大
  • 需要调优阈值

适用场景

  • 对检索质量要求高
  • 主题分明的长文档
  • 计算资源充足

4. 结构分块

原理:根据文档的显式结构(标题、层级、章节)进行分块

LangChain 实现

fromlangchain.text_splitterimportMarkdownTextSplitter splitter=MarkdownTextSplitter(chunk_size=500,chunk_overlap=50,)

优点

  • 保留文档结构信息
  • 分块边界符合阅读习惯
  • 便于追溯原文位置

缺点

  • 依赖文档格式
  • 无结构文档不适用
  • 需要提取文档结构

适用场景

  • Markdown、reStructuredText 等结构化文档
  • 技术文档、API 文档
  • 有明确章节结构的文档

5. 标题层级分块

原理:按照文档的标题层级(如 H1、H2、H3)进行分块

优点

  • 保留层级上下文
  • 便于定位和引用
  • 用户体验好

缺点

  • 只适用于 HTML 等有标题标记的文档
  • 层级深度不好控制

适用场景

  • 网站文档
  • 帮助中心
  • 带目录的文档

6. 句子分块

原理:以完整句子为基本单元进行分块

fromlangchain.text_splitterimportSentenceTextSplitter splitter=SentenceTextSplitter(chunk_size=5,# 5 个句子chunk_overlap=2,# 2 个句子重叠)

优点

  • 保持句子完整性
  • 语义自然连贯
  • 便于阅读和理解

缺点

  • 句子长度差异大
  • 某些语言分句困难
  • chunk 大小不均匀

适用场景

  • 小说、散文等叙事性文本
  • 对句子完整性要求高的场景

7. LLM 驱动分块

原理:使用 LLM 智能判断分块边界

# 伪代码:LLM 驱动分块defllm_based_splitting(document):prompt=f""" 分析以下文档,识别主题边界,并给出分块建议:{document[:2000]}# 只发送开头部分 输出格式: - 用 "=== Section N ===" 标记每个新主题的开始 - 确保每个 section 主题内聚、主题间区分明显 """result=llm.invoke(prompt)returnparse_sections(result.text)

优点

  • 语义理解最准确
  • 可处理复杂文档
  • 分块质量最高

缺点

  • 成本高
  • 延迟大
  • 实现复杂

适用场景

  • 顶级质量要求
  • 复杂文档结构
  • 预算充足

高级分块技术

1. 重叠分块(Overlapping Chunks)

核心思想:相邻 chunks 之间保留重叠区域,避免关键信息被切断

重叠比例选择

场景重叠比例说明
通用场景10-20%平衡效果与存储
重要内容20-30%需要高召回
计算敏感5-10%减少重复计算

重叠分块的优缺点

优点缺点
减少信息丢失存储空间增加
关键信息更完整向量数据库存储更多
检索召回率提高检索可能返回重复内容

2. 父子文档分块

原理:创建多层级的 chunk,父 chunk 包含子 chunk

检索流程

1. 查询 → 子 Chunk 匹配 2. 子 Chunk → 父 Chunk 3. 父 Chunk → LLM 生成(保留完整上下文)

优点

  • 细粒度检索 + 完整上下文
  • 平衡精确性和完整性
  • 支持不同粒度的查询

实现要点

  • 建立父子映射关系
  • 存储时保留层级信息
  • 检索时同时返回父子 chunk

3. 小结分块(Summary Chunking)

原理:为每个 chunk 自动生成摘要,检索时使用摘要匹配

检索优化

# 检索时同时匹配原始文本和摘要query_vector=embed(query)# 方式1:分别检索后融合results_text=vector_db.search(query_vector,index="text")results_summary=vector_db.search(query_vector,index="summary")final_results=fusion_merge(results_text,results_summary)# 方式2:扩展查询expanded_query=f"{query}{summary}"

优点

  • 摘要更精确匹配查询
  • 提高检索召回率
  • 支持多角度检索

缺点

  • 生成摘要有成本
  • 存储空间增加
  • 摘要质量依赖 LLM

不同文档类型的分块策略

Markdown 文档

特点

  • 有明确的标题层级
  • 代码块需要特殊处理
  • 列表、表格结构化

推荐策略

fromlangchain.text_splitterimportMarkdownTextSplitter# 方式1:Markdown 专用分块器markdown_splitter=MarkdownTextSplitter(chunk_size=500,chunk_overlap=50,)# 方式2:组合策略fromlangchain.text_splitterimport(MarkdownHeaderTextSplitter,RecursiveCharacterTextSplitter,)# 先按标题分割header_splitter=MarkdownHeaderTextSplitter(headers_to_split_on=["#","##","###",])md_chunks=header_splitter.split_text(markdown_text)# 再对每个部分递归分块recursive_splitter=RecursiveCharacterTextSplitter(chunk_size=500,chunk_overlap=50,)final_chunks=recursive_splitter.split_documents(md_chunks)

注意事项

  • 代码块应作为独立 chunk 或排除
  • 表格内容需要特殊解析
  • 保持标题与内容的关联

PDF 文档

特点

  • 版面结构复杂
  • 可能包含图片、表格
  • 提取时可能丢失格式

推荐策略

# 使用 PDF 专用加载器fromlangchain_community.document_loadersimportPyPDFLoader loader=PyPDFLoader("document.pdf")pages=loader.load()# 按页面或段落分块fromlangchain.text_splitterimportRecursiveCharacterTextSplitter splitter=RecursiveCharacterTextSplitter(chunk_size=500,chunk_overlap=50,separators=["\n\n","\n","。"," "],)chunks=splitter.split_documents(pages)

PDF 提取工具对比

工具优点缺点
PyPDFLoader简单易用格式保留有限
PDFPlumber表格提取好速度较慢
PyMuPDF性能好依赖特殊处理
Unstructured智能分块资源消耗大

代码文件

特点

  • 有明确的语法结构
  • 函数、类有清晰边界
  • 注释与逻辑需要分离

推荐策略

fromlangchain.text_splitterimportLanguage# 按编程语言选择分块器python_splitter=RecursiveCharacterTextSplitter.from_language(language=Language.PYTHON,chunk_size=500,chunk_overlap=50,)# 或使用代码专用分块器fromlangchain.text_splitterimportCodeTextSplitter code_splitter=CodeTextSplitter(language="python",chunk_size=500,chunk_overlap=50,)

代码分块策略

优先级: 1. 类/函数定义(最高) 2. 代码块 3. 段落 4. 单行(兜底)

注意事项

  • 保持函数/类的完整
  • 保留必要的上下文
  • 处理跨文件引用

HTML 文档

特点

  • DOM 结构明确
  • 内容与样式混合
  • 需要提取正文
fromlangchain.text_splitterimportHTMLHeaderTextSplitter# 按标题层级分割html_splitter=HTMLHeaderTextSplitter(headers_to_split_on=[("h1","Header 1"),("h2","Header 2"),("h3","Header 3"),("h4","Header 4"),])html_chunks=html_splitter.split_text(html_string)

分块优化实践

如何选择合适的分块策略

策略选择矩阵

文档类型推荐策略备选策略关键参数
技术文档递归分块 + 结构语义分块chunk_size=500-800
论文报告递归分块句子分块chunk_size=800-1000
聊天记录句子分块固定长度chunk_size=300-500
代码文件代码专用分块递归分块按函数/类边界
网页内容HTML 分块语义分块保留标题层级
法律文档递归分块父子文档chunk_size=1000+,大重叠

分块参数的动态调整

基于查询类型的自适应分块

defadaptive_chunking(query,document):# 分析查询类型query_type=classify_query(query)ifquery_type=="factoid":# 事实型查询:需要精确小块chunk_size=256overlap=50elifquery_type=="summary":# 摘要型查询:需要较大块chunk_size=1024overlap=100elifquery_type=="comparison":# 对比型查询:中等大小chunk_size=512overlap=80returnsplit_with_config(document,chunk_size,overlap)

基于文档特征的自适应

defanalyze_and_split(document):# 分析文档特征length=len(document)has_structure=detect_structure(document)avg_sentence_length=compute_avg_sentence_length(document)# 动态调整iflength<1000:# 短文档不分块return[document]elifhas_structureandlength>10000:# 长文档 + 有结构 → 父子分块returnparent_document_split(document)elifavg_sentence_length>50:# 长句子 → 句子分块returnsentence_split(document)else:# 默认递归分块returnrecursive_split(document)

评估分块效果

关键指标

指标说明评估方法
召回率相关内容被检索到的比例人工标注测试集
精确率检索结果中相关内容的比例人工标注测试集
上下文完整性chunk 是否保留完整语义人工评估
块均信息量每个 chunk 的信息密度自动化指标

A/B 测试框架

defevaluate_chunking_strategy(strategy,test_queries):results=[]forqueryintest_queries:# 检索retrieved_chunks=retrieve(query)# 评估relevance_scores=human_rate(retrieved_chunks,query)results.append({"query":query,"chunks":retrieved_chunks,"relevance":relevance_scores,})# 汇总metrics={"hit_rate":compute_hit_rate(results),"mrr":compute_mrr(results),"avg_relevance":compute_avg_relevance(results),}returnmetrics

常见调优信号

信号问题调整方向
检索不到相关内容chunk 太大减小 chunk_size
上下文不完整chunk 太小增加 chunk_size + overlap
检索到太多噪声chunk 太大或语义散减小 size + 优化结构
相邻块主题跳跃分块边界不对改用递归/语义分块

常见问题与解决方案

问题原因解决方案
检索不到chunk 太大,关键词被稀释减小 chunk_size
检索太多噪声chunk 太大减小 chunk_size,添加重排序
上下文不完整chunk 太小增加 chunk_size,添加重叠
主题跳跃分块不合理使用递归/语义分块
关键信息被切分分块边界不佳增加 overlap,父子分块
代码被切断未使用代码专用分块使用 CodeTextSplitter
表格信息丢失表格处理不当使用表格专用提取器

工程工具推荐

主流分块工具

工具特点适用场景
LangChain TextSplitters丰富、支持多种语言通用场景
LlamaIndex NodeParser强大、配置灵活高级用户
Unstructured智能、端到端复杂文档
SpacyNLP 能力语义分块

组合使用建议

基础方案:LangChain RecursiveCharacterTextSplitter ↓ 优化方案:LlamaIndex NodeParser(更精细控制) ↓ 高级方案:Unstructured(复杂文档) ↓ 终极方案:自定义 + LLM 辅助

参考资料

  • LangChain Text Splitters
    https://python.langchain.com/docs/modules/data_connection/document_transformers/

  • LlamaIndex Node Parsers
    https://docs.llamaindex.ai/en/latest/api_reference/node_parsers.html

  • Semantic Chunking for RAG
    https://www.pinecone.io/blog/semantic-chunking

  • Chunking Strategies for RAG
    https://github.com/run-llama/llama_index/blob/main/docs/docs/module_guides/loading/node_parser.md

  • Advanced RAG Techniques: Chunking
    https://www.anyscale.com/blog/chunking-strategies-for-rag

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

相关文章:

  • 别再为公网IP发愁了!用一台腾讯云轻量服务器+NPS,把家里NAS变成私人云盘
  • 2026年冷水机组维修厂家TOP5排行:磁悬浮压缩机售卖、磁悬浮压缩机维修、离心式压缩机售卖、离心式压缩机维修选择指南 - 优质品牌商家
  • 《身体健康最重要》的内容入口:朴素标题如何连接听众
  • PostgreSQL 中的 NULL 陷阱:从一次排除过滤说起
  • Git 如何检查当前版本是否存在已知安全漏洞 CVE
  • 【NotebookLM物理学研究辅助终极指南】:20年物理计算专家亲授5大高阶用法,90%研究者至今不知
  • BililiveRecorder 直播录制文件修复:3步拯救你的珍贵直播回忆
  • 2026年4月黄金回收技术解析与正规渠道指南:18K金回收/18K金抵押/包包典当/包包回收/包包抵押/奢侈品抵押/选择指南 - 优质品牌商家
  • Taotoken控制台功能详解,从密钥管理到用量分析一站掌握
  • CC2530开发避坑指南:IAR for 8051 10.10.1新建工程到流水灯调试的完整流程
  • 专业实战指南:如何高效应用FUnIE-GAN实现水下图像增强
  • 《UltraEdit 正则表达式实战:从数据清洗到代码重构》
  • Ketcher分子绘图工具完全指南:从零开始掌握化学结构绘制
  • 2026年5月湖北地区知识产权实缴:专业团队如何助力企业优化资本结构? - 2026年企业推荐榜
  • LLM Token用量监控:从成本可视到优化实践
  • STM32H743 FDCAN实战:手把手教你调试CAN节点错误计数器与Bus_Off状态
  • 5大革新点解析:Faze4六轴机械臂从开源设计到工业级应用的实战指南
  • Bebas Neue:为什么这款开源字体让设计师爱不释手?
  • 用Python+Pandas搞定QAR飞行数据清洗:手把手教你从MathorCup赛题数据中提取安全关键项
  • 《企业级 Harness 工程实战:原理与应用》AI Agent领域的“Harness Engineering”(驾驭工程) FDE 前线部署工程师 Forward-Deployed Eng‘r
  • NomNom存档编辑器:解放你的《无人深空》游戏体验终极指南
  • 【STM32+HAL库】---- 模拟SPI实现ST7735s屏幕图形化界面开发
  • 我靠“测试即服务”这个理念,拿下了3个大客户
  • 用STM32F103C8T6驱动Ra-01SC模组:从接线到收发数据的保姆级避坑指南
  • Java-Callgraph2:企业级Java静态调用图分析工具深度解析
  • JavaScript PPT自动化生成终极指南:5分钟从零到专业演示文稿
  • MoocDownloader终极指南:三步轻松下载中国大学MOOC视频课程
  • ML模型监控:构建生产环境模型性能保障体系
  • 保姆级教程:在Qt项目中配置Halcon18.11环境并显示第一张图片
  • 企业费控管理软件系统推荐怎么选?这几个核心问题一定要搞懂 - 资讯速览