分块策略(深挖)
这篇是进阶内容,涉及搜索系统的技术细节。如果你刚接触 AI,先读 第13章 · RAG 进化树 了解基本概念。
检索增强生成(RAG)需要把长文档切成小块。切法不对,检索全废。这篇深入四种分块策略的优劣和选型。
为什么分块重要
不分块会怎样?把一整本 300 页的书一次塞给 Embedding 模型——整本书变成一个向量。你搜”第三章的内容”,系统不知道该匹配书的哪一页。整本书的向量太”稀”了——信息被平均化了。
分块的目的是:把长文档切成一段段独立的”知识点”。 每段有自己的向量,检索时可以精确命中。
切得太粗:一段包含多个不同主题,检索不精确。切得太细:一段只包含半句话,丢失上下文。
策略一:固定长度分块
最简单的方式——按字符数或 token 数切。
text = "很长的文档..."
chunk_size = 500 # 每段 500 个字符
overlap = 50 # 段与段之间重叠 50 个字符
overlap 很关键。如果完全无重叠,一句话可能被切在两段的边界上——“张三的老板”在一段的末尾,“是李四”在下一段的开头。检索时两段都搜不到完整的”张三的老板是李四”。有 overlap 可以缓解这个问题。
优点:简单、快。缺点:切的位置可能正好在句子中间,破坏语义完整性。
建议 overlap:chunk_size 的 10%-20%。500 字符的 chunk,overlap 50-100 字符。
策略二:语义分块
不按固定长度切,按语义边界切——在段落结束、话题转换的地方下刀。
工具:LangChain 的 RecursiveCharacterTextSplitter + 分隔符优先级:
["\n\n", "\n", "。", "!", "?", " ", ""]
先尝试在段落分隔符(\n\n)处切。如果切成的一段还是太长,再用句号(。)切。再长就用空格切。最后的兜底方案是强制按字符数切。
优点:保持语义完整性。缺点:段落长度不均匀——有的段落 50 字,有的 2000 字。对向量存储不友好(向量库喜欢等长的向量)。
策略三:Late Chunking
前面两种都是在 Embedding 之前分块——先切,再向量化。Late Chunking 反过来:先向量化整篇文档,再切。
Jina AI 2024 年提出 1。原理:
- 整篇文档输入长上下文 Embedding 模型(如 jina-embeddings-v3,支持 8192 tokens)
- 模型输出每个 token 的向量,而不是整篇文档的一个向量
- 然后按语义边界切——第一段对应 token 1-100 的向量,第二段对应 token 101-200 的向量
- 每段用其对应 token 的向量做池化(pooling),得到段向量
优点:避免了分块→Embedding 的信息丢失。模型在编码时看到了完整的上下文。段向量更准确。
代价:需要长上下文 Embedding 模型。传统模型(如 text-embedding-ada-002)最大 8191 tokens,长文档放不下。
策略四:Agentic Chunking
2025-2026 年新趋势——让 AI 自己决定怎么切。
Agent:
Thought: 这篇文档包含三个独立主题:法律条款、赔偿标准、生效日期
Action: 在第 15 段和第 28 段处下刀
Output: "已切成 3 个 chunk"
优点:最智能——AI 理解文档结构,知道哪里是话题边界。缺点:贵——每次切文档都要调用 LLM。只适合重要文档,不适合批量处理。
最优实践:分块大小怎么定
没有标准答案。取决于你的场景:
| 场景 | chunk_size | overlap | 策略 |
|---|---|---|---|
| 一般 FAQ | 256-512 tokens | 50-100 | 语义分块 |
| 长文档问答 | 512-1024 tokens | 100-200 | Late Chunking |
| 代码搜索 | 整个函数(不计长度) | 无 | 语义分块(按函数边界) |
| 法律/合同 | 500-800 tokens | 50-100 | Agentic Chunking |
| 多语言混合 | 512 tokens | 100 | 固定长度(不同语言语义边界不一致) |
2026 年默认推荐:语义分块,512 tokens 一段,overlap 100 tokens。不够好再换成 Late Chunking。
分块之后的坑
相同内容出现在多个 chunk(因为 overlap)。检索时同一个文档的不同 chunk 可能都被召回,AI 会看到重复信息。解决:检索后去重——同一个文档的多个 chunk,只保留最相关的那个。
chunk 之间缺少全局上下文。每个 chunk 不知道自己在整篇文档中的位置。解决:给每个 chunk 加上”元数据”——[文档标题] [第 N 段/总共 M 段] [前一段摘要]。
相关笔记
- 第13章 · RAG 进化树 — 分块是检索的前置步骤
- 稠密检索(深挖) — 分块决定了 Embedding 的粒度
- 混合检索(深挖) — 分块策略影响 BM25 和 Embedding 的表现
来源
- Jina AI, “Late Chunking”, 2024, https://jina.ai/news/late-chunking-in-long-context-embedding-models/
- LangChain Text Splitters Documentation
注释
-
Jina AI, “Late Chunking”, 2024, https://jina.ai/news/late-chunking-in-long-context-embedding-models/ ↩
关联5
知识图谱局部图谱 · 点节点跳转