02:文本分块策略详解

发布时间:2026/5/16 0:15:42

02:文本分块策略详解 学习笔记详述 RAG 系统中文本分块的核心原理、主流策略、优化技巧以及工程实践目录为什么分块至关重要分块的基本概念分块的核心参数分块大小的影响分块策略详解固定长度分块递归字符分块语义分块结构分块标题层级分块句子分块LLM 分块高级分块技术重叠分块父文档分块小结分块不同文档类型的分块策略Markdown 文档PDF 文档代码文件HTML 文档分块优化实践如何选择合适的分块策略分块参数的动态调整评估分块效果常见问题与解决方案工程工具推荐参考资料为什么分块至关重要文本分块Chunking是 RAG 系统的第一道门槛直接影响后续检索和生成的效果。分块决定检索质量分块问题检索后果Chunk 太小上下文不完整关键信息被切散Chunk 太大引入噪声稀释关键信息分块方式不当语义单元被破坏检索不到相关内容分块影响生成质量上下文完整合理的分块能保留完整的语义单元LLM 更容易理解信息密度高信息密度的 chunk 能提高生成质量引用追溯清晰的 chunk 边界便于生成时引用原始文档分块的基本概念分块的核心参数参数说明常用值chunk_size每个 chunk 的最大长度256~2048 tokenschunk_overlap相邻 chunk 之间的重叠 token 数10%~20% chunk_sizeseparator分隔符换行符、句子边界、段落标记length_function长度计算方式token 数量、字符数分块大小的影响分块大小选择指南场景推荐 chunk 大小理由代码检索256~512 tokens代码逻辑紧凑需要精确匹配短问答256~512 tokens问题简单不需要过多上下文文档问答512~1024 tokens平衡上下文与精确度长文档摘要1024~2048 tokens需要完整上下文多步骤推理512~1024 tokens保留推理链条分块策略详解1. 固定长度分块原理按固定的字符数或 token 数切分文本# 伪代码示例text这是一段很长的文本...chunk_size500chunks[]foriinrange(0,len(text),chunk_size):chunks.append(text[i:ichunk_size])优点实现简单逻辑清晰处理速度快输出 chunk 大小一致便于管理缺点可能切断句子、段落等语义单元不考虑文本结构可能丢失关键上下文适用场景文本格式单一、结构简单对处理速度要求高初步原型验证改进方向尽量在句子边界切分保留一定的重叠2. 递归字符分块原理按层级递归切分尝试多种分隔符LangChain 实现fromlangchain.text_splitterimportRecursiveCharacterTextSplitter text_splitterRecursiveCharacterTextSplitter(separators[\n\n,\n,。,,, ,],chunk_size500,chunk_overlap50,length_functionlen,)分隔符优先级优先级分隔符说明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):promptf 判断以下两段文本是否应该分开成不同的 chunk 文本 A:{text_a}文本 B:{text_b}如果两段文本讨论的是不同主题或话题返回 YES。 如果两段文本主题一致只是内容展开返回 NO。 responsellm.invoke(prompt)returnYESinresponse.text优点分块边界更符合语义保留完整的主题内容检索质量更高缺点计算成本较高实现复杂度大需要调优阈值适用场景对检索质量要求高主题分明的长文档计算资源充足4. 结构分块原理根据文档的显式结构标题、层级、章节进行分块LangChain 实现fromlangchain.text_splitterimportMarkdownTextSplitter splitterMarkdownTextSplitter(chunk_size500,chunk_overlap50,)优点保留文档结构信息分块边界符合阅读习惯便于追溯原文位置缺点依赖文档格式无结构文档不适用需要提取文档结构适用场景Markdown、reStructuredText 等结构化文档技术文档、API 文档有明确章节结构的文档5. 标题层级分块原理按照文档的标题层级如 H1、H2、H3进行分块优点保留层级上下文便于定位和引用用户体验好缺点只适用于 HTML 等有标题标记的文档层级深度不好控制适用场景网站文档帮助中心带目录的文档6. 句子分块原理以完整句子为基本单元进行分块fromlangchain.text_splitterimportSentenceTextSplitter splitterSentenceTextSplitter(chunk_size5,# 5 个句子chunk_overlap2,# 2 个句子重叠)优点保持句子完整性语义自然连贯便于阅读和理解缺点句子长度差异大某些语言分句困难chunk 大小不均匀适用场景小说、散文等叙事性文本对句子完整性要求高的场景7. LLM 驱动分块原理使用 LLM 智能判断分块边界# 伪代码LLM 驱动分块defllm_based_splitting(document):promptf 分析以下文档识别主题边界并给出分块建议{document[:2000]}# 只发送开头部分 输出格式 - 用 Section N 标记每个新主题的开始 - 确保每个 section 主题内聚、主题间区分明显 resultllm.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 生成保留完整上下文优点细粒度检索 完整上下文平衡精确性和完整性支持不同粒度的查询实现要点建立父子映射关系存储时保留层级信息检索时同时返回父子 chunk3. 小结分块Summary Chunking原理为每个 chunk 自动生成摘要检索时使用摘要匹配检索优化# 检索时同时匹配原始文本和摘要query_vectorembed(query)# 方式1分别检索后融合results_textvector_db.search(query_vector,indextext)results_summaryvector_db.search(query_vector,indexsummary)final_resultsfusion_merge(results_text,results_summary)# 方式2扩展查询expanded_queryf{query}{summary}优点摘要更精确匹配查询提高检索召回率支持多角度检索缺点生成摘要有成本存储空间增加摘要质量依赖 LLM不同文档类型的分块策略Markdown 文档特点有明确的标题层级代码块需要特殊处理列表、表格结构化推荐策略fromlangchain.text_splitterimportMarkdownTextSplitter# 方式1Markdown 专用分块器markdown_splitterMarkdownTextSplitter(chunk_size500,chunk_overlap50,)# 方式2组合策略fromlangchain.text_splitterimport(MarkdownHeaderTextSplitter,RecursiveCharacterTextSplitter,)# 先按标题分割header_splitterMarkdownHeaderTextSplitter(headers_to_split_on[#,##,###,])md_chunksheader_splitter.split_text(markdown_text)# 再对每个部分递归分块recursive_splitterRecursiveCharacterTextSplitter(chunk_size500,chunk_overlap50,)final_chunksrecursive_splitter.split_documents(md_chunks)注意事项代码块应作为独立 chunk 或排除表格内容需要特殊解析保持标题与内容的关联PDF 文档特点版面结构复杂可能包含图片、表格提取时可能丢失格式推荐策略# 使用 PDF 专用加载器fromlangchain_community.document_loadersimportPyPDFLoader loaderPyPDFLoader(document.pdf)pagesloader.load()# 按页面或段落分块fromlangchain.text_splitterimportRecursiveCharacterTextSplitter splitterRecursiveCharacterTextSplitter(chunk_size500,chunk_overlap50,separators[\n\n,\n,。, ],)chunkssplitter.split_documents(pages)PDF 提取工具对比工具优点缺点PyPDFLoader简单易用格式保留有限PDFPlumber表格提取好速度较慢PyMuPDF性能好依赖特殊处理Unstructured智能分块资源消耗大代码文件特点有明确的语法结构函数、类有清晰边界注释与逻辑需要分离推荐策略fromlangchain.text_splitterimportLanguage# 按编程语言选择分块器python_splitterRecursiveCharacterTextSplitter.from_language(languageLanguage.PYTHON,chunk_size500,chunk_overlap50,)# 或使用代码专用分块器fromlangchain.text_splitterimportCodeTextSplitter code_splitterCodeTextSplitter(languagepython,chunk_size500,chunk_overlap50,)代码分块策略优先级 1. 类/函数定义最高 2. 代码块 3. 段落 4. 单行兜底注意事项保持函数/类的完整保留必要的上下文处理跨文件引用HTML 文档特点DOM 结构明确内容与样式混合需要提取正文fromlangchain.text_splitterimportHTMLHeaderTextSplitter# 按标题层级分割html_splitterHTMLHeaderTextSplitter(headers_to_split_on[(h1,Header 1),(h2,Header 2),(h3,Header 3),(h4,Header 4),])html_chunkshtml_splitter.split_text(html_string)分块优化实践如何选择合适的分块策略策略选择矩阵文档类型推荐策略备选策略关键参数技术文档递归分块 结构语义分块chunk_size500-800论文报告递归分块句子分块chunk_size800-1000聊天记录句子分块固定长度chunk_size300-500代码文件代码专用分块递归分块按函数/类边界网页内容HTML 分块语义分块保留标题层级法律文档递归分块父子文档chunk_size1000大重叠分块参数的动态调整基于查询类型的自适应分块defadaptive_chunking(query,document):# 分析查询类型query_typeclassify_query(query)ifquery_typefactoid:# 事实型查询需要精确小块chunk_size256overlap50elifquery_typesummary:# 摘要型查询需要较大块chunk_size1024overlap100elifquery_typecomparison:# 对比型查询中等大小chunk_size512overlap80returnsplit_with_config(document,chunk_size,overlap)基于文档特征的自适应defanalyze_and_split(document):# 分析文档特征lengthlen(document)has_structuredetect_structure(document)avg_sentence_lengthcompute_avg_sentence_length(document)# 动态调整iflength1000:# 短文档不分块return[document]elifhas_structureandlength10000:# 长文档 有结构 → 父子分块returnparent_document_split(document)elifavg_sentence_length50:# 长句子 → 句子分块returnsentence_split(document)else:# 默认递归分块returnrecursive_split(document)评估分块效果关键指标指标说明评估方法召回率相关内容被检索到的比例人工标注测试集精确率检索结果中相关内容的比例人工标注测试集上下文完整性chunk 是否保留完整语义人工评估块均信息量每个 chunk 的信息密度自动化指标A/B 测试框架defevaluate_chunking_strategy(strategy,test_queries):results[]forqueryintest_queries:# 检索retrieved_chunksretrieve(query)# 评估relevance_scoreshuman_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 Splittershttps://python.langchain.com/docs/modules/data_connection/document_transformers/LlamaIndex Node Parsershttps://docs.llamaindex.ai/en/latest/api_reference/node_parsers.htmlSemantic Chunking for RAGhttps://www.pinecone.io/blog/semantic-chunkingChunking Strategies for RAGhttps://github.com/run-llama/llama_index/blob/main/docs/docs/module_guides/loading/node_parser.mdAdvanced RAG Techniques: Chunkinghttps://www.anyscale.com/blog/chunking-strategies-for-rag

相关新闻