面试问到chunk心慌慌?从企业开发者角度谈一谈具体的chunk策略选择

之前团队在做合同审查和研报问答两个 RAG 项目,踩了不少分块(Chunk)相关的坑。今天把这块经验整理一下,希望对正在做类似事情的朋友有点帮助。

先搞清楚 Token 这个概念

做 Chunk 之前,得先理解 Token。很多人把 Token 简单等同于"字"或"词",这不太准确。Token 是模型实际处理的最小单元,中文大约 1.5-2 个字对应一个 Token,英文则大约是 0.75 个单词一个 Token。

这件事为什么重要?因为不同类型的文档,Token 密度差异很大。我们实测过:一份 20 页的中文合同,大约 8000-12000 个 Token;一篇 8 页的学术论文(中英混排),Token 数可能到 6000-9000;而一份 30 页的分析报告,因为包含大量表格和数据描述,Token 数经常飙到 15000 以上。这意味着同样设 512 Token 的分块大小,在合同里可能刚好覆盖一个完整条款,在报告里可能只截到半张表格。所以分块参数不能一刀切,得结合文档特征来定。

六种分块策略到底怎么选

我把目前主流的六种策略做个对比。

固定大小分块是最简单的方案,按固定 Token 数切分,实现成本低、速度快。但它最大的问题是完全不管语义边界——一句话可能被拦腰切断,检索出来的片段答非所问。适合对精度要求不高的初期原型验证。

滑动窗口分块在固定大小基础上加了重叠区域(Overlap),相邻块之间共享一部分内容,一定程度上缓解了上下文断裂的问题。实现也不复杂,是固定分块的实用升级版。代价是存储量会膨胀,重叠区域设大了还会引入噪声。

自然结构分块利用文档本身的结构标记来切分——比如 Markdown 的标题层级、PDF 的章节目录、Word 的 Heading 样式。这种方式对格式规范的文档效果很好,每个块天然就是一个完整的语义单元。但现实中很多文档格式混乱,一旦结构缺失就会退化成一整块的大段文本。

递归分块是 LangChain 里比较常用的方案,它按分隔符优先级逐层递归切分:先按段落切,如果还太长就按句子切,最后按字符切。这种方式在大多数通用场景下表现都不错,是个稳健的"中间路线"。

语义分块更进一步,它用 Embedding 模型计算相邻句子的语义相似度,在相似度骤降的地方切分。这种方式最能保证每个块的语义完整性,但计算成本也最高——每次分块都要跑一遍 Embedding,对大批量文档来说不太现实。

混合分块顾名思义,组合使用以上策略。比如我们在合同项目中的做法是:先用自然结构把文档按条款拆开,对超长条款再用递归分块做二次切分,关键条款则加上语义分块保证完整性。灵活但实现复杂度高,需要针对具体业务做调优。

不同场景的实战选择

经过几个项目的摸索,我总结出来的经验大致是这样:

结构化程度高的文档(法律合同、技术文档、学术论文),优先用自然结构分块,配合递归分块做兜底。这类文档标题和层级信息本身就是很好的切分线索,别浪费了。

非结构化的长文本(会议纪要、访谈记录、邮件往来),语义分块或递归分块更靠谱。这类文档没有明确结构,强行按格式切只会乱套。

对实时性要求高、数据量大的场景(客服知识库、产品FAQ),固定大小加滑动窗口就够了。这类场景每条文档本身就不长,分块精度的收益远不如检索速度重要。

用动态路由自动化选择

如果你的系统要处理多种类型的文档,手动配策略迟早会崩。我们后来做了一层轻量的动态路由:文档进来后先跑一个分类模块,识别文档类型(合同/报告/通信记录等)和结构特征(有无标题层级、平均段落长度、是否含表格),然后根据预设的规则映射到对应的分块策略组合。

具体实现上,我们用了一个简单的决策树:先判断文档是否有清晰的结构标记,有的话走自然结构分块;没有的话看文档长度,短文档直接递归分块,长文档走语义分块。每条路径都有参数模板,比如合同类的块大小默认 384 Token、Overlap 设 64,报告类默认 512 Token、Overlap 设 128。

这套东西不复杂,但上线后分块质量确实稳定了不少,也省去了每接一个新文档类型就要手动调参的麻烦。

说到底,Chunk 策略没有最优解。最重要的还是理解你的数据长什么样、你的用户会怎么提问,然后在效果和成本之间找到那个平衡点。

如果大家有需要,后续可以出一篇在极端情况下(如语义切块/自然结构分块时,段落长度差异巨大)的动态路由策略分享。

#AI求职实录#
全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务