怎么考「知识库更新了,向量索引怎么增量更新?删除的文档怎么办?

Q2-23索引运维常见

谁在问:工程向二面;运维过线上知识库的面试官必问

开场怎么问

文档改了之后,你们怎么同步到索引里?

换个问法

  • 删掉的文档还能被检索出来吗?
  • 更新的时候会不会出现检索不到的空窗期?

五层追问链

左边照着问,右边对着听。最后一层是压力面,不必每个候选人都问到。

怎么知道哪些文档需要更新?

期望
上游变更检测——文件哈希/mtime 比对、业务系统的变更事件(CDC、消息队列)、定时全量扫描做兜底对账。理想是事件驱动 + 定期对账双保险,因为事件可能丢。
信号
只说「定时全量重跑」的,没做过成本优化;能提「事件驱动 + 对账兜底」的,是做过数据同步的。

一个文档改了一句话,要重算整个文档的向量吗?

期望
不用——做 chunk 级哈希对比,只重算内容变化的 chunk。但要注意边界效应:如果分块是按语义或滑动窗口切的,改一句话可能导致后续所有 chunk 的边界偏移,那就只能整篇重切。按结构(标题)切分的文档在这方面稳定得多,这是结构感知切分的一个隐藏好处。
信号
能想到「边界偏移」这个细节的,是真做过增量更新。

软删除积累多了具体会怎样?怎么监控?

期望
图连通性劣化 → 召回率下降、查询变慢;存储不释放。监控手段:跟踪软删除占比(比如超过 20–30% 触发告警)、定期在评测集上跑 recall 看有没有缓慢下滑。处理:定期 compact 或在低峰期重建。关键是这种劣化是渐进无声的,不主动监控发现不了。
信号
能说出「渐进劣化、需要主动监控」的,运维过真实系统。

更新过程中用户正好在查询,会读到不一致的数据吗?

期望
会——比如新 chunk 写了一半,用户检索到了新旧混合的内容。解法:版本号过滤(用户只看到完整的某一版本);或者用别名/指针切换(新版本全部就绪后原子切换指针);pgvector 这类支持事务的库可以直接用事务保证。这也是 pgvector 的一个真实优势场景
信号
能把这题连回「向量库选型时事务一致性为什么重要」的,知识成体系。

客户要求「文档删除后 5 分钟内不能再被检索到」,你怎么保证?

期望
分层设计——① 检索层用元数据黑名单立即过滤(不依赖向量库的物理删除,秒级生效);② 缓存层同步失效(语义缓存、答案缓存都要清);③ 物理删除异步执行;④ 加一条验证机制:删除后自动跑一次针对该文档的检索测试,确认返回为空,并记录审计日志。给出可验证的保证,而不只是「我们会删掉」。
信号
只答「调用删除接口」的,不理解软删除的存在;能提出「元数据黑名单立即生效 + 缓存失效 + 删除后验证」的,是能扛合规要求的方案。

危险信号

听到这些话,基本可以判定是背题而不是做过。

「每天定时全量重建一次」——小规模能跑,量一大就崩,且成本浪费严重。
认为向量库的删除是即时物理删除。
没有版本控制,先删后插导致检索空窗。
完全不考虑缓存里的旧答案。
意识不到删除在业务上往往意味着合规要求,而不只是省空间。

评分卡

  1. 知道更新 = 删旧 + 插新,且要保证向量与原文对齐
  2. 知道向量库多为软删除,空间不立即释放
  3. 知道软删除积累会导致召回下降,需要 compact 或重建
  4. 能给出避免更新空窗的方案(版本号/时间戳过滤)
  5. 有变更检测机制,不是每次全量重跑
  6. 加分:意识到删除的合规维度(缓存失效、审计)
  7. 加分:知道全量重建的触发条件和双索引灰度切换
  8. 加分:知道分块策略会影响增量更新的成本(边界偏移)
参考答案与考察意图面试中途别看这一段

考察意图

这题问的是「上过线」而不是「跑通过」。 demo 阶段的 RAG 全量重建就行,一旦真跑在业务上,文档天天变、旧内容必须立刻失效、更新期间不能停服——这些问题一个都躲不掉。三个观察点:① 知不知道向量库的删除是软删除;② 有没有更新期间的一致性方案;③ 有没有意识到「答案引用了已删除的文档」是合规风险。

参考答案

图 2 · 60 分与 90 分差在哪:代价、演进、怎么验证

60

60 分答案(及格线)

新增:直接 upsert,HNSW 支持增量插入。 更新:本质是删旧 + 插新。要注意向量和原文的对齐,否则会出现「检索到了但取不到原文」。 删除:多数向量库是软删除——图结构不好真删,一般打标记跳过,空间不会立刻释放。删除比例高了会让图结构劣化、召回下降,需要定期 compact 或重建索引。

实践上常用 文档ID + chunk序号 作为稳定主键,更新时按文档 ID 批量删除旧 chunk 再写入新 chunk。

90

90 分答案(有生产经验的回答)

补四层:

用版本号避免更新空窗(关键):如果先删后插,中间那段时间用户检索不到内容。正确做法是给每个 chunk 打版本号或时间戳作为元数据:先写入新版本,检索时按元数据过滤只取最新版本,再异步清理旧版本。这样任何时刻都有一份完整可用的数据。

变更检测要做在上游:不要每次全量重跑。用文件哈希或修改时间判断哪些文档真的变了;文档内变更还可以做 chunk 级别的哈希对比,只重算变化的那几块——这能把日常更新的 embedding 成本降一个数量级

删除的合规维度(很多人漏):文档被删除通常意味着「这份内容不该再被引用」——可能是过期政策、下架产品、甚至是隐私删除请求。所以软删除不够,要确保:① 检索层立即过滤掉(元数据标记,不等 compact);② 已生成的缓存答案要失效;③ 有审计记录。在 toB 场景,「答案引用了一份已删除的文件」是事故不是瑕疵。

什么时候必须全量重建:换 embedding 模型、改分块策略、改索引参数(M/ef_construction)、软删除比例过高导致召回劣化。重建时用双索引 + 灰度切换:新索引在旁边建好,验证召回率不低于旧索引后再切读流量,保留旧索引一段时间以便回滚。

攒够了去组卷页一键生成可打印的面试题单