RAG 分块策略:按字数切是最差的一种
数据截至 2026-07,规范与各项目能力以官方文档当前版本为准。
如果你的 RAG 检索回来的片段读着像半句话,问题多半不在嵌入模型,而在最不起眼的那一步:分块。按固定字数切是所有切法里最省事的一种,也是效果下限最低的一种——它唯一考虑的是长度,完全不看这段文字本身是什么结构。
常见的误解是:分块只是个预处理小步骤,随便切切,后面靠好一点的嵌入模型和重排就能捞回来。实际不是这样。分块决定了检索系统能看到的最小语义单位,一旦这个单位本身就不成话,后面所有环节都在替它擦屁股。嵌入模型只能忠实地把你喂给它的那段字变成向量,它没办法替你补回被切掉的半句主语,也没办法知道这张表格的表头在上一个块里。
一、按字数切具体切坏了什么
固定字数切分(比如每 500 字一刀,重叠 50 字)之所以流行,是因为它零配置、对任何格式都能跑。它的失效方式也很固定,主要是三类:
第一类,切断句子和逻辑单元。 一刀正好落在句中,前一块结尾是”因此本条款适用于”,后一块开头是”上述情形,但不包括”。这两块单独拿去做嵌入,语义都是残的。检索时哪一块都命中不了完整意图,命中了喂给模型也容易被误读。
第二类,切碎表格和列表。 表格是最典型的受害者。表头在第一块,数据行散在后面两块,每一行数据脱离表头之后就是一串没有含义的数字。用户问”某项指标是多少”,检索器可能把含有那个数字的块捞回来,但模型看不到列名,答出来的东西经常张冠李戴。
第三类,混合无关内容。 一个块里塞进了上一节的结尾和下一节的开头,两段讲的完全是两回事。这种块的向量是两个主题的平均值,落在语义空间里一个尴尬的位置,对任何查询都不太像,也就很难被检索到——它成了知识库里的死块。
这三类问题有个共同特征:它们不会报错,只会让答案变差。你从日志里看不出来,只有把检索回来的原始片段打印出来一段段读,才会发现问题一直在这儿。所以排查 RAG 效果的第一件事,永远是把召回的原文打出来看,而不是先去换模型。
二、先分清”切分单位”和”喂给模型的单位”
很多人卡在块大小上,是因为把两件事混成了一件:用来做向量检索的单位,和最终送进大模型上下文的单位,不必是同一个东西。
小块的向量更”聚焦”,一个块只讲一件事,检索精度高;但小块的信息量不够,直接喂给模型,模型缺上下文。大块反过来,上下文够,但一个块里混了好几个主题,向量被稀释,检索精度掉下来。
这个矛盾不需要靠折中的块大小来解决,可以直接绕开:用小块做索引和检索,命中之后把它所属的大块(或者前后相邻的块)取出来喂给模型。 这套做法在不同项目里叫法不一样,有的叫父子块,有的叫小到大检索,有的用句子窗口来实现,本质都是把”检索单位”和”生成单位”解耦。
想清楚这一层之后,块大小的调参空间会小很多——你不用再去找那个既能精确检索又能提供完整上下文的神奇数字,因为那个数字通常不存在。
三、比按字数切更值得先试的四种切法
按优先级排,下面四种做法在多数语料上都比固定字数切更靠谱。它们不是互斥的,实际项目里经常叠着用。
第一种,按文档结构切。 Markdown 按标题层级切,HTML 按标签切,代码按函数和类切。这类切法的好处是切点天然落在语义边界上,而且能顺手把标题路径记进块的元数据里——比如”第三章 / 3.2 计费规则 / 阶梯定价”,检索时把这串路径拼进块的文本里一起做嵌入,效果通常比裸文本明显好,因为它给了这段文字一个位置感。
第二种,递归按分隔符切。 这是固定字数切的改良版,也是最容易替换上去的一种。它按优先级列表依次尝试分隔符:先按段落(连续换行)切,切完仍然超长的块再按单换行切,还超长的再按句号切,最后才退化到按字符硬切。绝大多数情况下前两级就够了,只有极端长段落才会走到硬切。改动成本很低,效果提升却很实在,值得作为默认起点。
第三种,语义切分。 逐句计算相邻句子的向量相似度,在相似度明显下跌的地方下刀,认为那里发生了话题切换。它的好处是不依赖格式,对没有明显结构的长文(会议纪要、访谈记录、口语化的文档)尤其有用。代价是要为每个句子算一次嵌入,预处理成本高一截,而且阈值需要针对语料调。语料格式规整的话,先别急着上这个,结构切分往往已经够了。
第四种,按业务语义单元切。 这是效果最好也最费人力的一种:不按通用规则,而是按你的文档实际是什么来切。法规按条切,产品手册按功能点切,工单按单条工单切,问答库一问一答就是一块。它需要你写针对性的解析规则,做不了通用,但对固定格式的核心语料回报很高。企业知识库里往往只有一小部分文档是高频被问到的,把这部分手工切好,性价比比全量上语义切分高得多。
选哪种,取决于你的语料是什么样子。结构清晰的(Markdown、规范的 Word、结构化 PDF)优先第一种;混杂来源、格式不统一的用第二种打底;长段落口语文本考虑第三种;核心高频语料值得花力气做第四种。
四、重叠该怎么设,以及它不解决什么
块之间留一段重叠(比如后一块把前一块结尾的一两句话再抄一遍),是为了缓解切点附近的语义断裂。这确实有用,但要清楚它的边界。
重叠能救的是切点恰好落在关键句附近这种情况——重叠让关键句在两个块里各出现一次,总有一个块能被完整命中。它救不了的是结构性问题:表头和数据行隔了两三个块,靠几十字的重叠根本接不上;一个块里混了两个主题,重叠只会让第三个块也被污染。
实践上有几条粗略的经验。重叠比例通常在块长度的一到两成之间,太少起不到作用,太多则会让相邻块的向量高度相似,检索时一次返回好几个内容重复的块,白白挤占上下文预算。如果已经用了结构切分,切点本身就在语义边界上,重叠可以设得更小甚至不设。另外别忘了重叠是有成本的:重叠比例越高,总块数越多,向量库体积和嵌入调用次数都跟着涨。
五、分块之前,先确认解析是对的
有个顺序问题必须讲在前面:分块策略再讲究,也救不回一份没被读明白的文档。
扫描版 PDF、双栏排版、跨页的表格、带页眉页脚的财报,这些东西用普通文本提取器读出来,得到的可能是一堆顺序错乱的文字碎片。这时候不管你用什么切法,切的都是错的原料。判断方法很直接:把解析后的纯文本落盘,自己读一遍前几页,看它是不是人话、表格还成不成形。
如果确实卡在这一步,处理方向是换解析层而不是调分块参数。按公开的项目定位,LlamaIndex 主打数据优先,专注对私有内容做索引与查询,配套的解析能力是它的强项之一;RAGFlow 是开源的 RAG 引擎,强在深度文档理解,分块尊重文档结构,内置版面感知解析,适合扫描版 PDF、财报、版式复杂的法律文书这类传统文本解析器搞不定的语料——它把”版面理解”和”分块”当成一件事来做,而不是先粗暴提取文本再切。具体能力以各项目官方文档当前版本为准。
这一段的详细排查顺序,可以看RAG 效果差?先确认瓶颈是不是在解析这一步。
六、块大小别靠直觉定,用评估跑出来
关于块大小,网上流传着各种”推荐值”。这些数字对不对,取决于你的语料和你的问题类型,照抄意义不大。真正可行的做法是把它当成一个可调参数,用固定的评估集跑出来。
最小可行的评估闭环是这样:准备三十到五十个真实问题(从用户实际问过的问题里挑,别自己编),标注每个问题应该命中哪几段原文。然后固定其他所有变量,只改分块策略和块大小,跑一轮看检索命中率——正确片段有没有出现在返回的前几个结果里。这一步只测检索,不测生成,因为生成质量受模型影响太大,噪声会淹没分块带来的差异。
命中率稳定之后再往下测端到端答案质量。RAGAS 这类评估工具可以挂在你已有的框架上做这一层,不用换框架。相关做法见RAG 怎么评估?凭感觉调是调不出来的。
要提醒的是:评估集本身的质量决定了这套流程有没有意义。用编出来的问题跑出来的最优块大小,换到真实流量上经常不成立。宁可只标二十个真问题,也别标一百个假问题。
七、框架层面要不要为分块换轮子
分块这件事,各主流框架都能做,差别在于默认给了多少现成的切分器、以及做深度文档理解时的开箱程度。
关于框架热度,有一组第三方统计口径的数据可以参考:截至 2026 年 1 月的 GitHub star 数,LangChain 约 125,000、Dify 约 114,000、RAGFlow 约 70,000、LlamaIndex 约 46,500、Haystack 约 24,000。要说明的是,star 数只反映关注度,不代表它在你的场景里更适用——它跟项目出现的早晚、面向的人群都有关系,拿它当选型依据会误导。
另有第三方评测指出,LangChain 的 LCEL 语法能做复杂的查询重写,但相比 LlamaIndex 的直接检索会多出约 15% 到 20% 的延迟开销。这是第三方基准的口径,不是官方指标,不同负载下差异会很大,只能当作”抽象层是有成本的”这个判断的一个佐证,不宜直接套到你的容量规划里。
更实际的一点是:这几个东西不是互斥的。一种常见的生产组合是用 LlamaIndex 做 ingestion 与索引、LangChain 做编排、LangGraph 做 agent 工作流。所以如果你只是想换个更好的分块器,通常不需要把整套编排推倒重来,把 ingestion 这一段单独换掉就行。框架选型的完整思路见RAG 框架怎么选?按瓶颈选,别按 star 数选。
自托管方面,按公开资料,RAGFlow 走 Docker 部署,提供 slim(2GB)与 full(9GB)两种镜像,区别是是否内置嵌入模型;LangChain 和 LlamaIndex 本身是库,所谓自托管就是你自己跑 Python 服务和向量库。向量库这一侧,Qdrant 是常见搭配,支持过滤、payload 索引与量化,第三方称在 100 万以上向量规模下可做到 50 毫秒以内检索,可以作独立二进制或 Docker 容器运行——这个延迟同样是第三方口径,实际表现跟硬件、索引参数、过滤条件都相关。
八、说清楚局限
有几件事得摊开讲,免得把分块当成万能开关。
分块能修的是”检索回来的片段不成话”这一类问题。如果你的问题是需要跨十几个文档做汇总统计,或者要沿着实体之间的关系一路追下去,那再好的分块也帮不上——这类需求的方向是图检索或者结构化查询,不是切得更聪明。语料本身是有链接关系的结构化内容时,可以看看图检索路线,参考图检索什么时候值得上?不是所有语料都适合。
语义切分虽然听起来先进,但它引入了一个额外的调参维度(相似度阈值),而且预处理时间会明显变长。全量语料上跑之前,先在一小部分文档上验证它确实比结构切分好,别默认更复杂就更好。
最后,分块策略改了之后向量库要重建。这在小规模知识库上是几分钟的事,在几十万文档的规模上就是一次需要排期的任务,还得考虑重建期间线上怎么切换。所以块策略值得在项目早期就多试几轮定下来,越往后改代价越大。
小结
按固定字数切之所以是下限最低的一种,是因为它唯一的依据是长度,而长度跟语义几乎无关。改进路径有明确的先后:先确认解析读对了文档,再换成按结构或递归分隔符切,再把检索单位和喂给模型的单位拆开,最后才用真实问题组成的评估集把块大小跑出来。重叠是缓解切点断裂的补丁,不是结构问题的解药,比例控制在一到两成通常够用。框架和向量库的选择会影响做这些事的顺手程度,但不该反过来主导策略——各家的具体能力和参数,以官方文档当前版本为准。