增量索引是什么
增量索引指文档发生变更时不整体重建库,而是按文档粒度定点更新:先按稳定的 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 或标量字段 | 缓存未失效,仍返回旧权限答案 |
批量更新建议按文档为单位提交,并在流水线中记录每份文档的处理状态与版本,重跑时跳过已完成部分;出现失败可定向补齐而不必全量重来。