答得出处

坐下 2 / 5

源文件删了,chunk 还在,回答仍会引用它。

一份差旅制度进过索引。法务说作废。磁盘上的 PDF 被拿走了。客服第二天还问到「住宿 450」——那一截 chunk 活着,parent 指着一个已经不存在的文件。删除若只发生在网盘,检索层不知道。进索引的每一截都必须能指回父亲,否则你删不干净。

四个身份要一起走

文档 id:业务对象,例如 doc:travel-cn。换文件名也不该换这个号。

内容哈希:这一版字节的指纹。哈希变了,就是新版本,不要靠「最后修改时间」独断。

chunk parent:每一截检索单元记下自己从哪份文档、哪一版切出来。没有 parent,你删文档时找不到孩子。

tombstone:一枚「已删除」章,写在文档 id 上。检索、缓存、重放摄取,都要先看这枚章。只删 chunk 不盖章,队列重放会把旧段落写回来。

v1 已在,v2 到了

先算 v2 的哈希。若与 v1 相同,什么都别动。若不同:写入带 parent=doc:travel-cnversion=2 的新 chunk,再删 version=1 的孩子。只加不删,索引里两版同时可被命中,模型会把作废条款和现行条款拼在一段回答里。

乱序事件常见。更旧的更新晚到,不能靠「谁最后写入谁赢」。比较版本号或事件时间,旧的那条丢弃。worker 在写索引前崩溃、队列重投,同一版本可能处理两次——写入要幂等:同一 (doc_id, content_hash, chunk_i) 写两次仍是一条。删除 SLA 用分钟说清:tombstone 后 30 秒内检索应看不到,对账任务每小时扫一遍还活着的 parent。

业务说删

第一步盖 tombstone,让检索立刻滤掉这个 id。第二步删该 id 下全部 chunk。第三步对账:按 doc_id 查索引,应为空。源文件可以从对象存储里收,但它不是开关——开关是 tombstone 和索引。

先删源文件、不盖章、不动 chunk:这就是活引用。先全库重建:窗口以小时计,重建期间旧段落仍回答。重建是灾难恢复,不是日常删除。摄取要记下每次运行处理了哪些 doc_id、成功几条、失败几条。失败隔离:一页 PDF 解析崩了,不要拖死整批。同一文档在网页、PDF、共享盘各有一份时,先定哪一份是权威,其余只做来源记录,否则去重会把不同地区的「最终版」合成一条。

现在要删 docA。v1 的 chunk 还在。

按你要执行的顺序点。可以少点,不要乱点两次。

(还没选)

自己对过

写 tombstone → 删该 doc 的 chunk → 按 doc_id 对账。源文件稍后收。全库重建不在这条短路径上。