为什么要版本管理
知识库里的文档会更新、下架、换版,切片却是按内容生成的静态副本。给每个切片带上 doc_id 与 doc_version,更新时按 doc_id 删除旧切片再写入新切片,就能避免同一个问题同时召回到新旧两版内容。定期全量重建用于清理历史残留与碎片,保证索引与源文档一致。
基本信息
| 核心字段 | doc_id(文档身份)、doc_version(版本号或时间戳) |
|---|---|
| 更新动作 | 先删后写,或写新集合后切流量 |
| 清理策略 | 按周期全量重建 + 删除标记扫描 |
| 风险等级 | 删除与写入之间没有过渡会造成文档在索引里暂时消失 |
典型使用场景
- 制度与手册改版:旧版必须下架,检索只命中现行版本
- 产品文档迭代:同一页面频繁更新,需要按版本号覆盖旧切片
- 文档下架:源文件被移除时同步清理索引,避免回答已废止内容
- 排障回溯:回答质量异常时确认索引由哪一版文档生成
- 灰度重建:新切分策略先在影子集验证,再整体切换
替换流程
替换流程
def reindex(doc):
# 1) 用固定 doc_id + 新版本号重建切片,id 可复现
new_chunks = build_chunks(doc.text, meta={"doc_id": doc.id,
"doc_version": doc.version})
store.delete(filter={"doc_id": doc.id}) # 2) 删旧版本切片
store.upsert(new_chunks, embed_batch(new_chunks)) # 3) 写新版本切片
report(doc.id, old=old_count, new=len(new_chunks)) # 4) 记录差异供核对
# 写入失败时按 doc_id 重跑整个函数;幂等前提是切片 id 由内容派生元数据字段清单
| 字段 | 作用 | 缺失后果 |
|---|---|---|
| doc_id | 同一文档所有版本的公共标识 | 无法定位并批量替换旧切片 |
| doc_version | 时效排序与版本展示的依据 | 新旧内容混答且无法区分 |
| chunk_index | 切片在原文中的顺序 | 引用回原文时顺序错乱 |
| status | active 与 deprecated 生命周期标记 | 已废止文档仍被检索命中 |
重建要可回滚:写入新集合或新分区,验证通过再切流量,出问题切回旧索引,避免就地覆盖后没有退路。
删除与写入放进同一个幂等任务,中途失败重跑不会产生重复切片;任务日志里要能查到每次删除的切片数量。