语义分块
语义分块是一种文档切分技术,它在意义边界处切分文本,而不是按固定的字符数或 token 数切分。它利用嵌入来检测相邻句子何时发生主题转移,然后在那里下刀,这样每个生成的文本块在内部都是连贯的,并能作为一个完整的概念被检索。
语义分块是一种文档切分技术,它在意义边界处切分文本,而不是按固定的字符数或 token 数切分。它利用嵌入来检测相邻句子何时发生主题转移,然后在那里下刀,这样每个生成的文本块在内部都是连贯的,并能作为一个完整的概念被检索。
为什么重要
朴素的分块在每 N 个 token 处或在段落分隔处切分,完全无视意义。这经常会把一段论述拦腰截断,把前提放在一个文本块、把结论放在另一个文本块,于是检索器返回的就是说不通的片段。语义分块通过尊重主题转移来解决这个问题。LlamaIndex 和 LangChain 在 2024 至 2025 年的基准报告显示,在开放域问答上,语义分块相比固定长度切分能将 RAG 的回答质量提升 8% 到 20%,其中在长篇技术文档上的提升最为明显。
工作原理
1. 切分成句子:使用句子分词器获取原子单位。
2. 对每个句子嵌入:用一个小型嵌入模型为每个句子生成一个向量。
3. 计算相邻相似度:对每一对句子,测量其嵌入之间的余弦相似度。
4. 找出切分点:当相似度低于某个阈值(或落在最低百分位区间)时,将其标记为主题转移点。
5. 把切分点之间的句子归为一个文本块:每个文本块在主题上都是连贯的。
6. 可选的大小约束:合并过小的文本块或拆分过大的文本块,使检索保持实用。
语义分块 vs 固定长度分块 vs 递归分块
| 策略 | 如何切分 | 连贯性 | 成本 | 适用场景 |
|---|---|---|---|---|
| 固定长度 | 每 N 个 token | 低 | 免费 | 原型开发、日志 |
| 递归 | 段落 → 句子 → 词 | 中 | 免费 | 通用默认方案 |
| 语义 | 嵌入相似度边界 | 高 | 嵌入成本 | 技术文档、长文 |
| 智能体式 | 由 LLM 逐文档决定 | 最高 | 非常高 | 高风险、低产量场景 |
语义分块介于"廉价而笨拙"和"昂贵而智能"两端之间,是你在递归切分已不够用时的一个不错的默认选择。
可调参数
相似度阈值:阈值越低 → 文本块越多、主题连贯性越紧凑、上下文连续性越差。阈值越高 → 文本块越少、越长。可以从相邻相似度的第 15 到 25 百分位附近开始尝试。
嵌入模型:一个廉价的小型嵌入模型通常就足够了,因为你衡量的是相对转移,而非绝对含义。
最小文本块大小:非常短的文本块(单句)由于缺乏上下文,检索效果很差。要设定一个下限。
最大文本块大小:限制文本块的大小,使其不超过下游的上下文窗口。
重叠:在相邻文本块之间留一点句子重叠(1 到 2 句),能在边界含糊的边缘情况下起到补救作用。
何时帮助不大
短文档:如果整篇文档就能放进一个文本块,那么切分本身就是多余的开销。
高度重复的文本:日志、产品清单和表格的自然主题漂移很低,语义分块会退化为固定长度切分。
结构化内容:表格、代码和 JSON 应该按结构切分,而非按意义切分。
当检索并非瓶颈时:如果幻觉源于提示词设计或重排序,那么修正分块也无济于事。
Sources: