RAG 知识库文档如何更新:增量更新、版本控制、去重与全量重建
RAG 上线后常遇到一个怪象:文档明明改了,回答还是老样子。问题通常不在 LLM,而在更新链路只做了”写新”,没处理旧版本清理、删除传播与多索引一致性。本文按新增、修改、删除三类事件,讲清增量索引设计、过期策略、版本对齐与热更新的工程做法。
更新要解决什么
知识库是活数据,更新链路要同时满足四个目标:及时性,文档变更后在业务可接受的窗口内同步到索引(制度库一天一次也许够,客服场景可能要分钟级);准确性,召回内容必须与当前版本一致,不能文档改到第五版、模型还引用第一版;一致性,向量库、元数据库、全文索引是三个独立系统,任何一端漏写都会出现”幽灵数据”;可回滚,出问题时能快速切回上一个健康状态。
增量索引设计:文档级版本管理
增量更新的前提是元数据能回答”这条向量属于哪篇文档、哪个版本、是否有效”。每个 Chunk 至少应携带:
doc_id 文档标识 |
content_hash 是去重与增量判定的核心:入库前算哈希,与已有记录一致就跳过 Embedding,不一致才重新编码。注意存完整哈希,避免前缀碰撞。
三类事件的同步方式:
- 新增:解析、切分、算哈希、查重后写三端。写入必须幂等——消息重复投递、worker 崩溃重跑都不该产生重复记录,用
doc_id + version_id + content_hash做唯一约束。 - 修改:稳妥做法是”先建后切”——新版本以
status = building写入但不参与检索,三端写成功后原子切换活动版本,旧版本异步清理。只写新向量不删旧向量是最常见的坑:文档改 10 次,库里就躺着 10 个可召回版本。 - 删除:见下节。
变更检测有三种来源:源系统 Webhook(延迟最低,依赖源系统支持)、CDC 监听数据库日志(适合结构化数据源)、定时轮询比对 updated_at(简单但有延迟)。生产推荐事件驱动加轮询兜底,中间用消息队列解耦,并按 doc_id 分区保证同一文档的事件有序消费。
删除与过期策略
删除分两层:
- 软删除:
is_deleted置为 true,查询侧默认过滤,可审计、可恢复,也给跨索引同步留了缓冲窗口。 - 物理删除:从向量库、元数据库、全文索引及缓存中真正移除。合规删除、敏感数据必须走到这一步,还要顺手清理 rerank、LLM 上下文等旁路缓存。常见组合是软删除 + 延迟物理删除 + 审计日志,保留时长按数据分类与合规要求定。
删除必须三端一致传播:只删向量库不删全文索引,混合检索照样把旧内容捞出来。另一个隐蔽场景是权限变更产生的幽灵数据:文档从”全员可见”改为”仅高管可见”,索引里的 acl 不更新,普通员工仍能召回——权限变更应触发该文档的元数据刷新或重建索引。
更新一致性:索引与源文档的版本对齐
向量库、元数据库、全文索引不在同一事务域,一次写三端必然存在部分成功的可能。解法有四:
- 以元数据库为准:记录每个 Chunk 的索引状态(
pending / ready / partial_failed),作为 source of truth。 - 补偿任务:后台定时扫描失败状态记录并重试;向量写入按
chunk_id幂等 upsert,重复执行不会产生多份。 - 对账(Reconciliation):周期性比对源系统与索引的文档数、哈希、
updated_at,漏写、漏删、乱序及时修复或告警。 - 乱序防护:事件携带版本号,写入前校验
event.version >= current_version,旧事件丢弃并打点监控。
热更新对在线服务的影响
日常增量更新对在线服务影响很小,真正的风险在两类”大动作”:
- Embedding 模型升级:不同模型的向量空间不通用,历史数据必须全部重嵌。做法类似蓝绿部署:新模型建一套全新索引,与旧索引并行运行、对比召回质量,稳定后通过索引别名切流,旧索引留一段时间用于回滚。切记把模型名称与版本写进元数据并在查询时校验,防止测试用本地模型、生产用 API 模型这种”看着正常、上线腰斩”的混用。
- 切分策略变更:从固定长度改语义切分,影响不亚于换模型。要么全量重建,要么策略版本化后逐批迁移,绝不能两套策略无标记混用。
全量重建期间服务不能停:查询侧始终通过别名访问,后台重建新索引,验证通过后切别名,旧索引留作快照。灾难恢复同样依赖快照与重建脚本,避免索引损坏无退路。
面试视角
文档更新后用户仍搜到旧答案,怎么排查? 沿链路查:变更事件有没有发出 → 消费是否成功(重试与死信队列)→ 旧版本是否被停用(只写新不删旧的坑)→ 三端与缓存是否一致 → 元数据 updated_at 与源系统是否对齐。
增量更新和全量重建怎么分工? 增量负责日常变更,成本低、延迟小;全量重建留给 Embedding 模型升级、切分策略迁移、严重数据不一致这几种硬场景。
删除一篇敏感文档要注意什么? 三端同步删,旁路缓存也要清;先软删标记,再按合规要求延迟物理删除,全程留审计日志。
小结
- 更新链路的目标是让检索结果与当前文档一致且可回滚,不只是”把新内容写进去”。
- 文档级版本管理(
doc_id、version_id、content_hash、is_deleted)是增量索引、去重与回滚的地基。 - 修改用”先建后切”避免空窗与新旧混召;删除三端一致传播,权限变更也要刷新索引。
- 元数据库作为 source of truth,加补偿任务与定期对账,兜住多系统写入的部分失败。
- 模型升级与策略变更走新索引加别名切换,热更新不中断在线服务、可回滚。

