Chunk设计
2470 字约 8 分钟
domain/aiai/rag
2026-07-24
Chunk 设计是 RAG 系统的核心超参数调优。同样的嵌入模型和向量数据库,仅换 chunk 配置,检索召回率就能相差 9% 以上[1]。不存在通用最优 chunk 大小,需要通过实验方法论找到适合具体场景的配置。
一句话解释
为 RAG 检索与生成设计最优的 chunk 大小、重叠策略和层级结构,在检索精度(Recall)与上下文完整性(Context)之间找到平衡点。
核心问题
Chunk 设计面临三重矛盾:
- 检索精度 vs 上下文完整性:小块精确定位但丢失上下文,大块上下文完整但语义被"平均化"
- 通用性 vs 场景特化:代码的语义边界是函数,学术论文的边界是章节,FAQ 的边界是问题——一刀切是最差的策略
- 固定配置 vs 动态适应:同一文档内,技术说明密集区域和叙述性段落需要不同的 chunk 粒度
基础概念
Chunk Size:每个 chunk 的 token 或字符数量。是 Chunk 设计中最核心的单一参数。
Chunk Overlap:相邻 chunk 之间的重叠部分,避免边界信息丢失。推荐区间 10%-20%。
多粒度索引:同时维护多个不同 chunk 大小的索引,按查询类型动态选择。
Parent-Child Chunk:父子分块架构——子块用于精确向量检索,父块用于提供完整上下文。
语义内聚:每个 chunk 应围绕单一主题,避免多主题混合导致向量被"平均化"。
Chunk 大小与 Context Window 的关系
核心约束公式
Prompt Tokens + Retrieved Chunks Tokens + Generation Budget ≤ Context Window最优比例
- Chunk Size 不应超过 Context Window 的 20%-30%。128k 窗口下建议 512-2048 token,32k 窗口下建议 256-512 token
- 检索结果总量(top-k × chunk_size)不应超过上下文窗口的 50%-60%,必须保留足够的生成预算
- 具体公式:
k × chunk_size ≤ 0.6 × C - P - G(C=Context Window, P=Prompt长度, G=生成预算)
大 Chunk 的隐性成本
当 chunk 过大时,检索内容直接挤压 LLM 的输出空间,导致回答被截断或推理深度下降。使用 Reranker 可缓解此问题:k=20 进 rerank,最终取 top-5 给 LLM,在不增加上下文压力的前提下扩大检索覆盖面。
不同场景的 Chunk 策略推荐
| 场景 | 推荐 Chunk Size | 推荐 Overlap | 推荐算法 | 核心逻辑 |
|---|---|---|---|---|
| QA(客服/FAQ) | 128-256 token | 10% | 递归字符 / 结构感知 | 答案通常是原子性事实,小块向量更聚焦 |
| Summarization(摘要) | 512-1024 token | 15% | 语义切分 / 层级切分 | 需要保留完整论证链 |
| Code Generation | 按函数/类切分 | 0-5% | AST-based(结构感知) | 代码语义边界是函数/类,非字符数 |
| Legal Document Review | 256-512 token | 20% | 语义切分 | 条款引用需精确边界,overlap 大降低"半条法条"风险 |
| Academic Paper Analysis | 512-1024 token | 15% | 语义切分 / 递归 | 摘要独立成块,方法按子章节切分 |
| 通用知识库 | 512 token | 15% | 递归字符切分 | 覆盖 80% 通用场景 |
场景特化逻辑:
- QA 场景:答案通常是原子性事实,小块(128-256)的向量更聚焦,检索精度更高
- 代码场景:固定长度切分会切断函数体,必须使用 AST 解析器保留函数签名 + docstring
- 法律/合同:条款经常跨段落引用,overlap 建议上浮至 20%,确保关键条件不被切断
Small Chunk vs Large Chunk 权衡
| 维度 | Small Chunk (<256 tokens) | Large Chunk (>1024 tokens) |
|---|---|---|
| Precision(精确率) | 高 | 低 |
| Recall(召回率) | 低 | 高 |
| 语义聚焦度 | 单一主题,向量精准 | 多主题混合,向量被"平均化" |
| 上下文完整性 | 不足,LLM 难以独立理解 | 完整,噪声也同步增加 |
| 索引膨胀度 | 高(块数多) | 低(块数少) |
实验数据:在问答类任务中,512 token 的 Chunk 比 1024 token 的 Chunk 在 MRR 指标上平均高出 12-18%[2]。原因是:大 Chunk 引入的语义噪声会压低相关文档的向量相似度排名。
Embedding 模型的黄金编码区:大多数模型对 200-600 token 区间的文本编码保真度最高[3],超出此区间嵌入质量衰减。
"独立阅读测试":如果一个 chunk 单独阅读时不完整、不可理解,对 LLM 也无意义——这是判断 chunk 是否过小的最直观标准。
Sliding Window 策略简述
滑动窗口通过设定步长和重叠实现,完整数学推导见 文档切分策略 的"Overlap 窗口的数学直觉"。
核心公式:step = chunk_size - overlap
最优区间:10%-20% 是工程黄金区间,超过 20% 后索引体积和检索开销显著上升,超过 30% 几乎确定对性能起负作用。详细成本分析见 文档切分策略。
Parent-Child Chunk 架构
父子分块是缓解"检索精度 vs 上下文完整性"矛盾的经典架构。详见 Parent-child Chunk 的完整分析。
核心思想:
- 子块(Small Chunks):128-256 tokens,用于精确向量检索匹配
- 父块(Parent Chunks):512-1024 tokens,检索后返回包含子块的更大上下文,供 LLM 生成使用
实验方法论
核心原则:控制变量 + 指标驱动
阶段一:基线建立 递归字符切分 + Chunk Size 512 + Overlap 15%。这是覆盖约 80% 通用场景的可靠起点。
阶段二:多参数网格搜索 控制其他变量(Embedding 模型、向量库、重排序器)不变,仅调整切分参数:
| 搜索维度 | 推荐测试值 |
|---|---|
| Chunk Size | 128, 256, 512, 1024 |
| Overlap | 0%, 10%, 15%, 20%, 30% |
| 切分策略 | Fixed / Recursive / Semantic / 结构感知 |
阶段三:指标评估 使用 20-50 条标注问答对,计算:
- Hit Rate@k:正确答案是否落在 top-k 检索结果中
- MRR(Mean Reciprocal Rank):正确答案的平均倒数排名
- Context Precision/Recall:检索内容与答案的相关性
阶段四:显著性检验 若两个配置指标差异在 5% 以内,优先选择索引更小、成本更低的方案。
反直觉结论
语义切分并非总是最优。某技术文档项目中,语义切分替换递归切分后召回率反而下降 8%,原因是代码块和表格破坏了句子相似度计算。
评估指标
检索层
| 指标 | 定义 | 适用场景 |
|---|---|---|
| Recall@k | 正确答案是否被包含在 top-k 检索结果中 | 基础召回能力验证 |
| MRR | 正确答案排名的倒数均值 | 评估检索排序质量 |
| nDCG | 考虑相关性分级和排名的归一化折损累积增益 | 多层级相关性排序 |
| Context Precision | 检索出的内容有多少是真正相关的 | 衡量信噪比 |
| Context Recall | 正确答案有多少被检索内容覆盖 | 衡量信息覆盖度 |
生成层
| 指标 | 定义 |
|---|---|
| Faithfulness(忠实度) | 评估答案是否忠实于检索到的上下文,杜绝"幻觉" |
| Answer Correctness | 对比标准答案,量化回答准确度 |
实践 Checklist
- 文档结构诊断:是否有 Markdown/HTML 结构?是否含大量代码/表格?
- 基线配置:递归字符切分,chunk_size=512,overlap=15%
- 三档对比实验:在 256 / 512 / 1024 上跑相同评估集
- 指标筛选:在 Recall@5 相近时,选 MRR 更高的配置
- 上下文预算检查:确保
k × chunk_size ≤ 0.6 × ContextWindow - Prompt - Generation - Overlap 上限锁死:不超过 20%,超过后必须证明指标增益大于成本增幅
- Metadata 同步:每个 chunk 必须携带 breadcrumbs、source_document、chunk_index
- 版本控制:语料快照、分块参数、嵌入模型、评估套件全部版本化
决策树
文档有清晰 Markdown/HTML 结构?
├─ 是 → 结构感知切分(Markdown Header Splitter)
└─ 否 → 是否代码库?
├─ 是 → AST-based 切分
└─ 否 → 语义跳转明显(学术/法律)且成本可接受?
├─ 是 → 语义切分
└─ 否 → 递归字符切分(默认)
Chunk Size 选择:
短问答/FAQ → 128-256
通用知识库 → 512
需要大量上下文的推理/摘要 → 512-1024(或层级索引)常见误区
- 固定大小一刀切:忽视文档类型、结构和语义边界
- 不考虑 Context Window 预算:chunk 过大直接挤占生成空间
- 以为语义切分永远更好:实际对比中语义切分不一定优于递归切分
- 不跑实验就定参数:不同场景的最优配置差异可能超过 40%
- 重叠过大:超过 20% 后索引膨胀成本急剧上升,边际收益递减
- 不评估检索质量:只看最终回答,不检查检索结果——检索质量差而生成好,往往是模型"脑补"了答案
进阶方向
- Parent-child Chunk:父子分块架构,同时兼顾检索精度和上下文完整性
- Multi-query Retrieval:多角度查询并行检索,从不同粒度匹配
- Late Chunking:先嵌入后分块,保留全局上下文
- Proposition-Based Chunking:LLM 将文本分解为原子命题
- 多尺度索引:同时维护多个 chunk 大小,按查询类型自适应选择
关联笔记
- 文档切分策略
- Metadata设计
- 文档解析
- RAG基础
- RAG评估与优化
- Parent-child Chunk
- 向量与Embedding