在 RAG 中,Chunk Size(切块大小)和 Chunk Overlap(切块重叠)这两个参数如何设置?对检索效果有什么影响?
在 RAG(检索增强生成)系统中,Chunk Size(切块大小) 和 Chunk Overlap(切块重叠) 是两个至关重要的超参数。它们的设置直接决定了系统检索的准确性(Precision)和召回率(Recall),进而影响最终 LLM 生成答案的质量。
以下是关于这两个参数的详细解析、影响分析以及设置建议。
1. 核心概念定义
- Chunk Size (切块大小): 指将原始文本分割成小段时,每一段包含的字符数或 Token 数。
- Chunk Overlap (切块重叠): 指相邻两个切块之间重复内容的长度。它的目的是防止上下文在切块边缘被切断。
2. Chunk Size 对检索效果的影响
Chunk Size 的大小需要在“语义完整性”和“信息噪声”之间寻找平衡。
A. Chunk Size 过小 (例如 < 128 tokens)
- 优点:
- 高精度: 检索到的内容非常具体,能够精准匹配特定的关键词或短语。
- 低噪声: 送给 LLM 的无关信息很少。
- 缺点:
- 缺乏上下文: 句子可能被切断,导致 LLM 无法理解该片段的真正含义(例如,只有“是的,我同意”,但不知道同意了什么)。
- 语义丢失: 向量化(Embedding)模型可能无法捕捉到完整的语义,导致检索匹配度下降。
B. Chunk Size 过大 (例如 > 2048 tokens)
- 优点:
- 上下文丰富: 包含了完整的段落或章节,LLM 能获得更多背景信息,利于回答需要推理或总结的问题。
- 缺点:
- 噪声干扰: 包含了大量与查询无关的信息,可能会分散 LLM 的注意力("Lost in the Middle" 现象,即模型容易忽略长文本中间的关键信息)。
- 成本增加: 检索到的文本越长,LLM 的 Token 消耗越大,推理成本越高。
- 检索精度下降: Embedding 向量是对整个块的平均表示,块越大,语义越稀释,导致与具体问题的匹配度降低。
3. Chunk Overlap 对检索效果的影响
Chunk Overlap 的核心作用是保持语义的连贯性。
- 如果 Overlap 为 0:
- 如果用户的问题正好对应文本被切分的那条线(例如一个句子被切成两半),那么两个 Chunk 都无法完整表达该句子的含义,导致检索失败。
- 如果 Overlap 适中 (例如 10%-20%):
- 能够确保句子或逻辑段落的边缘不会因为切分而丢失语义。
- 如果 Overlap 过大:
- 导致存储空间浪费(重复内容多)。
- 检索时可能返回多个内容高度相似的 Chunk,浪费 LLM 的上下文窗口。
4. 如何设置这两个参数?(决策框架)
没有通用的“最佳数字”,设置时需要考虑以下 4 个维度:
(1) 数据的性质 (Nature of Data)
- 短文本/事实性数据 (如 FAQ、推特): 适合小 Chunk。因为每条数据独立且简短。
- 长文本/连贯性强 (如 论文、法律合同、小说): 适合大 Chunk。需要保留段落结构和上下文逻辑。
- 代码 (Code): 需要特殊的切分策略(基于 AST 或分隔符),通常需要较大的 Chunk 以保留函数或类的完整性。
(2) Embedding 模型的能力
- 模型限制: 不同的 Embedding 模型有最大 Token 限制(如 BERT 类通常是 512)。Chunk Size 不能超过这个限制。
- 模型特性: 某些模型(如 OpenAI
text-embedding-3)在处理长文本时表现更好,而某些旧模型在短文本上表现更好。
(3) 用户查询的类型 (Query Type)
- 精准问答 (Specific QA): "CEO 是谁?" -> 适合小 Chunk。
- 摘要/综合分析 (Summarization/Reasoning): "这篇文章主要讨论了什么趋势?" -> 适合大 Chunk。
(4) LLM 的上下文窗口 (Context Window)
- 如果你的 LLM 上下文窗口很小(如 4k),你需要更精简的 Chunk。
- 如果是 GPT-4-Turbo (128k),可以容忍更大的 Chunk 和更多的检索结果。
5. 推荐的设置策略 (Best Practices)
如果你不确定从哪里开始,可以参考以下经验值:
策略 A:通用默认值 (适合大多数文档)
- Chunk Size: 512 或 1024 Tokens (约等于 400-800 个中文汉字)。
- Chunk Overlap: Chunk Size 的 10% - 20% (例如 50-100 Tokens)。
- 理由: 这个大小通常能包含一个完整的段落,既有足够的上下文,又不会产生太多噪声。
策略 B:小块 + 父文档索引 (Parent Document Retriever)
这是一个高级且效果通常更好的策略:
- 切分: 将文档切成很小的块(如 128-256 Tokens)进行 Embedding 和检索。
- 映射: 检索到小块后,不直接把小块给 LLM,而是找到该小块所属的父文档(更大的块或全文)。
- 生成: 将父文档的内容送给 LLM。
- 优点: 兼顾了检索的精准度(小块匹配准)和生成的上下文完整性(大块信息全)。
策略 C:动态测试 (LlamaIndex/LangChain)
使用框架提供的评估工具。
- 准备一个测试集(10-20 个问题 + 对应的标准答案)。
- 设置几组参数:(256, 20), (512, 50), (1024, 100)。
- 运行 RAG 流程,使用 "RAGAS" 或 "TruLens" 等工具评估
Context Recall(上下文召回率)和Answer Relevancy(答案相关性)。
6. 总结与速查表
| 场景 | 建议 Chunk Size (Tokens) | 建议 Overlap | 备注 |
|---|---|---|---|
| 精准事实检索 (如员工手册查询) | 256 - 512 | 30 - 50 | 追求精准匹配,减少幻觉 |
| 一般性文档问答 (如产品文档) | 512 - 1024 | 100 - 150 | 平衡点,最常用的设置 |
| 复杂推理/摘要 (如研报分析) | 1024 - 2048 | 200 - 300 | 需要更多上下文逻辑 |
| 代码库问答 | 依据函数/类长度 | 0 (或基于结构) | 最好使用针对代码的 Splitter |
一句话建议:从 1024 Tokens Size / 100 Tokens Overlap 开始测试,如果发现检索内容经常断章取义,增加 Overlap;如果发现检索内容包含太多无关废话,减小 Size。