✂️ RAG 的 Chunking 策略:怎么切才不亏
切太细语义断,切太粗召回噪。从固定窗口到 parent-child,选型看文档类型。
Chunking 在解决什么权衡
⚖️ 三方的 trade-off
向量化是按块做的,检索也是按块匹配的,但生成需要完整上下文。
• 切太细 → 语义断
• 切太粗 → 召回噪
本质是「检索精度 / 语义完整 / token 成本」的平衡。
🎯 一句话定位
Chunking 决定检索的颗粒度。切得好,相关问题能命中同一块;切得差,内容被劈散在十几个块里,单独看每块相关度都不高。
它是 RAG 检索质量的第一道关口。
主流策略(从简单到进阶)
🔢 ① Fixed-size 固定窗口
按 token 数一刀切,256/512/1024 常见,加 10-20% overlap 防边界截断。
优点:实现简单,token 可控
缺点:无视语义边界,容易劈断句子
适用:baseline、日志类无结构文本
💬 ② Sentence-based 句子级
先按标点拆句子,再聚成块。比 fixed-size 多一层语义保护。
适用:规整短文、FAQ。
🔁 ③ Recursive 递归切(最常用)
按分隔符优先级递归:
→
→ 。 → 空格 → 字符。尽量在高层级(段落)控住 size。
优点:尊重文档天然结构,语义断裂最少,90% 项目默认起点
适用:Markdown、博客、说明书
🏗️ ④ Structure-aware 结构感知
按文档自带结构切:MD 按标题层级、代码按 AST 函数/类、合同按条款、PDF 按大纲。
优点:chunk 边界 = 语义边界,召回质量明显高
代价:要按文档类型写 parser
适用:代码库、法务、API 文档
🧠 ⑤ Semantic 语义切
靠 embedding 相似度判边界:滑窗算相邻句相似度,跌到阈值以下就切。
优点:真正按语义而非符号切,长叙事效果好
缺点:要调阈值、多跑一遍 embedding,慢且贵
适用:弱结构长文(论文/报告)
👪 ⑥ Parent-Child(生产首选)
检索用小 chunk,生成用大 chunk:一份文档存两份,子 chunk(128-256t)向量化检索,命中后回捞父 chunk(整段/整节)喂 LLM。
优点:检索颗粒细→准;上下文全→稳
代价:存储翻倍,检索后二次拼接
适用:生产通用最优解
策略对比速查
| 策略 | 优点 | 缺点 | 适用 |
|---|---|---|---|
| Fixed-size | 简单、token 可控 | 劈断句子 | baseline、日志 |
| Sentence-based | 多一层语义保护 | 不够细 | 规整短文、FAQ |
| Recursive | 尊重结构、断裂少 | 简单任务够用 | MD、博客(90%起点) |
| Structure-aware | 边界=语义边界 | 要写 parser | 代码、合同、API文档 |
| Semantic | 真按语义切 | 慢且贵、调阈值 | 弱结构长文 |
| Parent-Child | 检索准+上下文全 | 存储翻倍 | 生产首选 |
怎么选 + 参数经验值
通用文档
recursive 起步(512t, 15% overlap),不够再上 parent-child。
代码/合同/API
structure-aware(AST/条款/标题),边界即语义边界。
长叙事弱结构
semantic chunker(论文/报告),按语义切。
生产想稳
parent-child + recursive 或 structure-aware 做 child。
参数甜点
chunk_size 256/512/1024 三档试,多数 512 是甜点;overlap 取 chunk 的 10-15%。
看 embedding 维度
维度短(MiniLM)→ chunk 别太大;维度长(3072)→ chunk 可放宽。最终以 recall@k 为准调。
Chunking 本质是「检索精度 / 语义完整 / token 成本」的 trade-off。策略从简单到进阶:fixed-size(baseline)→ recursive(90% 项目起点)→ structure-aware(代码合同)→ semantic(弱结构长文)→ parent-child(生产首选,小 chunk 检索大 chunk 生成)。选型先看文档类型,参数以 chunk 512 + overlap 15% 为甜点,最终按 recall@k 调。
我从简单到进阶说。fixed-size 固定窗口最朴素,按 token 数切加 overlap,但容易劈断句子;sentence-based 按句子聚块,多一层语义保护;recursive 按分隔符优先级递归切,尊重文档结构,是 90% 项目的默认起点;structure-aware 按文档自带结构切,代码按 AST、合同按条款、MD 按标题,边界就是语义边界;semantic chunker 靠 embedding 相似度找边界,适合弱结构长文;生产里最实用的是 parent-child,也叫 small-to-big,小 chunk 向量化检索,命中后回捞大 chunk 喂 LLM,检索准加上下文全。
我一般先看文档类型。通用 Markdown 和博客用 recursive 起步,chunk_size 512、overlap 15% 作为甜点;代码、合同、API 文档走 structure-aware,因为它们的边界天然是语义边界;长叙事弱结构的论文报告用 semantic chunker;生产环境想稳定就上 parent-child,用 recursive 或 structure-aware 做 child。参数不能拍脑袋,最终要搭 retrieval recall@k 和生成质量一起调,还要看 embedding 模型的维度。
就是 small-to-big,一份文档存两份。子 chunk 大概是 128 到 256 token,用来向量化做检索,颗粒度细所以召回准;命中子 chunk 后,回捞它所属的父 chunk,也就是整段或整节,喂给 LLM 做生成,上下文完整所以答案稳。LangChain 里叫 ParentDocumentRetriever,LlamaIndex 叫 SentenceWindowNodeParser。代价是存储翻倍、检索后要做二次拼接,但生产环境通常值得。