
做知识库检索增强(RAG)的时候,很多人都会遇到这两个极端问题:要么检索出来的片段只有半句话,大模型找不到依据开始胡说八道;要么把切片设得太大,检索回来的内容一口气塞满上下文窗口,不仅 Token 费用暴涨,大模型还容易在长文本里“迷失”,找不到重点。
遇到这种情况,很多人第一反应是换更高维度的向量模型,或者换更大的大模型。但是如果你翻开日志看一眼,就会发现问题根本不在模型,而是你的文档分块(Chunking)策略从第一步就失衡了。
为什么块太大或太小都会翻车?
文档分块本质上是在做一件权衡的事:切片越小,向量检索的针对性越强;切片越大,保留的上下文语义越完整。
如果把块切得太小,比如只有 50 到 100 个 Token,单句话的向量确实能精确匹配用户的提问词。但在实际测试中,这种短碎片的端到端问答准确率往往非常糟糕。FloTorch 在基准测试中发现,平均长度只有 43 个 Token 的切片,最终问答准确率仅仅刚过 50%。原因很简单:句子脱离了上下文,主语不见了,代词不知道指代谁,大模型拿到这几句碎片根本拼不出完整逻辑。
但是,如果把块切得太大,比如直接拉到 2000 个 Token 以上,问题同样严重。英伟达(NVIDIA)和 Firecrawl 的多项实测数据表明,当单块上下文超过 2048 Token 时,生成质量会出现明显的下滑。切片内容太长,向量本身代表的是整个段落的平均语义,反而把关键信息点稀释掉了,导致检索命中率下降。而且更致命的是,常用的开源向量模型(比如 `bge-base-zh-v1.5`)通常有 512 Token 的输入硬限制。如果你的分块超过了这个长度,模型在向量化时会直接进行静默截断,后面的内容根本没有生成向量,相当于后半段内容直接丢失。
四种主流分块策略选型对比
在动手调参前,先要搞清楚手头方案的优缺点。目前工业界最常用的有以下四种方案,它们的特点和适用场景差异很大:
| 分块方案 | 实现复杂度 | 检索精确度 | 上下文完整度 | Token 消耗控制 | 最适合的业务场景 |
|---|---|---|---|---|---|
| 固定字符分块 (Fixed-size) | 低 | 低 | 差(易切断句子) | 好(长度固定) | 格式极规整的日志、扁平文本 |
| 递归字符分块 (Recursive) | 低 | 中到高 | 良好 | 较好 | 通用业务文档、知识库冷启动默认选择 |
| 语义分块 (Semantic) | 高 | 高 | 较好 | 难以预测 | 段落间主题转换频繁的长篇叙述文 |
| 父子文档分块 (Parent-Child) | 中等 | 高 | 极佳 | 优秀(按需组装) | 合同条款、技术手册、复杂规章制度 |
从工程落地的角度来看:
•递归字符分块是性价比最高的默认方案。它会按顺序尝试段落换行、句子标点、空格来切分,尽量保证句子完整。
•语义分块目前在中文生产环境里要谨慎选用。它需要逐句计算向量相似度来找分段拐点,计算开销大,耗时通常是递归分块的数倍,但召回率的改善往往只有 2% 到 3%,工程产出比并不划算。
•如果你既要检索准,又要大模型看得懂,父子文档分块是目前效果最稳的架构。
分块与 Token 平衡的实操五步法
如果你正面临检索不准或者超 Token 的问题,不要凭感觉改参数,按照下面的步骤顺序走:
第一步:根据问题类型设定初始基准尺寸
不同的业务场景,用户提问的方式完全不同:
•事实型查询(Factoid):比如“退货时限是几天”、“报错代码 502 代表什么”。这类场景需要精准命中,推荐切片大小设为 256 到 400 Token。
•分析型与推理型查询(Analytical):比如“对比方案 A 和方案 B 的架构差异”、“总结第二季度的运营策略”。这类场景需要大段逻辑支撑,推荐切片大小设为 512 到 1024 Token。
在基准测试中,512 Token 是综合表现最稳定的起点参数。
第二步:强制配置 10% 到 20% 的重叠率(Overlap)
切片之间绝对不能做物理一刀切。如果不设重叠,某句话刚好被切成两半,这一句的核心信息在两个切片里就都失效了。
•如果你的切片大小是 512 Token,重叠长度建议设在 50 到 80 Token 之间。
•避坑提示:重叠率不要超过 25%。重叠过大不仅会让你的向量数据库体积膨胀 30% 以上,还会导致检索结果里充斥大量重复文字,白白浪费送入大模型的上下文窗口。
第三步:统一使用 Tokenizer 计数,禁止按中文字符数硬切
这是很多团队最容易踩的坑:直接拿 Python 的 `len(text)` 统计字符数做切块。
•中文一个汉字在不同的分词器(Tokenizer)下可能对应 1 到 2 个 Token。
•如果你按 500 个字符去切,遇到特殊符号或英文混排时,转换成 Token 可能直接飙到 700 甚至更多,超过了向量模型的输入上限。
•标准操作:调用目标模型对应的 Tokenizer(比如 HuggingFace 的分词器或 Tiktoken)来计算长度,确保每个切片的 Token 数严格小于向量模型的最大支持长度。
第四步:引入“小块检索,大块输入”做解耦
这是彻底解决“检索准确度”与“上下文长度”矛盾的核心方法,也就是通常说的父子文档检索(Parent Document Retriever)。具体操作如下:
1.生成父块:先将原始文档切成较大的语义单元,比如 1000 到 1500 Token 的大块,包含完整的业务逻辑。
2.切分出子块:再将每个父块细切为 200 到 300 Token 的小块。
3.建立映射存储:只把小块的文字向量化并存入向量库,同时在元数据(Metadata)里标记对应的父块 ID。
4.检索与替换:用户提问时,向量库只比对 200 Token 的小块,保证检索的高精度命中;命中最匹配的小块后,系统根据 ID 提取出完整的 1000 Token 父块送给大模型。
这样做的好处是显而易见的:检索阶段用短文本保精度,生成阶段用长文本保逻辑,两边都不受委屈。
第五步:在组装 Prompt 前设置硬性预算与 Rerank 过滤
大模型的上下文窗口就算有 128K,也不要把搜出来的东西全倒进去。给大模型喂太多弱相关内容,回答质量会直线下降。
•固定上下文预算:不管检索到多少块,每次拼入 Prompt 的参考文档总量必须设硬上限,建议控制在 2000 到 3000 Token 以内。
•引入 Rerank 重排模型:初筛拿回 Top-15 个切片,然后用 Cross-Encoder 重排模型打分,只留下相关度得分高于阈值(例如 0.65)的前 3 到 5 个切片。这样既压低了实际消耗的 Token 数量,又过滤了检索噪点。
常见文档类型的参数配置速查
不同格式的文档不能用同一套参数通吃。下面是我们在实际项目中验证过效果较好的参数组合:
| 文档类型 | 切块策略 | 推荐切块大小 (Chunk Size) | 推荐重叠长度 (Overlap) | 特殊处理建议 |
|---|---|---|---|---|
| Markdown / 结构化技术文档 | 标题层级切分 + 递归切分 | 512 Token | 50 Token | 务必将上级各级标题路径(如 `# 一级 / ## 二级`)写入每个切片的元数据,辅助向量识别 |
| PDF 扫描件 / 财报表格 | 页面级切分 / 表格转 Markdown | 单页或 1024 Token | 100 Token | 严禁切断表格行,表格数据必须转为 Markdown 或 JSON 格式后再独立成块 |
| 客服 FAQ / 短问答库 | 单问答对独立成块 | 无需切分 (100-300 Token) | 0 | 将问题与答案绑在同一个切片内,优先针对“问题文本”做向量化索引 |
| 长篇小说 / 故事叙述 | 递归字符切分 / 父子文档 | 800 – 1200 Token | 120 Token | 依赖较长篇幅保持叙事连贯性,可搭配大窗口上下文模型直接输入 |
在真实业务里调试分块,切忌凭主观感觉判断好坏。先从真实的业务日志里挑出 50 个具有代表性的用户问题,建立一个固定的问答评测集。以 512 Token 大小、10% 重叠的递归切分为基准跑一次命中率和回答准确率;然后尝试调整尺寸或者加上父子文档结构。只要看测试集上的召回率变化和 Token 账单对比,哪个方案最平衡、最稳当,数据自然会给出结论。
原创文章,作者:七点互动,如若转载,请注明出处:https://ai.qidianhudong.com/aikonw/3676.html