首页/AI/RAG 与向量库速查/增量索引与文档更新

增量索引与文档更新

文档变更时按 doc_id 删除旧切片、写入新切片,用稳定主键保证幂等;更新链路要覆盖新增、修改、删除三类事件与相关缓存失效。

RAG 与向量库速查AI更新于 2026-10-13

增量索引是什么

增量索引指文档发生变更时不整体重建库,而是按文档粒度定点更新:先按稳定的 doc_id 删除该文档的旧片段,再写入重新切分与向量化的新片段。核心要求是幂等——同一份文档重复执行结果一致,靠稳定的 chunk_id 覆盖实现。更新链路必须覆盖新增、修改、删除三类事件,并在更新后同步失效相关缓存,否则用户还会拿到旧答案。

基本信息

主键设计doc_id + 序号生成稳定 chunk_id,不用随机值
三类事件新增(直接写入)、修改(先删后写)、删除(只删)
删除方式按元数据表达式或 filter 删除
幂等保证chunk_id 固定,重复执行覆盖同一批记录
配套动作缓存失效、统计刷新、评测集回归

典型使用场景

  • 制度或手册改版:只重跑受影响文档,避免全库重灌的算力开销
  • 每日增量同步:从源系统拉取变更清单,逐条执行删旧写新
  • 权限或密级变更:更新元数据字段,使过滤条件立即生效
  • 误入库内容回滚:按 doc_id 精确删除,不影响其它文档
  • 灰度验证:新版本片段先写入影子集合,评测通过再切流

按文档删除旧片段

按文档删除旧片段
# Milvus:按元数据表达式删除
client.delete(collection_name='docs', filter='doc_id == "hr-policy"')

# Qdrant:按过滤条件删除
from qdrant_client import models
client.delete(
    collection_name='docs',
    points_selector=models.FilterSelector(filter=models.Filter(
        must=[models.FieldCondition(key='doc_id',
                                    match=models.MatchValue(value='hr-policy'))])),
)

再写入新版本

再写入新版本
chunks, vecs = build_chunks(new_text, meta={'doc_id': 'hr-policy',
                                          'doc_version': '2026-10-01'})
store.upsert(chunks, vecs)      # 同一 chunk_id 覆盖,重复执行结果一致
invalidate_cache(doc_id='hr-policy')   # 顺带失效语义缓存与答案缓存

更新事件处理对照

事件动作易漏点
新增文档切分、向量化、写入忘记写版本号与生效日期
内容修改删旧片段再写新片段只写不删,新旧内容同时被召回
文档删除按 doc_id 删除全部片段删除异步生效,未验证就宣布完成
元数据变更覆盖 payload 或标量字段缓存未失效,仍返回旧权限答案
批量更新建议按文档为单位提交,并在流水线中记录每份文档的处理状态与版本,重跑时跳过已完成部分;出现失败可定向补齐而不必全量重来。

易错点

  • 个别系统的删除是异步生效,删完要实际检索验证确实查不到,否则新旧内容并存
  • chunk_id 用随机值导致每次更新都堆积旧数据,向量库迅速膨胀
  • 只处理新增不处理删除,被废止的条款还会被检索并当成现行规定
  • 更新向量库后没有失效语义缓存,用户仍拿到旧答案且报表显示“已更新”
  • 按整库重建应对单文档变更,算力与时延成本被无谓放大

数据来源与参考

  • Milvus 官方文档(删除与 Upsert)
  • Qdrant 官方文档(过滤删除)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌