[Bug] 知识库大批量向量写入后检索分数持续退化不自愈,需重建 HNSW 索引才能恢复

オープン
#7,597 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

  • #7693 @ump45nose による — マージされずにクローズ

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
28/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
活発
技術スタック
postgresql, python
領域
databases, search

調査の方向性

The payload names the per-knowledge partial HNSW index embedding_hnsw_idx_{knowledge_id} on the embedding table, filtered by knowledge_id, and the bulk paragraph and problem-vector writes that precede the drop. Start by finding where that index is created and where batch vector writes happen, then reproduce the score drop after a large import with a REINDEX as the comparison. Done means a clear statement of whether index maintenance or rebuild is needed, with a reproducible before-and-after check. The payload does not settle whether the fix belongs in index maintenance or in the write path, so confirm scope with maintainers first.

索引モデルが issue の本文から書いたものです。

説明

MaxKB 版本

v2.10.x(生产环境为 v2 定制部署,2026-10 复现)

请描述您遇到的问题

知识库经历大批量向量写入后(分批导入、批间等待向量化完成,符合规范操作),检索分数在一小时左右后出现整体退化并恒定不自愈;仅对全库重建向量并重建索引后可恢复。

具体表现(同一知识库前后对照):

  • 精确标题查询的命中分数从 1.0 跌至 0.38~0.54
  • 短查询分数从 0.9 量级跌至 0.37~0.57,top1 命中错误段落
  • 连续多轮复测分数逐位一致,跨小时、隔夜均无变化(非暂态)
  • keywords(全文检索)模式始终正常
  • 同一嵌入模型的存量旧知识库始终正常(0.90~0.97)
  • 内容层数据零差异(文档数/段落数/问题数/字符总量与源数据完全一致)

即:数据完整、嵌入模型服务健康、检索服务本身正常,退化发生在向量索引层。

复现步骤
  1. 新建知识库,绑定 embedding 模型
  2. 分批批量导入大量段落(我们场景:1127 个文档、4911108 段),每批等待向量化完成
  3. 批量补挂大量关联问题(数百至上千条,分批写入)
  4. 写入完成后初期检索正常,约 50~60 分钟后同题复测分数明显下降且此后恒定
  5. 对该库执行全量重新向量化(会删除并重建该库 HNSW 索引)后,检索分数立即恢复

背景机制:MaxKB 为每个知识库在 embedding 表上建一个部分 HNSW 索引
(embedding_hnsw_idx_{knowledge_id} ... WHERE knowledge_id = '<kb_id>')。
大量增量插入(尤其高频短文本,如 FAQ 关联问题向量)后,HNSW 图结构退化、
近似检索召回率下降,这与 pgvector 的已知特性一致;删除操作在 HNSW 中为
标记删除,死节点同样加剧失真。逐文档 refresh 只重写数据行、不重建索引,
因此无法恢复。

预期的正确行为

批量写入完成后检索质量应保持稳定,或至少有索引维护机制避免持续退化。

备注
  • 客户侧临时缓解:批量写入完成后对该索引执行 REINDEX(秒级到分钟级)即可恢复
  • 涉及库规模:单库 1127 文档、4911515 段落、440~1349 条关联问题向量
主要言語
Python
スター
23.1k
フォーク
3.2k
平均マージ
41分
マージ済み PR(30日)
480

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

1Panel-dev/MaxKB のほかの issue

1Panel-dev/MaxKB の issue をすべて見る

似ている issue

Python の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。