RAG知识库更新选全量重建、增量索引还是CDC?三种方案完整选型

文章摘要

RAG知识库上线后,文档、商品、制度、工单和数据库数据都会持续变化。全量重建实现简单但成本高,增量索引效率更高但版本与删除治理复杂,CDC可以接近实时同步,却会引入事件顺序、幂等、事务和回放问题。本文从数据规模、更新频率、一致性、成本、恢复能力和实施复杂度出发,比较三种更新架构,并给出企业项目的组合选型建议。

一、为什么更新架构比首次入库更难

首次建设RAG时,数据链路通常是:

全部文档
→ 解析
→ 分块
→ Embedding
→ 写入向量库

上线后,数据开始变化:

  • 新增文件;
  • 修改制度;
  • 删除合同;
  • 商品信息调整;
  • 权限变化;
  • 数据库记录更新;
  • 文档生效和失效;
  • 多语言版本发布。

此时需要回答:

哪些内容发生变化
哪些Chunk需要重算
旧内容何时失效
删除如何传播
失败后从哪里恢复
线上是否允许短暂不一致

二、方案一:全量重建

流程:

读取全部数据
→ 重新解析
→ 重新分块
→ 全部Embedding
→ 建立新索引
→ 切换生产别名

优点

  • 实现最简单;
  • 最容易保证最终一致;
  • 不需要复杂的变更识别;
  • 可以清理历史脏数据;
  • 适合更换Embedding模型;
  • 便于重构Chunk策略。

缺点

  • Embedding成本高;
  • 构建时间长;
  • 数据量越大越难频繁执行;
  • 可能产生大量重复计算;
  • 切换和回滚需要双索引空间。

适合场景

  • 数据量较小;
  • 更新频率低;
  • 每天或每周离线同步;
  • 经常调整解析与分块策略;
  • 需要更换Embedding模型;
  • 初期项目优先保证简单可靠。

三、全量重建不要覆盖生产索引

错误做法:

清空生产Collection
→ 开始重新写入

构建期间,用户只能检索到部分数据。

推荐蓝绿索引:

knowledge_blue:当前生产
knowledge_green:正在构建

构建完成后:

完整性校验
→ 回归测试
→ 切换Alias
→ 保留旧索引用于回滚

逻辑:

knowledge_current
→ knowledge_green

切换后观察稳定,再删除旧索引。

四、方案二:增量索引

增量索引只处理变化内容。

流程:

发现新增、修改、删除
→ 计算差异
→ 更新对应Chunk
→ 修改版本和状态

优点

  • 成本低;
  • 同步速度快;
  • 对大规模知识库更友好;
  • 减少重复Embedding;
  • 可频繁执行。

缺点

  • 差异识别复杂;
  • 删除容易遗漏;
  • Chunk边界变化会扩大更新范围;
  • 新旧版本切换需要状态机;
  • 长期运行可能积累脏数据。

适合场景

  • 文档数量较多;
  • 每天有持续变化;
  • 需要小时级更新;
  • 数据来源有稳定ID和更新时间;
  • 有能力建设版本、幂等和补偿机制。

五、增量索引如何识别变化

文档级Hash

文件内容Hash变化
→ 重新处理整个文档

Chunk级Hash

同一章节内容未变化
→ 复用旧向量

内容变化
→ 重新Embedding

更新时间

SELECT *
FROM product
WHERE updated_at > :last_sync_time;

单靠updated_at存在问题:

  • 时钟偏差;
  • 批量回填;
  • 事务未提交;
  • 同一时间多条记录;
  • 删除记录无法查询。

更可靠的是:

稳定主键
+版本号
+内容Hash
+删除标记

六、方案三:CDC事件驱动更新

CDC是Change Data Capture,即捕获数据库的新增、修改和删除事件。

链路:

业务数据库
→ Binlog/WAL
→ CDC平台
→ 消息队列
→ RAG索引消费者
→ 向量数据库

常见工具包括:

  • Debezium;
  • Kafka Connect;
  • Flink CDC;
  • 云数据库变更流;
  • 自研Outbox事件。

优点

  • 接近实时;
  • 能捕获删除;
  • 不需要频繁扫描整库;
  • 适合结构化业务数据;
  • 事件可重放。

缺点

  • 基础设施复杂;
  • 事件可能重复;
  • 顺序和事务边界难处理;
  • 大批量更新可能冲击Embedding服务;
  • Schema变更需要兼容;
  • 失败补偿和积压治理要求高。

七、CDC不应该直接调用Embedding

错误链路:

收到数据库事件
→ 同步调用Embedding
→ 写向量库

如果Embedding限流,CDC消费就会阻塞。

推荐:

CDC事件
→ 标准化变更任务
→ 任务队列
→ 批量聚合
→ Embedding Worker
→ 向量写入

任务示例:

{
  "event_id": "EVT-10001",
  "entity_type": "PRODUCT",
  "entity_id": "P1008",
  "operation": "UPDATE",
  "version": 18,
  "occurred_at": "2026-07-24T02:30:00Z"
}

八、事件幂等与顺序

可能先收到:

version=18

后收到延迟事件:

version=17

如果不校验版本,旧数据会覆盖新数据。

写入规则:

incoming_version > stored_version
→ 允许更新

incoming_version <= stored_version
→ 忽略

事件ID还应去重:

processed_event_id

九、删除如何处理

全量重建

新索引里不存在的内容自然消失。

增量索引

需要显式:

删除向量
或标记DELETED

CDC

必须消费DELETE事件。

若业务表使用软删除:

is_deleted = true

也应转成RAG删除任务。

删除传播延迟应单独监控,因为它直接影响隐私和权限风险。

十、三种方案对比

维度 全量重建 增量索引 CDC
实现复杂度
更新延迟 小时或天 分钟或小时 秒到分钟
Embedding成本
删除处理 简单 需显式处理 事件驱动
一致性治理 简单 中等 复杂
故障恢复 重跑全量 重跑任务 回放事件
适合数据量 小到中 中到大 大规模实时

十一、企业项目通常采用组合方案

推荐:

日常:增量或CDC
定期:全量重建校准

例如:

实时CDC同步商品与订单
每小时增量同步文档
每周全量一致性校验
每月蓝绿重建索引

全量重建可以消除长期积累的:

  • 漏删;
  • 重复;
  • 错误版本;
  • Payload漂移;
  • 历史任务失败。

十二、如何选择

选择全量重建

满足大部分条件:

数据量小于可接受范围
更新不频繁
成本可控
团队希望降低复杂度

选择增量索引

文档较多
小时级更新即可
来源有稳定ID
需要控制Embedding成本

选择CDC

数据来自业务数据库
要求接近实时
更新和删除频繁
已经具备消息与CDC基础设施

十三、必须统一的元数据

不管选择哪种方式,都应记录:

source_id
logical_document_id
source_version
content_hash
chunk_hash
index_version
embedding_model
status
updated_at

否则无法判断:

  • 当前向量来自哪个版本;
  • 是否应该更新;
  • 是否能够回滚;
  • 引用是否过期。

十四、上线前的故障演练

至少演练:

  • Embedding限流;
  • 向量库超时;
  • 任务重复投递;
  • 删除事件丢失;
  • 旧事件晚到;
  • 索引切换失败;
  • 新版本质量不合格;
  • 消息积压;
  • 数据库Schema变化。

十五、核心指标

source_to_index_latency
pending_index_task_count
failed_index_task_count
duplicate_event_count
stale_event_count
delete_propagation_latency
index_consistency_rate
embedding_reuse_rate
full_rebuild_duration

总结

三种方案没有绝对优劣:

全量重建
→ 简单和最终一致

增量索引
→ 成本与复杂度平衡

CDC
→ 实时,但工程要求最高

多数企业RAG的稳妥方案是:日常使用增量或CDC,定期通过蓝绿全量重建校准数据和索引状态。

延伸阅读

如果你正在关注企业级 AI 应用、RAG、Agent、MCP 与大模型工程化落地,欢迎访问 智元界

https://www.zyentor.com/

智元界将持续分享可运行的技术实战、架构设计、问题排查与企业应用案例。