语义分块(Semantic Chunking)
语义分块(Semantic Chunking)
核心思想
递归分块是按格式符号切(段落符、换行符、句号),它不理解内容。
语义分块则是让模型真正读懂文字,在”话题转变”的地方切——语义连续就不切,语义跳跃就切。
一句话:在”内容的意思发生变化”的地方切,而不是在”标点符号”的地方切。
具体怎么做?
主流实现是基于 Embedding 相似度的方法,不需要额外的大模型,只用 Embedding 模型就够了。
步骤一:先按句子粗切
把文本先按句号切成一个个小句子(这里不是最终结果,只是临时单位):
句1: "苹果公司成立于1976年。"
句2: "创始人是乔布斯和沃兹尼亚克。"
句3: "公司最初主要生产个人电脑。"
句4: "iPhone于2007年正式发布。"
句5: "它彻底改变了智能手机行业。"
句6: "今天的天气非常晴朗。" ← 话题突然跳跃
句7: "气温大约在25度左右。"
句8: "适合出门运动。"
步骤二:计算相邻句子之间的语义相似度
把每个句子转成向量,然后计算相邻两句之间的余弦相似度:
句1 ↔ 句2 : 相似度 0.91 (都在讲苹果公司历史)
句2 ↔ 句3 : 相似度 0.87 (都在讲苹果公司历史)
句3 ↔ 句4 : 相似度 0.82 (还是苹果公司话题)
句4 ↔ 句5 : 相似度 0.88 (都在讲 iPhone)
句5 ↔ 句6 : 相似度 0.11 ← 相似度骤降!话题跳跃 ⚠️
句6 ↔ 句7 : 相似度 0.93 (都在讲天气)
句7 ↔ 句8 : 相似度 0.89 (都在讲天气)
步骤三:在相似度骤降的地方切割
相似度变化曲线:
0.91 0.87 0.82 0.88 0.93 0.89
●─────●─────●─────● ↓ ●─────●─────●
句1 句2 句3 句4 句5 句6 句7 句8
↑
0.11 骤降
在这里切!
最终结果:
块1: "苹果公司成立于1976年。创始人是乔布斯和沃兹尼亚克。
公司最初主要生产个人电脑。iPhone于2007年正式发布。
它彻底改变了智能手机行业。"
块2: "今天的天气非常晴朗。气温大约在25度左右。适合出门运动。"
完美地按照话题边界切开了,而且完全没有依赖任何标点符号或格式符号。
和递归分块的本质区别
递归分块: 语义分块:
"苹果公司成立于1976年, "苹果公司成立于1976年,
创始人是乔布斯。 创始人是乔布斯。
──── 遇到\n\n切割 ──── iPhone改变了手机行业。"
iPhone改变了手机行业。" ─── 语义跳跃才切 ───
"今天天气很好,
"今天天气很好, 适合出门。"
适合出门。"
按符号切 按语义切
不管内容 真正理解内容
什么时候用语义分块?
适合用:
- 文档格式很乱(没有规范的段落结构)
- 对检索精度要求很高的场景
- 文档中话题切换没有明显的格式标记
不适合用:
- 文档量极大、对速度要求高
- 快速原型验证阶段(先用递归分块跑通再优化)
- 计算资源有限
一句话总结
递归分块是看格式切,语义分块是看内容切。 语义分块效果更好,但要为每个句子计算向量,成本更高——是精度和速度之间的取舍。