---
title: "搭一条能用的分块与重排流水线"
description: "分块决定检索能拿到什么，重排决定模型先看到什么。本课从按结构切块开始，经过混合召回与重排，最后用 20 条问题量出召回是否够用。"
updated: 2026-11-13
canonical: https://docai.cc/learn/build-a-chunking-pipeline/
markdown_mirror: https://docai.cc/learn/build-a-chunking-pipeline.md
---
## 第一步：按结构切块

先切语义边界，再考虑长度。标题层级是最可靠的边界：一个二级标题下的小节，通常就是完整的语义单元；段落、列表项、表格、代码块也各有边界。

处理原则：表格不要按行切散，表头要跟数据放一起；代码块不要从中间截断；结构不够用时再按长度兜底，落刀点选在句号、问号或换行附近；相邻块留一小段重叠，避免答案跨在边界上。

块大小要和上下文预算一起考虑，没有通用最优值。中文没有空格，按固定字符数切容易切坏词，优先按标点切。

## 第二步：保留标题路径

每个块单独取出来时，必须还带着自己的坐标。做法是给块附加一条标题路径，例如「部署 > 回滚 > 常见错误」，向量化和送进模型时都带着它。

一块正文脱离标题后，可能像在讲任何一件事；带上路径，检索和重排模型才能判断它属于哪一层。

工程上把路径当元数据存一份，同时拼进块文本前部。只存不拼，向量检索用不上；只拼不存，过滤和展示时又会丢。

分块的整体思路见 [RAG](/concepts/rag/)，切分粒度与窗口预算的关系见[上下文窗口](/concepts/context-window/)。

## 第三步：混合召回

只走向量会漏掉专名、编号和错误码，只走关键词又接不住口语化描述。两路并行召回，再合并结果：

- 向量路：把查询和块分别编码，按相似度取候选，编码模型见[向量化](/concepts/embedding/)。
- 关键词路：按词项匹配打分，专名和数字一字不差才命中。
- 融合：按名次而不是原始分数合并，避免两套分数量纲不同带来的偏置。

两路都要设超时，一路失败时退回另一路。候选合并后去重，同一个块只保留一份。向量怎么存，见[向量数据库](/concepts/vector-database/)。

## 第四步：重排取前 n

召回追求快和全，重排追求准。把候选逐条与问题一起送进重排模型重新排序，只取最前面的 n 条放进提示。

k 与 n 要一起调：k 太小，答案进不了候选；n 太大，无关片段占满预算。重排多了一跳，候选多、文本长时延迟明显。

必须有降级路径：重排超时或报错时退回原始召回顺序。召回质量很差时，先修分块和召回，别指望重排把答案变出来。

## 第五步：用 20 条问题量召回

准备 20 条有明确答案的问题，人工标出每条对应哪些块，然后分两层看：

- 重排前：正确块有没有进候选。没进，是分块或召回的问题。
- 重排后：正确块有没有进前 n。进了候选却没排上来，是重排的问题。

逐条记录失败类型：专名没命中、数值被切碎、答案跨块、表格没保住。哪类占多数就先改哪一层。不要拿这 20 条反复调参调到全过——那只是在背题。样本要轮换扩充，真实流量的新失败要补进来。

## 自测

1. 问：块切得越短，检索就越准吗？
   答：不一定。块太短会把答案和前提拆散，召回准了但模型没有足够材料回答。要调的是切分边界与块大小。

2. 问：既然有了重排，召回阶段是不是可以随便取？
   答：不行。重排只对已召回的候选重新排序，召回没进候选的内容它看不到。召回要保证覆盖率，重排只负责排序。

3. 问：两路召回的分数能直接相加吗？
   答：不建议。两种分数量纲不同，直接相加会偏向其中一路，按名次融合更稳。
