当你决定用 LangChain、LlamaIndex 或是原生的向量数据库(如 ChromaDB)给自己搭建一个私有的知识库搜索问答系统(RAG)时,你很快就会碰到第一个卡脖子的大头疼:文本分块(Chunking)。
为什么要做切片? 因为大多数大模型有上下文长度限制,更重要的是,向量模型(Embedding)把太长的文章揉成一个向量的话,会严重丢失细节(也就是所谓的“稀释”)。为了准确,我们需要把一篇 1 万字的技术 PDF,切成一块块 300 到 500 字的小豆腐块。
但怎么切,大有讲究!今天分享三种最主流的切分策略。
第一层级:基于固定字符数量 (Character Splitter)
顾名思义:暴力一刀切。比如设定每块长度为 500 个字母/汉字,且允许前后块有 50 个字重叠 (Overlap) 防止一句话被从中间物理切断。
- 优点:极其简单、速度最快,不需要引入复杂的计算。
- 缺点:不带大脑。它很可能会把一行极其关键的代码:
public static void main(...)从中间咔嚓劈开,导致这段代码的两半分别被存了进去,搜索结果惨不忍睹。
第二层级:基于 Token 的切分 (Token Splitter)
因为大模型都是按 Token 计费和限制长度的,所以很多系统会用诸如 tiktoken 这样的库,先把文本转成 Token 再来切。比如规定每块是 512 个 Token。
- 适用场景:适用于你需要精准控制送给大语言模型的令牌长度,防止超限报错。
- 评价:属于工程上的稳妥选择,但从“找对意图”的角度来说,它还是盲目的。
第三层级:基于语义 / Markdown 层级的智能切片
这是真正能在实战中拉开差距的地方!
如果你切的是一篇文章,为什么不根据 \n\n(段落符号)来切?如果你切的是代码,为啥不借助树结构的解析器,把一个个完整的 function 或者 class 整体剥离出来?
- Markdown 切片器:聪明的系统会识别
# 章节一和## 子章节。它会努力保证属于同一个#标签下的内容待在同一个块里。这保证了局部上下文的完整性。只有块大意完整,Embedding 获取出的向量才是纯粹的。
核心忠告
在 RAG 中,切片策略一旦选错,后面的所有向量搜索都会被污染。 实战中最常用的策略是:“优先以 Markdown 标题或空行切割(保证语义),如果某个自然段实在太长,再用 Token 作为后备切分底线”。
本文是个人学习大模型方向时的实战小记,希望对准备入门 AI 开发的大家有所启发。
感谢关注,我会持续更新,欢迎查看相关源码实现与学习记录:
github.com/start007-sm…