Skip to content

第 4 课:Chunking 与 Embedding 决定召回上限

RAG 课程 · 04 |目标:能用真实 query 评估切分和向量模型|用时:25 分钟

很多人看到答案不准,第一反应是换更大的 LLM 或修改 prompt。但如果正确答案没有进入召回结果,生成模型再强也无法凭空恢复它。检索决定上限,生成主要负责发挥。

Chunking 的核心矛盾

切块不是单纯的“每 500 个字切一刀”,而是在两个风险之间取平衡:

切法优点风险
块偏大上下文较完整主题混杂、向量语义被稀释、上下文噪声多
块偏小检索更精确、噪声更少指代丢失、规则与条件被拆散
有 overlap缝合切口处的语义存储膨胀、重复召回、上下文浪费

例如:

text
Chunk A:员工可以申请年假。
Chunk B:申请应至少提前 3 个工作日提交。

如果用户问“年假需要提前几天申请”,只召回 Chunk B 可能够用;但如果 Chunk B 是“申请应至少提前……”而没有“年假”的标题或前文,embedding 和模型都更难理解它的对象。

更好的结构感知切分是:

text
员工请假制度 > 年假
员工可以申请年假。申请应至少提前 3 个工作日提交。

三种切分策略

1. 固定长度切分

按字符数或 token 数切分,最容易实现,但可能从句子、表格或代码中间切开。适合内容结构简单、需要快速建立基线的场景。

2. 结构感知切分

优先沿文档天然结构切分:

  • Markdown:按标题层级切分。
  • 网页:按 DOM 语义区域切分。
  • PDF:按页、段落、标题和表格切分。
  • 代码:按模块、类、函数切分。

这是工程实践中很好的默认方案。先保住语义单元,再对过长段落做二次切分。

3. 语义切分

用 embedding 计算相邻句子的相似度,在主题发生明显跳变的位置切分。它更贴近内容边界,但计算成本和实现复杂度更高,适合高价值知识库或结构很差的文档。

python
chunks = split_by_headings(document)

for chunk in chunks:
    if token_length(chunk) > MAX_TOKENS:
        chunk = sliding_window(chunk, size=512, overlap=64)

Overlap 怎么设置

Overlap 是相邻 chunk 共享的文本,用来降低关键信息刚好被切断的风险。

  • 没有 overlap:存储省,但边界语义更容易断裂。
  • overlap 太大:召回结果高度重复,索引和上下文成本增加。
  • 常见起点:设为 chunk 大小的 10%~20%,然后用评测数据调整。

10%~20% 不是定律。FAQ、法条、表格等结构完整的内容可能不需要太多 overlap;叙述型文档或跨句依赖强的内容可能需要更多上下文。

Embedding 怎么选

Embedding 把 query 和 chunk 投影到同一个向量空间,决定语义匹配的上限。至少检查以下维度:

  1. **语种:**中文知识库应使用中文或多语模型;跨语言检索要确认模型是否做过跨语言对齐。
  2. **领域:**医疗、法律、代码等领域的术语分布不同,通用模型不一定能分辨细微差异。
  3. **检索形式:**短 query 找长文档是非对称检索,应优先选择针对 query-to-document 训练的模型,而不是简单句子相似度模型。
  4. **输入长度:**模型的最大 token 长度会反过来约束 chunk 大小。
  5. **维度与成本:**维度越高不等于一定更好,还会增加索引、内存和查询成本。

不要只看通用榜单选模型。你真正关心的是:在自己的中文、业务领域和 query 分布上,哪个模型能把正确 chunk 排进前 k 名。

Chunking 和 Embedding 要联动调

推荐顺序:

  1. 先按文档结构切出完整语义单元。
  2. 按 embedding 模型的输入长度限制,对超长单元二次切分。
  3. 从 10%~20% overlap 开始,观察重复率和边界问题。
  4. 用真实 query 标注正确 chunk,比较多个 embedding 模型。
  5. 用 Recall@k、MRR 和延迟判断,而不是只看主观回答。

一个最小评测集

至少准备以下字段:

json
{
  "query": "年假需要提前几天申请?",
  "relevant_chunk_ids": ["leave-policy-annual-001"],
  "expected_answer": "至少提前 3 个工作日",
  "source": "员工请假制度 / 年假"
}

运行不同切分和 embedding 方案后,检查正确 chunk 是否进入 top_k。如果没有,先解决检索;如果有但答案仍错,再检查重排、上下文和生成。

本课练习

针对“公司请假制度”设计两套方案:

  • 方案 A:固定长度切分。
  • 方案 B:按标题结构切分,过长段落再滑动切分。

为每套方案写出 chunk 大小、overlap、metadata 和你会使用的 5 条评测 query。然后说明你会用什么指标决定 A 或 B 更好。

主读材料

Chunking 怎么切、Embedding 怎么选,才决定 RAG 的上限。重点关注切分策略、overlap 和“用自己的 query 评测 embedding”的观点。

下一步

有任何不清楚的地方,直接向老师提问。