RAG02:切分策略

从按章节、语义、代码块到业务对象切分,理解如何将文档切分为合适的检索单元。

字数 1078 阅读时长 ≈ 4 分钟 2026-7-25 2026-7-27
RAG02:切分策略

文档切分是 RAG 的核心环节之一。合理的切分策略能将长文档拆分为合适的检索单元,既保证语义完整性,又提高检索精度。

切分策略的重要性

切分不当的问题

问题表现影响
切分过大每个片段包含太多内容检索精度低,噪音多
切分过小每个片段内容不完整语义断裂,上下文丢失
切分不均片段大小差异大检索效果不稳定
切分不当破坏语义完整性答案质量差

切分策略的影响

切分方式优点缺点
按章节语义完整片段可能过大
按固定长度简单可控可能破坏语义
按语义语义完整实现复杂
按代码块适合代码不适合普通文本

常见切分策略

按章节切分

按章节切分是最直观的方式:

文档结构:
第1章:引言
  1.1 背景
  1.2 目的
第2章:系统设计
  2.1 架构设计
  2.2 模块划分
第3章:实现细节
  3.1 核心算法
  3.2 代码实现

切分结果:
片段1:第1章完整内容
片段2:第2章完整内容
片段3:第3章完整内容

适用场景

  • 结构化文档(书籍、报告)
  • 章节内容相对独立
  • 需要保持章节完整性

按固定长度切分

按固定长度切分是最简单的方式:

def split_by_fixed_length(text, chunk_size=500, overlap=50):
    chunks = []
    start = 0
    while start < len(text):
        end = start + chunk_size
        chunk = text[start:end]
        chunks.append(chunk)
        start = end - overlap
    return chunks

参数说明

参数说明推荐值
chunk_size片段大小(字符数)500-1000
overlap重叠大小(字符数)50-100

适用场景

  • 非结构化文本
  • 简单场景
  • 需要快速实现

按语义切分

按语义切分是最智能的方式:

from langchain.text_splitter import RecursiveCharacterTextSplitter

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

chunks = text_splitter.split_text(text)

分隔符优先级

优先级分隔符说明
1\n\n段落分隔
2\n换行分隔
3。!?句子分隔
4,、逗号分隔

适用场景

  • 需要保持语义完整
  • 复杂文档
  • 对检索精度要求高

按代码块切分

按代码块切分适合技术文档:

import re

def split_by_code_blocks(text):
    # 匹配代码块
    code_pattern = r'```(\w*)\n(.*?)```'
    code_blocks = re.findall(code_pattern, text, re.DOTALL)
    
    # 匹配内联代码
    inline_pattern = r'`([^`]+)`'
    inline_codes = re.findall(inline_pattern, text)
    
    return {
        'code_blocks': code_blocks,
        'inline_codes': inline_codes,
        'text': re.sub(code_pattern, '[代码块]', text)
    }

适用场景

  • 技术文档
  • API 文档
  • 代码示例

按业务对象切分

按业务对象切分适合业务文档:

业务文档:
产品名称:电商平台
功能模块:用户认证
API:POST /api/auth/login

切分结果:
片段1:产品信息(名称、版本、描述)
片段2:功能模块(用户认证)
片段3:API 定义(登录接口)
片段4:数据模型(用户实体)
片段5:业务流程(登录流程)

适用场景

  • 业务文档
  • API 文档
  • 产品文档

切分策略的优化

重叠设置

重叠设置确保相邻片段之间有一定的上下文重叠:

原始文本:"这是一段测试文本,用于演示切分策略的效果。"

切分(chunk_size=10, overlap=3):
片段1:"这是一段测试文本"
片段2:"测试文本,用于演示"
片段3:"用于演示切分策略"
片段4:"切分策略的效果。"

重叠的作用

  • 避免语义断裂
  • 保持上下文连续性
  • 提高检索召回率

元数据添加

为每个片段添加元数据:

元数据说明示例
source文档来源”产品文档”
title文档标题”用户认证模块”
section章节信息”2.1 架构设计”
type内容类型”代码”、“文本”、“表格”
page页码第5页

元数据的作用

  • 提高检索精度
  • 支持过滤和排序
  • 便于溯源

语义增强

为每个片段添加语义增强信息:

def enhance_chunk(chunk, metadata):
    # 添加标题信息
    enhanced = f"标题:{metadata['title']}\n"
    
    # 添加章节信息
    if metadata.get('section'):
        enhanced += f"章节:{metadata['section']}\n"
    
    # 添加内容类型
    enhanced += f"类型:{metadata['type']}\n"
    
    # 添加内容
    enhanced += f"内容:{chunk}\n"
    
    return enhanced

语义增强的作用

  • 提高检索精度
  • 增加片段的语义信息
  • 帮助模型理解上下文

切分策略的评估

评估指标

指标说明目标值
平均片段长度平均每个片段的字符数500-1000
片段长度标准差片段长度的一致性< 200
语义完整性片段是否保持语义完整> 90%
检索召回率检索时的召回率> 85%
检索精确率检索时的精确率> 80%

评估方法

1. 准备测试文档
2. 使用不同切分策略
3. 进行检索测试
4. 计算评估指标
5. 选择最优策略
6. 持续监控和调整

切分策略的常见问题

问题1:语义断裂

表现:切分后语义不完整

解决方案

  • 使用语义切分
  • 增加重叠大小
  • 优化分隔符

问题2:片段过大

表现:片段包含太多内容

解决方案

  • 减小 chunk_size
  • 使用更细粒度的分隔符
  • 按子章节切分

问题3:片段过小

表现:片段内容不完整

解决方案

  • 增大 chunk_size
  • 使用更粗粒度的分隔符
  • 合并小片段

问题4:切分不均

表现:片段大小差异大

解决方案

  • 使用动态切分策略
  • 设置最小和最大片段大小
  • 合并过小的片段

项目判断清单

  • 需要保持章节完整性 → 使用按章节切分
  • 需要快速实现 → 使用按固定长度切分
  • 需要保持语义完整 → 使用按语义切分
  • 需要处理技术文档 → 使用按代码块切分
  • 需要处理业务文档 → 使用按业务对象切分
  • 语义断裂 → 增加重叠或使用语义切分
  • 片段过大 → 减小 chunk_size
  • 片段过小 → 增大 chunk_size
  • 需要长期维护 → 建立切分策略评估和优化机制