知识库的维护,越来越多地交给 Agent 来做:清理过期的活动说明,删掉被新版本替代的规则,整理重复上传的文件。这类工作通常在没人盯着的时候批量进行,而 Agent 是会犯错的(ps:AI是人工智能,人会错 AI 也会错):选错一个编号,或者一个循环的条件写错,就可能删掉一篇还在用的文档。
删错了,存储不会报错。Agent 会继续工作,只是之后的回答都会缺失了这一块知识,甚至会被留下来的不完整的信息带偏。这时候要的不是整库回滚到昨晚的备份,因为那会把这一天里其他正常的写入一起退回去;要的是把删错的那一篇单独找回来(ps:DBA们是不是很熟悉,对就是类似于 Oracle“Flashback 闪回”的能力)。
AI Agent 误删了知识库里的文档,会发生什么
这里,我们拿一个客服知识库举个例子。命名空间里有 5 篇文档,其中两篇都叫退款规则:现行的一篇写「银行卡 3 到 5 个工作日到账」。2024 年的旧版写「一般 7 到 10 个工作日到账」,标题里注明了已停用。
文档写入之后,每一篇都有一个文档编号。列出命名空间里的文档,就能看到编号和文件名的对应关系:
documents:
01M6J97AWB0ZGW6JNRRCXYJ1RW 会员积分规则.md
01M6J97BDFSWW60QV9A9EC7Z32 发票开具说明.md
01M6J97BYSYCEH1CP5TMJ2CBAK 退款规则-2024旧版.md
01M6J97CG3JE4Y0ED1RQ90MBWJ 退款规则.md
01M6J97D1BB0RE4M97ZPXZCPQB 配送时效.md
删除之前,问「退款多久能到账」,现行规则排第一,旧版排第二:
before the delete:
1 退款规则.md rerank_score=0.9577 退款多久到账:款项原路退回,银行卡 3 到 5 个工作日到账,余额支付即时到账。超过 30 ...
2 退款规则-2024旧版.md rerank_score=0.8614 用户申请退款后,款项原路退回,一般 7 到 10 个工作日到账。超过 15 天的订单不支持退款。
3 配送时效.md rerank_score=0.0291 同城订单当日达,跨省订单一般 2 到 4 天送达,偏远地区可能延长到 7 天。
然后,模拟 Agent 误删了 0.9577 的现行规则「退款规则.md」。再查一次,结果变成了这样:
DELETE /documents/01M6J97CG3JE4Y0ED1RQ90MBWJ -> 204
after the delete:
1 退款规则-2024旧版.md rerank_score=0.8614 用户申请退款后,款项原路退回,一般 7 到 10 个工作日到账。超过 15 天的订单不支持退款。
2 配送时效.md rerank_score=0.0291 同城订单当日达,跨省订单一般 2 到 4 天送达,偏远地区可能延长到 7 天。
3 发票开具说明.md rerank_score=0.0249 订单完成后 90 天内可以在订单详情页申请电子发票,抬头和税号提交后不能修改。
现行规则不见了,排在第一的是一条已经停用的规则。对接的客服 Agent 拿到这个结果,会很自然地告诉用户「7 到 10 个工作日」。
Cortrix 软删除:误删的文档 30 天内按编号恢复
在 Cortrix 里,DELETE /api/v1/documents/{id}?namespace={ns} 不会马上把数据清掉,而是做一次软删除:
- 文档被标记为已删除,并记下删除的时间。从这一刻起,查询、文档列表和按编号读取都看不到它。
- 它的数据块、向量和原始文件都还留在磁盘上,所以找回之后不需要重新解析和计算向量。
- 默认保留 30 天(配置项
gc.soft_delete_retention_days)。后台每 24 小时清理一次,过了保留期的才被清除。
在保留期内,用 POST /api/v1/gc/restore 按文档编号找回。要传的编号,就是上面文档列表里「退款规则.md」那一行的 01M6J97CG3JE4Y0ED1RQ90MBWJ。一次可以传多个编号,结果按篇返回。为了看清这一点,我们在同一次调用里多传了一个编号:把同一个编号的最后一位 J 改成 X,模拟 Agent 抄错了编号:
restore 01M6J97CG3JE4Y0ED1RQ90MBWJ and 01M6J97CG3JE4Y0ED1RQ90MBWX:
succeeded 01M6J97CG3JE4Y0ED1RQ90MBWJ
failed 01M6J97CG3JE4Y0ED1RQ90MBWX CX_ERR_GC_DOC_NOT_FOUND retryable=false
no deleted document with this id
coverage_ratio=0.5
现行的退款规则找回来了,抄错的那个编号单独列在 failed 里,并且标明不可重试。这和系列第 1 篇讲的部分成功是同一个约定:HTTP 状态码是 200,Agent 要看 coverage_ratio 和 failed,才知道哪几篇没有找回、为什么。再查一次:
after the restore:
1 退款规则.md rerank_score=0.9577 退款多久到账:款项原路退回,银行卡 3 到 5 个工作日到账,余额支付即时到账。超过 30 ...
2 退款规则-2024旧版.md rerank_score=0.8614 用户申请退款后,款项原路退回,一般 7 到 10 个工作日到账。超过 15 天的订单不支持退款。
3 配送时效.md rerank_score=0.0291 同城订单当日达,跨省订单一般 2 到 4 天送达,偏远地区可能延长到 7 天。
排序和分数都和删除之前一样,因为软删除只是给文档打了删除标记,数据块和向量原封不动,30 天内可以把标记撤掉。

图 1|删除先是软删除,30 天内按编号找回;清除要显式确认。
要让软删除的文档不能再被找回,我们提供两个接口:POST /api/v1/gc/run 清理已过保留期的文档,POST /api/v1/gc/purge 不等保留期,立即清除所有软删除的文档。两个都要求管理员权限,且必须带上请求头 X-Ops-Confirm: true。例如确定不再需要 2024 年的旧版,先删除,再清除:
DELETE /documents/01M6J97BYSYCEH1CP5TMJ2CBAK (退款规则-2024旧版.md) -> 204
POST /gc/purge without X-Ops-Confirm -> 400 CX_ERR_OPS_CONFIRM_REQUIRED
POST /gc/purge with X-Ops-Confirm: true -> 202
restore 01M6J97BYSYCEH1CP5TMJ2CBAK:
failed 01M6J97BYSYCEH1CP5TMJ2CBAK CX_ERR_GC_DOC_NOT_FOUND retryable=false
no deleted document with this id
coverage_ratio=0.0
不带确认头的清除直接被拒绝;带上之后,旧版被清除,再找回就只会得到 CX_ERR_GC_DOC_NOT_FOUND。
还有一种删除,是 Agent 自己往往意识不到的:用文件上传接口 POST /api/v1/namespaces/{ns}/documents 传了一个同名、内容有改动的文件。Cortrix 会把它当成新版本,上传的响应里用 superseded_doc_id 告诉调用方被替代的是哪个编号;新版本处理完成的那一刻,旧版本被软删除。如果这时候想把旧版本找回来,Cortrix 不会让两个版本同时生效,而是在 message 里写明下一步(这一段的输出来自仓库里的英文示例):
upload refund-policy.md again: doc_id=01M6J97GKED58ZS15BANHEGVMT superseded_doc_id=01M6J97G0Q56CJKB2HNR03DXKK
restore the first version 01M6J97G0Q56CJKB2HNR03DXKK:
CX_ERR_GC_RESTORE_SUPERSEDED
another version is live: delete 01M6J97GKED58ZS15BANHEGVMT in namespace new-version-1793762508, then restore 01M6J97G0Q56CJKB2HNR03DXKK
DELETE /documents/01M6J97GKED58ZS15BANHEGVMT -> 204
restore 01M6J97G0Q56CJKB2HNR03DXKK again: succeeded=['01M6J97G0Q56CJKB2HNR03DXKK'] coverage_ratio=1.0
Agent 照着先删新版本、再找回旧版本就可以,不需要人在中间解释。新版本的编号和命名空间也放在返回的 structured_data 里,Agent 不用解析这句话。
向量数据库怎么恢复误删:Pinecone、Qdrant、LanceDB 的备份、快照和版本
Cortrix 保留期挂在每一篇被删除的文档上,找回也按篇进行,同一个命名空间里其他正常的写入不受影响。这样恢复的粒度更细,也更灵活。业界也有一些产品,恢复的单位会按索引、集合或者整张表来处理。
Pinecone 的备份是整个 serverless 索引的拷贝,恢复的方式是用备份新建一个索引。

图 2|Pinecone 文档里从备份恢复索引的做法,截于 2026-11-03。见参考资料 [1]、[7]
Qdrant 从快照恢复一个集合时,会覆盖节点上这个集合现有的数据。

图 3|Qdrant 接口文档里从快照恢复集合的说明,截于 2026-11-03。见参考资料 [2]
LanceDB 用的是版本:表有版本,删除也会生成一个新版本,可以打开删除之前的版本,也可以把整张表回滚过去。旧版本在运行 optimize() 时按保留设置清理,默认保留 7 天。

图 4|LanceDB 文档里回滚到之前版本的说明,截于 2026-11-03。见参考资料 [3]
给 Agent 建议:记编号、分权限、慎用清除
- 删除之前,把文档编号和文件名记进 Agent 自己的操作记录。找回按编号进行,删掉之后的文档在列表里是看不到的。
- 找回需要管理员权限。开启认证后,给 Agent 一把只有读写权限的密钥(在配置文件的
auth.api_keys里写permissions: 3)。它可以删除,调用找回会得到 403 和ADMIN permission required。比较稳妥的分工是:Agent 只管删,删错了交给持有管理员密钥的人或流程来找回。 - 清除作用于整个服务:
/gc/purge会清掉所有命名空间里软删除的文档,不只是你刚删的那一篇。还有文档等着找回的时候,不要调用它。 - 通过目录监听导入的文档,跟着源文件走。文件从被监听的目录里删掉,对应的文档会直接删除,不进 30 天的窗口;要找回,从源目录恢复文件。
- 删除时还没处理完的文档,找回会返回
CX_ERR_GC_RESTORE_INCOMPLETE,按提示重新提交原文件。
常见问题
Cortrix 里删除的文档还能恢复吗?
能。在 Cortrix 里通过接口删除文档是软删除,默认保留 30 天。这期间用 POST /api/v1/gc/restore 传入文档编号,就能把文档找回来,数据块和向量都还在,不需要重新入库。
删除之后,文档还会出现在检索结果里吗?
不会。软删除之后,查询、文档列表和按编号读取都看不到这篇文档,直到它被找回。
怎么清除一篇文档,让它不能再找回?
先删除,再调用 POST /api/v1/gc/purge,并带上请求头 X-Ops-Confirm: true。清除不可撤销,作用于整个服务上所有软删除的文档,需要管理员权限。也可以等保留期过后,由后台每天一次的清理自动清除。
和向量数据库的备份、快照有什么不同?
备份和快照恢复的是整个索引、集合或表,会把恢复点之后的其他写入一起退回去,或者要新建一个索引。Cortrix 按文档找回,只恢复删错的那一篇。
系列导航
- 第 1 篇:返回 HTTP 200,可能只成功了一半。一次查询只查到一部分时,存储要说清缺了什么。
- 第 2 篇:写到一半被 kill -9,重启后数据自己对齐。写入中途崩溃,存储自己清掉写了一半的数据。
- 第 3 篇,就是本文:Agent 误删了文档,30 天内按编号找回来。
本文的两个实验,我们都放进了 Cortrix 仓库的 examples/delete-restore。按目录里的说明从 main 构建并启动 Cortrix,就能自己跑一遍:
python examples/delete-restore/delete_restore.py
python examples/delete-restore/new_version.py
delete_restore.py 加上 --purge,就会多跑一遍上面清除的那一段。清除会清掉服务上所有软删除的文档,只在没有别的文档等着找回的服务上用。
仓库里的示例用的是英文文档,步骤和输出的格式与本文相同。如果它帮你省下了自己做软删除和回收站的时间,欢迎到 GitHub 给 Cortrix 点一个 Star。
参考资料
- [1] Pinecone Docs, Restore an index:https://docs.pinecone.io/guides/manage-data/restore-an-index
- [2] Qdrant API Reference, Recover from a snapshot:https://api.qdrant.tech/api-reference/snapshots/recover-from-snapshot
- [3] LanceDB Docs, Versioning:https://docs.lancedb.com/tables/versioning
- [4] Cortrix GitHub 仓库:https://github.com/cortrix/cortrix
- [5] Cortrix 接口规范,文档删除和找回:https://github.com/cortrix/cortrix/blob/main/api/paths/ops.yaml
- [6] 本文的实验代码,examples/delete-restore:https://github.com/cortrix/cortrix/tree/main/examples/delete-restore
- [7] Pinecone Docs, Backups overview:https://docs.pinecone.io/guides/manage-data/backups-overview
本文的命令和输出来自 Cortrix main 分支提交 0d8d2b8 的构建,只用 CPU,没有配置 LLM。