Chico Notes
LLM Wiki / RAG

RAG 数据摄取与索引流水线:别让脏数据进入向量库

设计生产级 RAG 的数据摄取、解析、清洗、增量索引、权限元数据、Embedding 缓存和索引发布流程。

持续修订的工程笔记

RAG 的线上质量,很多时候在用户提问前就已经决定了。文档有没有解析对,表格有没有丢列,旧版本有没有清掉,权限有没有带进索引,Embedding 是否复用缓存,都会直接影响后面的召回和生成。

数据摄取流水线的目标不是“把文档塞进向量库”,而是把原始内容变成可检索、可引用、可授权、可回滚、可评测的知识单元。

核心判断

如果索引里没有 document_id、chunk_id、source、updated_at、acl、pipeline_version,就很难做生产级 RAG。你能回答问题,但很难解释、修复和回滚问题。

调研摘要

主流 RAG 工程方案在数据摄取上有几个共同点:

  • LlamaIndex 的 ingestion pipeline 把加载、切分、元数据抽取、Embedding 等步骤看作 transformations,并通过缓存避免重复处理相同节点。
  • LangChain 的 indexing 思路强调记录源文档和派生文档的关系,避免重复写入和无效重建。
  • Azure AI Search 的 RAG 文档强调多源数据接入、增量索引、chunking、vectorization、hybrid search、semantic ranking 和查询时权限裁剪。
  • Elastic 的 RAG 资料强调外部知识更新、引用可验证、document-level access control,以及文本、向量、混合和语义检索组合。

落到工程实践里,可以把摄取流水线拆成八个阶段。

总体流水线

这条链路最好是可重放的。任意一个版本的索引都应该能回答:它来自哪些数据源、用什么解析器、什么分块策略、什么 embedding 模型、什么权限快照生成。

1. 数据源接入

生产 RAG 往往不是单一文档目录,而是 Wiki、PDF、网页、对象存储、数据库、客服工单、代码仓库和内部系统的混合体。

数据源接入重点常见风险
Wiki / Markdown标题层级、页面路径、更新时间、作者。链接失效、重复页面、草稿页混入。
PDF / OfficeOCR、页码、表格、图片说明、版面顺序。断行、表格错列、页眉页脚重复。
Web 页面正文抽取、导航去噪、canonical URL。菜单、脚注、广告进入索引。
数据库字段解释、主键、更新时间、权限映射。结构化字段直接拼文本导致语义丢失。
代码仓库文件路径、函数/类边界、版本分支。按长度切断函数或配置块。

接入层不要急着生成 embedding。先把 source manifest 建好,记录每个源的同步范围、频率、owner 和权限策略。

2. 变更检测

没有增量机制的 RAG 索引,很快会遇到两个问题:全量重建太慢,旧内容无法清理。

建议为每份文档计算稳定指纹:

{
  "source_id": "wiki:rag-playbook",
  "source_url": "https://example.com/wiki/rag-playbook",
  "content_hash": "sha256:...",
  "metadata_hash": "sha256:...",
  "updated_at": "2026-07-07T10:00:00Z",
  "deleted": false
}

增量索引至少要识别四种事件:新增、内容更新、元数据更新、删除。元数据更新也很重要,因为 ACL、owner、业务标签变化可能不改变正文,但会改变检索边界。

3. 解析与抽取

解析阶段的产物不应该只是一段纯文本。生产系统更需要结构化中间表示。

推荐中间结构包含:

字段用途
block_id后续 chunk 和引用映射的基础。
block_typeparagraph、heading、table、image、code。
text规范化后的文本。
page / positionPDF、PPT、扫描件定位。
heading_path保留文档层级。
source_span回溯到原文位置。

不要过早丢掉页码、标题路径和表格结构。后面做 citation、bad case 复现和人工审核时,这些字段很关键。

4. 清洗与规范化

清洗不是把文本“变干净”这么简单,而是减少会污染检索的噪声。

清洗项处理方式
页眉页脚统计重复文本,按页删除。
导航菜单对网页抽取正文区域,过滤导航和版权信息。
断行合并 OCR 或 PDF 抽取造成的异常换行。
重复版本通过 canonical URL、文档 ID、版本号去重。
过期内容保留状态字段,不一定物理删除,但默认不召回。
空内容图片、扫描件、空表格需要补 OCR 或标记不可用。

清洗规则要版本化。否则一次规则调整导致召回变化时,很难判断是数据变了还是 pipeline 变了。

5. 元数据和权限

元数据不是附加字段,而是 RAG 的控制面。没有元数据,就做不了权限过滤、时间过滤、业务路由、引用和回滚。

{
  "document_id": "doc_rag_playbook",
  "chunk_id": "doc_rag_playbook_0042",
  "source": "wiki",
  "source_url": "https://example.com/wiki/rag-playbook#release-gate",
  "title_path": ["RAG Playbook", "Release Gate"],
  "owner": "ai-platform",
  "updated_at": "2026-07-07",
  "doc_status": "active",
  "acl_groups": ["team:ai-platform"],
  "pipeline_version": "ingest_2026_07_07",
  "embedding_model": "text-embedding-v3"
}

权限建议在检索前就裁剪,而不是把无权内容放进 prompt 再要求模型不要泄露。缓存 key 也要包含用户权限上下文,避免跨租户或跨团队污染。

6. 分块与父子关系

分块策略在 Chunking 工程指南 里已经展开。摄取流水线里需要额外关注的是:分块结果要能增量更新和回溯。

先按结构切分,保留 heading_path、block_id 和 source_span。
再生成 child chunk 用于精确召回,parent section 用于补上下文。
对表格、代码、FAQ、配置项使用专门策略,不强行按固定长度切。
为每个 chunk 计算 hash,正文不变时复用 embedding。

一个常见错误是:文档某一段更新后,整篇文档所有 chunk_id 都变化。这会破坏引用、评测样本和 bad case trace。chunk_id 应尽量稳定。

7. Embedding 与索引写入

Embedding 是昂贵步骤,也会成为质量漂移来源。生产系统需要把 embedding 模型、维度、归一化方式和生成时间写进 manifest。

索引写入通常至少有两类目标:

索引内容
全文索引text、title、heading、keywords、metadata,用于 BM25 / keyword search。
向量索引embedding、chunk_id、metadata,用于 semantic / vector search。

如果使用 hybrid retrieval,两个索引的 chunk_id 和过滤字段必须一致。否则线上 trace 很难解释“为什么 BM25 找到了而 vector 没有”,也很难合并排序结果。

8. 索引发布

不要直接把新索引写到线上 collection。更稳的方式是构建新版本索引,评测通过后切 alias。

每个索引版本都应该有 manifest:

字段说明
index_version索引版本。
source_snapshot数据源快照或同步时间。
parser_version解析器版本。
chunker_version分块策略版本。
embedding_modelEmbedding 模型和维度。
doc_count / chunk_count文档数和 chunk 数。
eval_report发布前评测报告链接。

上线后如果出现集中 bad case,先看 manifest,而不是直接猜 prompt 有问题。

质量门禁

摄取流水线完成后,至少跑一组数据质量和检索质量检查。

检查失败信号
文档数量文档数突然大幅变化。
Chunk 数量平均 chunk 数异常,说明解析或切分可能出问题。
空文本比例OCR、正文抽取或过滤规则异常。
重复率重复页面、历史版本或导航噪声进入索引。
权限覆盖chunk 缺少 ACL 或 ACL 分布异常。
Recall@KGolden Set 正确证据召回下降。
Citation Sample抽样引用无法回到原文位置。

这些检查应该在索引发布前执行,而不是等用户线上报错。

常见反模式

最小实现清单

如果从零开始,先做到这些:

  • 为每个数据源建立 source manifest。
  • 为每份文档计算 content_hash 和 metadata_hash。
  • 解析阶段保留 block、page、heading_path、source_span。
  • Chunk schema 包含 document_id、chunk_id、parent_id、source_url、updated_at、acl。
  • Embedding 结果按 chunk hash 缓存。
  • 全文索引和向量索引共享 chunk_id 和过滤字段。
  • 新索引先评测,再通过 alias 发布。
  • 旧索引保留至少一个回滚窗口。
  • 每次发布生成 index manifest 和 eval report。

相关阅读

参考资料

结论

RAG 数据摄取不是离线杂活,而是生产质量的第一道门禁。把解析、清洗、元数据、权限、分块、Embedding、索引发布和回滚做成可观测流水线,后面的检索、生成和评测才有稳定基础。

讨论

继续讨论这篇笔记

有问题、补充案例或不同观点,可以通过 GitHub Discussions 继续交流。

On this page