你的 RAG 流水线将文档切分为 512 个 token 的片段,并带有 50 个 token 的重叠。这是一个标准的行业默认设置。在你的语料库中,有这样一句话——“除非订单来自欧盟地区(在这种情况下监管窗口为 14 天),否则退款将在 5 个工作日内处理”——它恰好跨越了分块边界。分块 N 包含前半部分。分块 N+1 包含后半部分。
用户提问“欧盟退款需要多长时间”。检索系统给分块 N 打分最高,因为查询嵌入与第一段碎片中的“欧盟地区”对齐。而包含唯一实际答案的分块 N+1 排名太低,无法同时被检索到。智能体回答“5 个工作日”,并自信地引用了分块 N。客户人在法兰克福。答案是错误的。流水线完全按照设计运行。
这种故障模式不会出现在你的分块质量评估中。分块是格式良好的。语料库是格式良好的。嵌入模型是格式良好的。分块之间的边界——你在自己文档中划下的那些线——才是答案所在。
分块器是为上下文窗口而建,而非为了意义
每个流行 RAG 框架自带的默认分块器都是围绕一个约束设计的:嵌入模型的上下文窗口。512 个 token 是编码器能容纳的上限。带有重叠的递归 token 切分既能干净地适应这个上限,又能在索引时保持低廉的计算成本。
这种设计完全没有考虑到语篇逻辑。token 切分器不知道“除非订单来自欧盟地区”是一个从句,其含义取决于它修饰的主句。它不知道合同中带编号的例外情况一旦与它所限定的规则分离,就会失去功能。它也不知道没有表头的表格行是一行没人能理解的数字。切分器只知道 token 和换行符。文档的语篇结构对它来说是不可见的。
增加 50 个 token 的重叠是为了捕捉边界溢出,但重叠是根据典型句子长度校准的。长复合句——那些带有例外、限定条件、前提和豁免条款的句子——经常会超过重叠窗口。而在法律、监管、财务和政策文档中,起到支撑作用的句子几乎总是长句。重叠是为了保护中位数长度的句子。它保护不了那个关键的句子。
2026 年 1 月一项使用 SPLADE 检索对重叠进行的系统分析发现,总体而言,重叠没有提供可衡量的召回率提升,只是增加了索引成本。总量数据隐藏了重叠起关键作用的情况和重叠纯属摆设的情况。它没有区分二者,你的评估套件可能也没有。
为什么分块质量评估会错过这类失败
当运行分块质量评估时,通常会评判两件事:是否检索到了正确的分块,以及该分块是否包含回答问题的句子。在上述被切分的案例中,这两个问题的答案都是“是”。分块 N 被检索到了。分块 N 包含关于欧盟退款的句子。评估通过了。但用户并不满意。
实际的失败在于检索返回了句子的错误一半,而评估没有任何“答案跨越边界”的概念。Top-k 召回率是在分块级别衡量的。金标准答案被锚定在一个分块上。流水线返回了那个分块。评分器记录了一次命中。没有人问过分块的文本本身是否足够——或者模型是否需要读取上方或下方的分块才能真正回答。
这是已知 RAG 病理学——上下文充分性 (context sufficiency) ——在分块领域的对应物。最近的研究表明,即使检索在 Top-k 指标上“成功”,一半以上的复杂检索查询仍缺乏生成正确答案所需的充分上下文。边界切分是导致上下文不足的一个特定原因。检索调用返回了包含问题关键词的分块。该分块不包含问题的答案。生成器随后编造了剩余部分。
具有覆盖意识的评估必须直接测试这一点。获取你的真实语料库。识别那些跨越分块边界的句子。构建专门针对这些句子的查询。将金标准答案跨越边界时的检索召回率作为一个独立指标,与你的总体召回率分开衡量。这两个数字会产生分歧。这个差距就是你一直在交付的故障模式。
真正缩小差距的方法
几种技术可以在流水线的不同层级解决切分问题。没有任何一种方案能独立解决所有问题;处理得好的生产环境栈通常会结合其中的两三种。
句感知与结构化分块 (Sentence-aware and structural chunking)。基于句子边界而非 token 计数进行切分会让你牺牲分块大小的均匀性,但能消除最常见的切分问题。更进一步,结构化分块将原子单元——合同条款、带编号的例外、带表头的表格行、带父级标题的列表项——固定在单个分块中,而不考虑 token 预算。分块有时会超过软限制;如果不这样做,代价就是软限制通过检索失败被默默地强制执行。
延迟分块 (Late chunking)。延迟分块由 Jina 在 2024 年引入,现在已成为长上下文嵌入工作流的标准,它反转了操作顺序。首先对全文进行嵌入,然后通过对每个分块 token 跨度进行均值池化 (mean pooling),从上下文感知的 token 表示中导出分块向量。因为每个 token 在编码期间都能看到整个文档,所以生成的分块向量保留了 token 边界分块会丢失的上下文。早期分块中提到的“欧盟地区”不再需要与“14 天”出现在同一个分块中——两半现在都锚定在一个共享的上下文表示上。
上下文检索 (Contextual retrieval)。Anthropic 的上下文检索方法则走向了另一个方向。它不是整体嵌入文档,而是在嵌入之前为每个分块添加一个由模型生成的、针对该分块的情境摘要。原本读作“监管窗口为 14 天”的分块变成了:“本分块讨论了 3.2 节中确定的退款处理时限的欧盟地区例外情况。监管窗口为 14 天。”Anthropic 报告称,在将上下文嵌入与 BM25 结合时,Top-20 检索失败率降低了 35%,而其他实现在妥善附加上下文后,检索错误减少了高达 67%。成本是在索引时每个分块多出一次模型调用——这确实可感知,但与生产环境中自信地给出错误答案的成本相比,只是九牛一毛。
检索时拼接 (Retrieval-time stitching)。改变分块策略的一种更便宜的替代方案:在检索时,当一个分块得分很高时,抓取其相邻的分块并将它们拼接成一个检索上下文窗口。这在索引时没有任何成本,只是在查询时通过牺牲一点 token 预算来换取边界稳健性。当相关上下文距离几段话而非相邻时,这没有帮助,但对于欧盟退款案例——两半正好隔着一个边界——它填补了空白。
层级化与语篇感知分块 (Hierarchical and discourse-aware chunking)。最近的学术研究构建了能保留完整文档层级(章节、小节、段落、句子)的树状分块器,而非扁平列表。检索随后可以遍历树:找到叶子节点,向上移动到父节点,调出赋予叶子节点意义的上下文。修辞结构理论 (RST) 已被用于识别语篇关系,并沿着这些关系而非 token 计数进行切分。这些方法在长篇、结构化文档上的表现优于任何 token 切分器,代价是索引过程更复杂。
这在架构层面意味着什么
更深层的认识是,分块(chunking)并不是一个预处理步骤。它是流水线(pipeline)对语料库中每篇文档做出的采样决策,而你划定的边界就是智能体(agent)思考时的边界。固定大小的分块器划定这些边界的依据——“我们有 512 个 token”——与原始材料中意义的组织方式毫无关系。
团队将分块大小视为一个调节旋钮。更小的分块是为了更高的精确率(precision),更大的分块是为了更高的召回率(recall)。这种权衡框架确实存在,但它忽略了一个前提问题:分块到底应该代表什么?如果答案是“一个能够独立存在并回答问题的意义单元”,那么任何固定大小的策略都无法满足要求。有些问题需要一个段落来回答,有些需要一个从句及其限定性的例外情况,有些则需要整个编号列表。Token 数量与这些需求完全不匹配。
成本框架在这里也很重要。你的 RAG 针对被切断的句子生成的每一个“自信的错误”答案,都是一次糟糕的客户交互——模型本可以获取正确信息,但流水线架构阻碍了它。这一成本最终由客户承担,并体现为支持工单(support ticket),最终被记录为模型质量问题,而实际上这本是一个检索架构问题。负责模型的团队背了黑锅,而负责分块器的团队拿到了预算。
本周你可以做的事
如果你无法在本季度重建分块流水线,你仍然可以在短期内解决那些代价最高昂的分断问题:
- 审计语料库中的长复合句。 找出超出重叠窗口(overlap window)长度的句子。抽检它们是否正好落在当前索引的分块边界上。这个列表会比你预想的短,而高价值的句子——如例外、条件、监管豁免条款——在其中占比会很高。
- 在评估中增加跨边界查询。 构建一个留出集(held-out set),其中标准答案(gold answer)已知是跨越分块边界的。将该子集的召回率作为一个独立的一级指标。每当分块大小、重叠或分块逻辑发生变化时,都要关注这一指标。
- 开启检索时的相邻块拼接。 这是成本最低且最容易上线的缓解措施。当 top-k 返回一个分块时,同时获取它的前一个和后一个分块。将这三个分块一起发送给模型。大多数边界切断问题都会被默默修复。
- 在风险最高的语料库子集上试点上下文检索(contextual retrieval)。 如果你只有重新嵌入一小部分数据的预算,请选择错误答案代价最高的部分。法律、账单、合规和监管内容往往既对边界最敏感,出错的代价也最昂贵。
那些根据 token 数量而非语篇单元(discourse unit)来选择分块大小的团队,无意中向最需要这些信息的模型隐藏了最重要的句子。模型本身没有问题。问题在于流水线在模型看到问题之前,就已经在答案上划了一道横杠。
会员专享
余下内容仅对会员开放。
会员可读完整内容 —— 每一个公开发布的观点背后,那些框架、决策与推理的全貌。
- —完整文章,包含未公开存档的部分
- —可落地的工作框架,附带权衡与决策依据
- —新文章抢先看,先于公开发布
随时取消 · 一次订阅,畅读全部