RAG文本分块

不论是向量化模型还是大语言模型,都存在输入长度的限制。对于超过限制的文本,模型会进行截断,造成语义缺失。分块可以确保每个文本片段都在模型的处理范围内,避免重要信息的丢失。

文本分块的核心原则

高质量分块的核心原则是:一个分块应当表示一个完整且语义相关的上下文信息

这意味着:

  • 分块过小:会导致语义信息被割裂,检索时可能错过真正相关的内容
  • 分块过大:一个块内可能包含多个不相关的上下文信息,增加检索噪声

实际应用中,合理的分块大小通常在几百到一千多个token之间,但具体应根据文档特性和应用场景灵活调整。

主流分块策略详解

1. 递归文本分块

递归文本分块是最常用的分块策略,其核心思想是根据特定的分隔符(段落、句子、单词等)对文档进行递归分割。

工作原理

  1. 指定目标块大小(如200个token,不要超过embedding尺寸)
  2. 定义由粗到细的分隔符列表(段落 > 句子 > 单词 > 字符)
  3. 先使用最粗的分隔符(如段落标记)拆分文本
  4. 检查拆分结果,如果某块大小超过目标值,则使用下一级更细的分隔符继续拆分
  5. 重复此过程,直到所有块都不超过目标大小
from langchain.text_splitter import RecursiveCharacterTextSplitter

# 创建递归文本分块器
text_splitter = RecursiveCharacterTextSplitter(
    # 设置块大小
    chunk_size=500,
    # 设置块间重叠部分
    chunk_overlap=50,
    # 按优先级定义分隔符
    separators=["\n\n", "\n", "。", ",", " ", ""]
)

# 进行分块
chunks = text_splitter.split_text(long_text)

chunk_overlap 重叠设置
分块时通常会设置一定的重叠区域(overlap),可以保持上下文连贯性,避免关键信息在块边界处断裂

在这里插入图片描述

separators 分隔符设置
不同类型的文档可能需要特定的分隔符设置:

  • 中文文档:应增加中文标点符号(如"。“、”,")作为分隔符
  • Markdown文档:可使用标题标记(#、##)、代码块标记(```)等作为分隔符

2. 基于语义的分块策略

递归文本分块基于预定义规则工作,虽然简单高效,但可能无法准确捕捉语义变化。
基于语义的分块策略则直接分析文本内容,根据语义相似度判断分块位置。

基于Embedding的语义分块

这种方法利用向量表示捕捉语义变化,可分为四个步骤:

  1. 将文档拆分为句子级别的基本单位
  2. 设定滑动窗口(如包含3个句子)
  3. 计算相邻窗口文本的embedding相似度
  4. 当相似度低于设定阈值时,在该位置进行分块
from langchain.text_splitter import SentenceTransformersTokenTextSplitter

# 创建基于语义的分块器
semantic_splitter = SentenceTransformersTokenTextSplitter(
    model_name="all-MiniLM-L6-v2",  # 指定embedding模型
    # 选择阈值策略
    threshold_strategy="percentile",  # 百分位策略
    threshold=0.95,  # 95%分位数作为阈值
    window_size=3  # 滑动窗口大小
)

# 分块
semantic_chunks = semantic_splitter.split_text(long_text)

阈值选择策略包括:

  • 百分位策略:对所有相似度值排序,选择特定百分位的值作为阈值
  • 标准差策略:基于相似度的统计分布确定阈值
  • 四分位策略:使用四分位数统计确定阈值
基于模型的端到端语义分块

更先进的方法是使用专门训练的神经网络模型,直接判断每个句子是否应作为分块点。这种方法无需手动设置阈值,而是由模型端到端地完成分块决策。

以阿里达摩院开发的语义分块模型为例,其工作流程为:

  1. 将文本窗口中的N个句子输入模型
  2. 模型为每个句子生成表示向量
  3. 通过二分类层直接判断每个句子是否为分块点
    在这里插入图片描述
from modelscope.pipelines import pipeline

# 加载语义分块模型
semantic_segmentation = pipeline(
    'text-semantic-segmentation',
    model='damo/nlp_bert_semantic-segmentation_chinese-base'
)

# 进行分块
result = semantic_segmentation(long_text)
segments = result['text']

这种方法的优势在于模型已经学习了语义变化的复杂模式,无需手动调整参数。但需注意模型的泛化能力,应在特定领域文档上进行验证。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一切皆有可能!!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值