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/

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