深蓝黑背景封面。左侧是一条自上而下的五环流水线:①「文档解析」PDF、Word、网页转成结构化纯文本;②「清洗」去掉页眉页脚、乱码与模板噪声;③「分块」切成 256~512 token 的块并留重叠;④「嵌入」每个块算成一个向量;⑤「入库」向量加元数据写入向量库建索引。各环节之间用向下箭头连接,每环右侧附一行紫色小字暗坑提示:多栏排版顺序错乱、误删正文、块大小失衡、通用嵌入模型在专业领域表征弱、漏挂元数据无法过滤。左下一行小注「索引质量在上线前就已定型:检索烂多半是这里埋的雷」。右侧大标题两行「从原始文档」「到可检索索引」,副标题「解析、清洗、分块、嵌入、入库:五环各有暗坑」,小注「知识延伸:RAG 工程落地全链路」。左上角标注「知识延伸 · RAG 工程」,右上角圆角胶囊标注「Day 06 · 12-03」。 图 1:本文封面,索引构建的五环流水线。

面试里被问「RAG 的分块有哪些切法」时,这个系列另有一篇真题解析专门拆解分块方法本身。本篇换个视角:分块只是索引构建流水线的中间一环,从原始文档到可检索索引,端到端要走解析、清洗、分块、嵌入、入库五步,每一步都有典型坑。索引质量在上线前就已定型——线上检索烂,多半是这里埋的雷。

第一环:文档解析。 PDF、Word、网页要变成结构化纯文本。典型坑是版式:多栏排版被按行读成左右交错的乱序文字,表格被打散成一列孤立的单元格,标题层级全部丢失。按文字坐标还原阅读顺序、按 DOM 结构提取正文,比直接抽文本可靠得多;扫描件还要先过 OCR,识别错误的文字会直接变成检索噪声。这一环偷懒,后面所有环节都在给垃圾输入擦屁股。

第二环:清洗。 去掉页眉页脚、页码、乱码、「内部资料请勿外传」这类模板行。坑在尺度:规则太松留下噪声,噪声会被嵌入成向量、稀释检索;规则太狠误删正文,答案直接被洗掉。清洗规则要按文档来源分别配置,并保留清洗前后的人工抽查环节。

第三环:分块。 把干净文本切成数百 token 的块并留重叠,方法细节见真题解析,这里只强调它在流水线里的位置:分块消费的是清洗后的文本,输出时要带上「来自哪篇文档、第几块」的元数据雏形,供入库环节使用。坑是块大小失衡——块太大噪声多,块太小上下文碎。

第四环:嵌入。 每个块算成一个高维向量。坑是通用嵌入模型在专业领域(医疗、法律、内部黑话)表征弱:语义相近的领域表述在向量空间里距离并不近,必要时换领域模型或用自有语料微调嵌入模型。还要记住一个约束:嵌入模型上线后很难换——换模型意味着全量重建索引,选型要当成架构决策来做。

第五环:入库。 向量连同元数据写入向量库建索引。最大的坑是漏挂元数据:来源、时间、权限、文档 ID 没有随向量入库,上线后想做「只查某个部门」「只查近半年」的过滤检索就没有地基。第二个坑是更新:文档修订后旧向量残留,新内容上线了旧答案还能被召回。正确做法是按文档 ID 先删旧向量、只重建受影响的块。

用一段迷你流水线把五环串起来(Node.js 22.15.0,嵌入用字符频次向量占位演示,node pipeline.js):

function upsertDocument(docId, text) {
  for (let i = store.length - 1; i >= 0; i--) {
    if (store[i].meta.docId === docId) store.splice(i, 1); // 先删该文档旧向量
  }
  chunk(clean(text), 40).forEach((c, idx) => {
    store.push({ vec: fakeEmbed(c), meta: { docId, chunkIndex: idx, source: 'manual.pdf' } });
  });
}

实测输出:

更新 doc-1: 删除旧向量 0 条,写入新向量 2 条
清洗后残留页脚? false
首块元数据 = {"docId":"doc-1","chunkIndex":0,"source":"manual.pdf"}
更新 doc-1: 删除旧向量 2 条,写入新向量 3 条
库内总向量数 = 3

页脚「- 3 -」和模板行被清洗环节去掉;每个块带着 docId 与 chunkIndex 入库;文档更新时旧的两条向量先被删除、新的三条写入,库里不留残影——这就是「按文档 ID 更新」的最小闭环。

深蓝黑背景概念图,顶部小字「概念图 · RAG 索引构建」,主标题「五个环节串成一条流水线,每个环节都有典型坑」。主体是横向五环卡片,箭头依次相连:第一环「文档解析」,输入 PDF、Word、网页,输出结构化纯文本,坑是「多栏排版与表格被读成乱序行」;第二环「清洗」,输入原始文本,输出干净语料,坑是「规则太狠误删正文、太松留下噪声」;第三环「分块」,输入干净语料,输出 256~512 token 带重叠的块,坑是「块大噪声多、块小上下文碎」;第四环「嵌入」,输入文本块,输出高维向量,坑是「通用嵌入模型在专业领域表征弱,必要时换领域模型」;第五环「入库」,输入向量与元数据,输出可检索索引,坑是「漏挂元数据无法过滤、文档更新后残留旧向量」。底部总结条写「更新机制:文档变更时按文档 ID 删除旧向量、只重建受影响的块;来源、时间、权限等元数据随向量入库,是后续过滤检索的地基」。 图 2:五个环节的输入输出与典型坑,以及更新机制。

入库之前还有一次自检机会。 流水线跑完别急着上线:抽几十条真实问题做检索回放,看命中的块是不是答案所在;再抽一批块人工读一遍,看有没有被切断的句子、残留的页眉、乱序的表格。五环里任何一环返工,下游都要跟着重建——改动越早越便宜。索引侧的问题在构建阶段发现,代价是重跑一遍流水线;等用户在线上碰到,代价就是信任了。

收尾。 五个环节的记忆点:解析保结构、清洗讲尺度、分块定粒度、嵌入选模型、入库带元数据与更新机制。LlamaIndex 官方文档把这条链抽象为 IngestionPipeline——文档进、节点(块)出,分块器只是其中一个变换环节,这个抽象本身就说明:分块是流水线的中段,不是全部。你的知识库流水线在哪一环踩坑最多?欢迎分享。