feat/knowledge-retrieval-core
main
本 PR 交付 RAG Benchmark(检索质量评测)后端能力,并落实 PR #12 的四项审阅问题修复。
目标分支:main 来源分支:feat/knowledge-retrieval-core 主要变更
1 P1 Benchmark 同步检索阻塞事件循环,取消/进度/并发失效 rag.py 每个样本前 await asyncio.sleep(0) 让出执行权,取消检查紧随其后 2 P2 SSE 流在终止事件后不结束 routes.py 回放与实时两处均检测 run_completed/run_failed/run_cancelled 并终止,try/finally 保证退订 3 P2 FTS 硬编码截断 5000,total 与分页失真 repository.py + engine.py 去除截断,真实 COUNT + 数据库分页 4 P2 仅标注 block_id 时被误判为检索失败 rag.py _expected_notes 从块反查所属笔记 回归测试 新增 6 个回归测试:test_cancel_running_benchmark_stops_early、test_sse_stream_ends_on_terminal_event_in_replay、test_block_only_annotation_resolves_note_and_scores、test_fts_not_truncated_at_five_thousand、test_fts_offset_beyond_end_reports_real_total、test_fts_score_threshold_filters_before_total。 后端完整测试:218 passed。 验证
cd backend uv run pytest -q # 218 passed uv run uvicorn app.main:app --reload --host 127.0.0.1 --port 8000 http://127.0.0.1:8000/docs 下:
POST /api/benchmarks/rag/runs → 202 queued → SSE 观察进度 → GET .../report 取报告 POST /api/search {"query":"向量数据库","mode":"fts"} 验证分页与 total 说明 未 push 前已与 origin/main 合并,无冲突。 导出(Markdown→HTML)与函数图像为后续 P0,本 PR 不包含。
审阅版本:abccb32。
abccb32
上一轮提出的 4 项问题均已修复并通过验证:
验证结果:
git diff --check
本轮未发现阻塞合并的问题,可以合并。
另外,PR 描述有两处非阻塞笔误,请同步修正:
/api/benchmarks/runs/{run_id}/events
/rag
No dependencies set.
The note is not visible to the blocked user.
本 PR 交付 RAG Benchmark(检索质量评测)后端能力,并落实 PR #12 的四项审阅问题修复。
目标分支:main
来源分支:feat/knowledge-retrieval-core
主要变更
异步任务模型:POST /api/benchmarks/rag/runs 创建即返回 queued,后台 asyncio.create_task 执行,内存注册表 + 协程取消(MAX_RUNS=100,终态淘汰)。
评测指标:hit_at_1 / hit_at_5 / recall_at_k / mrr / citation_hit_rate / p50 / p95,按 (mode, case, repeat) 逐样本计算,失败样本按零分计入质量指标分母(不把执行失败误判为检索质量)。
SSE 实时进度:GET /api/benchmarks/rag/runs/{run_id}/events 推送 RunStarted / RunCompleted / CaseCompleted / RunFailed / RunCancelled,支持 Last-Event-ID 断线重连。
内置数据集:backend/data/benchmarks/rag-core-v1.json(48 条样例,含笔记级/块级标注)。
FTS 路径改为数据库侧过滤/计数/分页:fts_score_bounds(ORDER BY rank ASC/DESC LIMIT 1 求 bm25 上下界)+ fts_search_page(bm25_max=...),阈值换算为 bm25 截止值,total 始终为真实命中数。
审阅问题修复(PR #12)
级别 问题 修复
1 P1 Benchmark 同步检索阻塞事件循环,取消/进度/并发失效 rag.py 每个样本前 await asyncio.sleep(0) 让出执行权,取消检查紧随其后
2 P2 SSE 流在终止事件后不结束 routes.py 回放与实时两处均检测 run_completed/run_failed/run_cancelled 并终止,try/finally 保证退订
3 P2 FTS 硬编码截断 5000,total 与分页失真 repository.py + engine.py 去除截断,真实 COUNT + 数据库分页
4 P2 仅标注 block_id 时被误判为检索失败 rag.py _expected_notes 从块反查所属笔记
回归测试
新增 6 个回归测试:test_cancel_running_benchmark_stops_early、test_sse_stream_ends_on_terminal_event_in_replay、test_block_only_annotation_resolves_note_and_scores、test_fts_not_truncated_at_five_thousand、test_fts_offset_beyond_end_reports_real_total、test_fts_score_threshold_filters_before_total。
后端完整测试:218 passed。
验证
cd backend
uv run pytest -q # 218 passed
uv run uvicorn app.main:app --reload --host 127.0.0.1 --port 8000
http://127.0.0.1:8000/docs 下:
POST /api/benchmarks/rag/runs → 202 queued → SSE 观察进度 → GET .../report 取报告
POST /api/search {"query":"向量数据库","mode":"fts"} 验证分页与 total
说明
未 push 前已与 origin/main 合并,无冲突。
导出(Markdown→HTML)与函数图像为后续 P0,本 PR 不包含。
审阅结论:同意合并
审阅版本:
abccb32。上一轮提出的 4 项问题均已修复并通过验证:
验证结果:
git diff --check通过。本轮未发现阻塞合并的问题,可以合并。
另外,PR 描述有两处非阻塞笔误,请同步修正:
/api/benchmarks/runs/{run_id}/events,不包含/rag。