Skip to content

fix: 修复多知识库稀疏检索排序失真 - #9426

Open
chinatsu1124 wants to merge 1 commit into
AstrBotDevs:masterfrom
chinatsu1124:fix/9425-multi-kb-sparse-rank
Open

fix: 修复多知识库稀疏检索排序失真#9426
chinatsu1124 wants to merge 1 commit into
AstrBotDevs:masterfrom
chinatsu1124:fix/9425-multi-kb-sparse-rank

Conversation

@chinatsu1124

@chinatsu1124 chinatsu1124 commented Jul 28, 2026

Copy link
Copy Markdown

修复多个知识库各自使用独立 FTS5 索引时,直接按原始 BM25 分数合并候选导致的排序失真。

不同 FTS5 索引的 BM25 分数受各自语料规模、词频和文档长度统计影响,不能直接跨索引比较。此前合并后的位置被当作稀疏检索排名传入 RRF,可能使小知识库中的高相关结果被大知识库候选压低。

Fixes #9425

Modifications / 改动点

  • SparseResult 增加可选的来源排名 rank

  • FTS5 检索时保留候选在各知识库独立索引中的局部排名,RRF 使用该排名计算贡献。

  • 内存 BM25 回退路径仍在统一候选集上排序,并记录全局排名,保持原有语义。

  • 对未提供 rank 的旧调用保留按列表顺序计算排名的兼容行为。

  • 增加跨知识库稀疏检索和 RRF 融合回归测试,测试数据均为虚构内容。

  • This is NOT a breaking change. / 这不是一个破坏性变更。

Screenshots or Test Results / 运行截图或测试结果

验证步骤:

.venv/bin/ruff format --check astrbot/core/knowledge_base/retrieval/sparse_retriever.py astrbot/core/knowledge_base/retrieval/rank_fusion.py tests/unit/test_sparse_retriever.py tests/unit/test_rank_fusion.py
.venv/bin/ruff check astrbot/core/knowledge_base/retrieval/sparse_retriever.py astrbot/core/knowledge_base/retrieval/rank_fusion.py tests/unit/test_sparse_retriever.py tests/unit/test_rank_fusion.py
.venv/bin/python -m pytest -q tests/unit/test_sparse_retriever.py tests/unit/test_rank_fusion.py tests/test_kb_import.py tests/unit/test_kb_document_cleanup.py tests/unit/test_kb_manager_resilience.py tests/unit/test_kb_upload_atomicity.py tests/unit/test_knowledge_base_service_contract.py

结果:

4 files already formatted
All checks passed!
43 passed, 4 warnings in 129.61s

4 条警告来自既有 aiosqlite 原子性测试在线程结束时访问已关闭的事件循环,与本次改动无关。


Checklist / 检查清单

  • 😊 If there are new features added in the PR, I have discussed it with the authors through issues/emails, etc.
    / 如果 PR 中有新加入的功能,已经通过 Issue / 邮件等方式和作者讨论过。
  • 👀 My changes have been well-tested, and "Verification Steps" and "Screenshots" have been provided above.
    / 我的更改经过了良好的测试,并已在上方提供了“验证步骤”和“运行截图”
  • 🤓 I have ensured that no new dependencies are introduced, OR if new dependencies are introduced, they have been added to the appropriate locations in requirements.txt and pyproject.toml.
    / 我确保没有引入新依赖库,或者引入了新依赖库的同时将其添加到 requirements.txtpyproject.toml 文件相应位置。
  • 😮 My changes do not introduce malicious code.
    / 我的更改没有引入恶意代码。

Summary by Sourcery

Preserve per-knowledge-base sparse retrieval ranks and use them in rank fusion to avoid distorted ordering across independent FTS5 indexes.

Bug Fixes:

  • Fix cross-knowledge-base sparse retrieval ranking by using local FTS5 ranks instead of raw BM25 scores when fusing results.
  • Ensure BM25 in-memory fallback path assigns and propagates global ranks consistently for rank fusion.

Enhancements:

  • Extend SparseResult with an optional rank field and make rank fusion backward-compatible with callers that do not provide ranks.

Tests:

  • Add unit tests to verify sparse retriever preserves per-knowledge-base FTS ranks and that rank fusion prioritizes high-relevance results from smaller knowledge bases.

@dosubot dosubot Bot added the size:S This PR changes 10-29 lines, ignoring generated files. label Jul 28, 2026

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S This PR changes 10-29 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] 多知识库稀疏检索直接合并独立 FTS5 BM25 分数导致排序失真

1 participant