9dad5e6289
PR-Eval-GradedNDCG-Dedup. [[feedback_graded_ndcg_dedup_invariant]] cleanup. plan pr-eval-graded-ndcg-dedup-stormy-tide.md. 변경: - tests/search_eval/run_eval.py: · _dedup_returned_ids() helper — returned[:k] 첫 등장 순서 보존 dedup + count 반환 · count_dedup() wrapper (audit 용) · ndcg_at_k + graded_ndcg_at_k 진입 시 dedup (NDCG > 1.0 invariant 강제) · QueryResult.dedup_count 필드 + csv schema 신규 column · evaluate() 에서 dedup_count > 0 시 stderr WARNING · print_summary 에 dedup audit stats (cases/total chunks + 정상/⚠️ flag) - tests/search_eval/test_eval_graded_ndcg_dedup.py 신규 — 13 test: · _dedup_returned_ids 6 (empty / no-dup / dup-first / k-limit / count helper / Phase 2Q kw_001) · graded_ndcg invariant 5 (baseline 회귀 0 / dup 차단 / all-dup / exam_001 regression / empty grades) · ndcg_at_k binary dedup 1 + graded_recall set 변환 1 51/51 test PASS (13 신규 + 38 기존 회귀 0). 🚨 CRITICAL 측정 발견: dedup audit baseline = 0/51 정상 (single-query path 의 retrieval 가 doc unique 박제) dedup audit gemma = 42/51 (totaling 81 chunks dedup) ⚠️ → _rrf_fuse_variants 의 representative 보존 logic 이 같은 doc_id 의 여러 SearchResult 를 unique 가정. chunk_id dedup (Rerank-Fix) 이후에도 doc_id 중복 잔재. 정정값 (이번이 가장 정확): baseline NDCG 0.644 (이전 0.659 와 noise level diff) gemma NDCG 0.641 → Δ vs baseline = -0.003 (사실상 동일, multi-query 실제 net 효과 ≈ 0) latency p50 +1005ms (+266%) — 회귀 Recall t≥3 -0.033 (회귀) 이전 박제값 (모두 inflation): Phase 3 (a41adb6) NDCG 0.927 — chunk_id 중복 Rerank-Fix (b734fc5) NDCG 0.876 — doc_id 중복 잔재 Category-Analysis (b00d9f5) NDCG 0.876 정정 박제 — 위와 동일 산출물: reports/v0_2_phase2q_eval_dedup_baseline_2026-05-24.csv (baseline 회귀 verify) reports/v0_2_phase2q_eval_dedup_gemma_2026-05-24.csv (실제 효과 측정) tests/search_eval/baselines/v0_2_phase2q_eval_dedup_2026-05-24.json (요약 + critical 권고) 권고 (사용자 결정 필요): 1. Apply rollback 검토 — multi-query 의 실제 net 효과 ≈ 0 + latency 4x 회귀 2. 또는 PR-2Q-Search-Result-Dedup 진입 (real fix _rrf_fuse_variants representative) 후 재측정 → 실제 multi-query 효과 측정 후 Apply 결정 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>