搭 RAG 知识库前,先把分块调对:chunk size、overlap 与切分策略
检索不准,先怀疑切块
RAG(检索增强生成)的链路是:文档切块 → 向量化入库 → 按问题检索相关块 → 塞给大模型生成回答。新手调试时总盯着模型和提示词,实际上检索质量的天花板在切块这一步就定了:用户的问题永远只会命中某一个块,块切得不好,后面的模型再强也只能基于错误的上下文作答。
两类典型翻车:块太大(比如整章 2000 字一块),检索时相关问题被无关内容稀释,答案东拉西扯;块太小(比如按 100 字硬切),一句话被拦腰截断,“它比上一代提升了 40%“这种指代上一块的句子检索出来就是天书。
三种切分策略,对应三种文档
🔧 RAG 分块预览器 内置了三种策略,正好对应三类常见文档:
- 固定长度(fixed):按字符数硬切,加上 overlap。适合纯流水文本——客服记录、日志、没有结构的纯文字。简单粗暴,但对结构化文档是灾难:会把表格切一半、把标题和正文分家。
- 递归分隔(recursive):按分隔符优先级切(先段落、再句子、再字符),尽量让块在自然边界断开。这是 LangChain 默认的 RecursiveCharacterTextSplitter 思路,不确定选什么时选它,对大多数中文文档是安全的起点。
- Markdown 感知(markdown):按标题层级切块,H2 下面的内容不会跑到 H2 的块外面去。手册、教程、wiki 这类带标题结构的文档首选,检索命中一个块就等于命中一个完整小节。
chunk size 和 overlap:经验起点
社区实践里比较收敛的口径:chunk size 256-512 token,overlap 取块的 10%-20%。中文 1 个字约等于 1 个 token,英文约 4 个字符 1 个 token,所以 512 token 的块对纯中文大约就是 500 字上下。这个口径不是铁律,但作为起点足够好:先按它设,再根据检索badcase微调。
overlap 的作用是边界保险:相邻块共享一段尾部内容,“跨块讲述"的信息不至于两头丢失。设 0 是新手常见错误——检索系统里最可惜的就是那句恰好骑在块边界上的关键信息。当然 overlap 也不是越大越好,超过块长一半就纯是存储浪费。
调参别在业务代码里盲调:把真实文档粘进🔧 分块预览器 ,切一遍,重点看三样——每块的起止行号是否落在自然段落边界、有没有块被切到句子中间、边界处的重叠内容是否真的衔接。预览器还会按块估算 token 数(中文 1 字≈1 token 的启发式口径,与站内🔧 Token 成本计算器 一致),导出 JSONL 直接可以喂给 embedding 流水线试跑。
切好之后还有两件事
切块只是第一步,入库前建议再过两道:
一是清洗:PDF 复制出来的文本带着换行断裂、页眉页脚重复,切块前先过一遍🔧 文本清洗 ,垃圾进垃圾出是 RAG 的第一定律。二是提示词:检索出来的块怎么喂给模型、要求它怎么引用来源,这部分站内🔧 提示词库 里有现成的 RAG 模板可以抄。
常见问题
中文和英文混排的文档怎么算 token?
启发式口径:CJK 字符按 1 字 1 token,其余按 4 字符 1 token 折算。这个估算和真实 tokenizer(如 tiktoken)有个位数百分比的偏差,调参够用,精确计费请用真正的 tokenizer。
块大小是按字符还是按 token 设?
工程实现里两种都有,LangChain 默认按字符。预览器按字符切、按 token 展示,你能同时看到两个口径。纯中文场景两者几乎等价(1 字≈1 token),混排英文时留意换算。
语义切分(semantic chunking)比这些强吗?
语义切分用 embedding 相似度找边界,对结构混乱的长文确实更好,但计算成本高一个量级,而且边界可解释性差。实践中先试递归分隔,检查预览确认不够用,再上语义切分不迟——多数文档到不了那一步。
本章配套工具箱
边读边用:以下工具均在浏览器本地运行,数据不上传。
- 🔧 RAG分块预览器 :三种策略实时切块,token 估算与 JSONL 导出
- 🔧 Token成本计算器 :入库和调用的成本估算
- 🔧 文本清洗 :切块前去掉 PDF 换行断裂与杂符
- 🔧 提示词库 :RAG 生成环节的现成模板
- 🔧 Prompt对比 :迭代提示词时看差异