# Phase 0.5 Fusion 전략 비교 — 2026-04-07

`tests/search_eval/queries.yaml` v0.1 (23개 쿼리)을 3가지 fusion 전략으로 실행한 비교.

## 전체 지표

| 지표 | legacy (기존 weighted-sum) | rrf (k=60) | rrf_boost (default) |
|---|---|---|---|
| Recall@10 | 0.788 | 0.788 | 0.788 |
| MRR@10 | **0.751** | 0.747 | 0.747 |
| NDCG@10 | **0.705** | 0.699 | 0.700 |
| Top-3 hit | 0.950 | 0.950 | 0.950 |
| Latency p95 | 554ms | 554ms | 556ms |
| Failure precision | 0/3 | 0/3 | 0/3 |

**현재 평가셋에서 RRF는 legacy 대비 측정 가능한 개선을 주지 못함** (NDCG -0.005, MRR -0.004).
오히려 미세하게 나쁘다. 그러나 rrf_boost는 rrf의 일부 손실을 복구한다.

## 쿼리별 차이 분석 (top5 ordering 변화 7건)

### kw_001 — RRF의 가장 큰 손실 (NDCG 1.000 → 0.906)

쿼리: `산업안전보건법 제6장`

| 전략 | top5 |
|---|---|
| legacy | 3856, 3868, 3879, 3912, 3950 |
| rrf/boost | 3856, **4041**, 3868, 3879, 3912 |

- 정답: [3856, 3868, 3879] (산안법 본법 + 시행령 + 시행규칙 6장)
- RRF가 4041(근로기준법 제6장 안전과 보건)을 2위로 끌어올림. 텍스트+벡터 둘 다에서 잡혀서 RRF가 보상.
- **boost가 잡지 못한 이유**: 4041 title도 "제6장"을 포함하지만 boost의 `LEGAL_ARTICLE_RE`는 `제\d+조`(조)만 매치, `제\d+장`(장)은 매치 안 함. 의도적 한계.
- RRF의 단점이 극명히 드러나는 사례 — false positive가 두 retriever에서 동시에 잡히면 promotion됨.

### news_004 — boost가 RRF를 정확히 보정한 사례

쿼리: `guerre en Iran` (불어 뉴스)

| 전략 | top5 |
|---|---|
| legacy | 4199, 4507, 4521, 4363, 4519 |
| rrf | 4199, 4507, 4519, **4211**, 4521 |
| **boost** | **4199, 4507, 4521, 4363, 4519** ← legacy와 동일 |

- rrf는 4211(불어 비-정답)을 4위로 올렸으나, boost가 4363(텍스트 매치)을 다시 끌어올려 legacy NDCG 복원 (0.822).
- **boost의 가치를 보여주는 유일한 사례**.

### kw_002 — 같은 NDCG, 다른 ordering

쿼리: `중대재해 처벌 등에 관한 법률 제2장 중대산업재해`

| 전략 | top5 |
|---|---|
| legacy | 3921, 3917, 3916, 3922, 3920 |
| rrf/boost | **3917**, 3921, 3916, 3922, 3920 |

- 정답: [3917, 3921] — RRF가 본법(3917)을 1위로 올림. **사람 직관에 더 부합**.
- legacy는 시행령(3921)을 1위로 — 점수 합산 우연.
- NDCG 같음(둘 다 1.0) — 평가 metric이 ordering 차이를 잡지 못함.

### misc_001 — RRF가 약간 더 좋음

쿼리: `강체의 평면 운동학`

NDCG: legacy 0.605 → rrf/boost 0.624 (+0.019)
- 미세하지만 RRF가 정답을 약간 위로.

### news_002, news_003 — 둘 다 미세하게 나쁨

미세 차이. 평가셋에 가린 신호.

## 핵심 인사이트

### 1. 현재 평가셋에선 fusion 전략 차이가 미미
- **이유**: 평가셋이 23개로 작고, exact_keyword 카테고리가 이미 NDCG 1.0이라 fusion 차이가 noise에 묻힘.
- **시사**: queries.yaml v0.2에서 graded relevance + 더 어려운 ranking 케이스가 필요.

### 2. RRF 단독은 RRF-friendly false positive에 취약
- 두 retriever 모두에서 쿼리와 *부분* 매치하는 doc은 RRF가 promotion.
- **kw_001**의 4041(근로기준법)이 대표 사례. 텍스트엔 "제6장 안전과 보건"이 있고, 벡터 임베딩도 의미상 가깝다.
- legacy의 weighted-sum은 텍스트 점수의 절대값을 보존해서 이런 부분 매치를 덜 promotion함.

### 3. boost는 일부 케이스만 보정
- news_004는 완벽 보정 (legacy 수준 복원).
- kw_001은 보정 실패 — 법령 "장" vs "조" 구분이 한계.
- **확장 후보**: `제\d+장` 패턴, 도메인 일치 boost(법령 쿼리에 대해 법령 결과 우선) — Phase 2 QueryAnalyzer 도입 시.

### 4. RRF의 진짜 가치는 Phase 1+ 인프라
- RRF가 빛을 발하는 시점:
  - Phase 1: trigram + reranker가 추가 retrieval 신호로 들어올 때 (3+ 신호 합치는 데 RRF가 normalize 부담을 흡수)
  - Phase 2: multi-query (한국어 + 영어) 임베딩 결과 fusion할 때
- 현 시점에서 legacy → rrf 교체의 손익분기점은 Phase 1에 도달.

## 결정

- **default = rrf_boost 유지**. 다음 이유:
  1. legacy 대비 손실이 작음(NDCG -0.005, MRR -0.004).
  2. 인프라(FusionStrategy ABC)가 Phase 1+ 신호 추가 시 즉시 활용됨.
  3. boost가 일부 케이스(news_004)에서 가치 입증.
- **legacy 보존**. Phase 1 reranker 통합 후 재비교를 위해 옵션 유지.
- **평가셋 v0.2 우선순위 상승**: graded relevance + ordering 민감 케이스 추가가 fusion 평가에 필요.

## 부수 개선

- `normalize_display_scores`: SearchResult.score를 [0..1] 랭크 기반 정규화. 기존 frontend의 `score*100` 표시 깨짐(>100% 또는 <5%) 수정.
