### 功能描述 目前知识库的文档管理页面只能逐个删除文档。希望增加多选删除功能,方便一次清理多个不再需要的文档。 建议支持: - 勾选多个文档,并支持当前页全选。 - 点击“删除所选文档”后,显示待删除数量并进行二次确认。 - 删除完成后刷新列表和文档数量;如果部分删除失败,提示失败结果,并允许重试。 此前 PR #8630 曾包含文档批量删除功能,但该 PR 已关闭且未合并。本 issue 希望单独讨论和实现这项功能,保持改动范围集中。 ### 使用场景 批量更新知识库资料时,需要先删除一批旧文档;或上传了重复、错误的文件,需要集中清理。逐个点击删除并确认较为繁琐,多选删除可以减少重复操作。 ### 检查清单 - [x] 我已在 Issue 列表中搜索过相关功能,找到曾包含此功能但已关闭的 PR #8630,未找到专门跟踪该功能的 issue。 - [x] 我建议的功能与 AstrBot 本体相关,而非在建议某一插件的功能。 - [x] 我已阅读并同意本项目的贡献者行为准则。 - [x] (可选)我愿意提交 PR 以帮助实现该功能。
Activity
LIghtJUNction commentedon Oct 15, 2026
基于当前默认分支
master@db4ce0c4和关联 PR #10565 的最新提交128b5104做了源码核对。结论是:当前DocumentsTab.vue确实只有单文档删除;#10565 已经覆盖了本 issue 的主体需求,包括当前页选择/全选、二次确认、知识库归属校验、500 个文档 ID 的请求上限、分批清理 chunk,以及上传与删除共用写锁。实现方向基本合理,但合并前建议再收紧两个失败路径,否则“允许重试”的用户可观察语义仍不完全成立。1. FAISS 写盘失败后,磁盘索引被保护了,但进程内索引没有回滚
相关位置:
astrbot/core/db/vec_db/faiss_impl/vec_db.py:FaissVecDB.delete_documents()astrbot/core/db/vec_db/faiss_impl/embedding_storage.py:EmbeddingStorage.delete()、save_index()、_write_index()确认的调用链是:
FaissVecDB.delete_documents()分批调用EmbeddingStorage.delete(..., persist=False)。faiss.Index.remove_ids()会立刻修改self.index。save_index();_write_index()通过临时文件 + replace 保护已有磁盘文件。KBDocument删除,因此元数据仍在,磁盘索引也仍是旧版本;但是当前进程的self.index已经少了这些向量。因此现有“保留索引文件、保留文档记录、可重试”的测试只验证了磁盘和元数据,还缺少运行中检索一致性。建议至少在
save_index()失败时从原索引文件重新加载self.index后再抛出;更完整的做法是对工作索引做 copy-on-write:在副本上删除并成功原子写盘后,再替换活动索引。伪代码可以是:如果考虑大索引复制的内存成本,最小修复也应是捕获写盘异常并立即从未被替换的磁盘文件恢复活动索引;同时需要明确检索是否要与写锁共享读写边界,避免读取到删除过程中的中间状态。
2. 统计刷新失败会把“已删除”误报成“删除失败”
相关位置:
astrbot/core/knowledge_base/kb_helper.py:KBHelper.delete_documents()astrbot/core/knowledge_base/kb_db_sqlite.py:delete_documents_by_ids()、update_kb_stats()astrbot/dashboard/services/knowledge_base_service.py:KnowledgeBaseService.delete_documents()dashboard/src/views/knowledge-base/components/DocumentsTab.vue:deleteSelectedDocuments()这里先完成向量、chunk/FTS、媒体及
KBDocument删除,之后才调用update_kb_stats()。如果只有统计刷新失败,删除已经提交,但异常仍经 API 返回通用失败;前端会显示“批量删除失败”,随后finally又刷新列表,用户会看到文档消失。#10565 的test_statistics_failure_is_retryable_after_content_cleanup已证明后台可通过重试修复计数,但没有覆盖这段相互矛盾的 API/界面反馈。建议让 service 返回分阶段结果,例如
deleted_count、stats_refreshed和可选warning。内容及元数据删除已完成时应报告“删除成功,但统计刷新待修复”,而不是把整批标为失败;只有内容清理尚未完成、元数据仍保留时,才保留失败状态并让当前选择可重试。这样也能准确覆盖 issue 中的“部分失败提示”。建议补充的验证
save_index()失败后,同时断言磁盘文件字节、进程内index.ntotal、实际检索结果、chunk/FTS、KBDocument均保持删除前状态;随后重试成功且只保存一次最终索引。update_kb_stats()失败时,路由返回结构化警告而非通用失败;前端刷新后列表不再显示已删除文档,并明确提示统计刷新状态。完成以上两处后,用户侧效果会更稳定:成功、可重试失败和“删除完成但统计待修复”三种状态可区分,且磁盘异常不会让当前进程的检索结果与持久化数据发生长期偏离。