리랭킹 — 병합 결과를 다시 세운다

무엇을

RRF 로 병합한 상위 후보를 크로스 인코더로 다시 정렬한다(B-3).

왜 순서가 중요한가 — MRR 이 여기서 움직인다

Recall@5 는 «5개 안에 있는가» 만 보지만 상담원은 맨 위 카드부터 읽는다. 지금 실측이 Recall@5 0.833 인데 MRR 0.659 다 — 찾기는 찾는데 1위에 못 올리고 있다는 뜻이다. 리랭킹이 겨냥하는 것이 정확히 이 간격이다.

완료 조건

주의

⚠ 리랭커는 ai/ 에만 둔다. server/.importlinter 계약 2 가 server/ 안에서 torch·transformers import 를 막는다(architecture.md §1).


2026-09-15 — MRR 0.885 → 0.919 (후보 5). 후보 20 은 예산을 깬다

측정일 2026-09-15 · 커밋 38f2fc3-dirty · 골든셋 v1-150 B 항목 n96 · 지식베이스 98조항 · 로컬 Darwin arm64
.venv/bin/python scripts/index_knowledge_base.py --to-es --recreate     # 본문 + KoE5 임베딩
.venv/bin/python scripts/compare_retrievers.py [--device mps]
결과 파일 data/processed/retrieval-compare/2026-09-15*.json (gitignore)
리랭커 BAAI/bge-reranker-v2-m3 (다국어 크로스 인코더, Apache-2.0, 568M)

변형                          Recall@5   hits    MRR   top1 │ p95 CPU   p95 MPS
bm25 (run_id=2 와 같은 값)       0.833   80/96  0.659    51  │     4ms      7ms
dense (KoE5 kNN)                0.979   94/96  0.885    78  │    59ms     50ms
hybrid RRF k=60 cand=20         0.927   89/96  0.828    73  │    58ms     39ms
  k=10 / 30 / 100               0.927   89/96  0.835 / 0.828 / 0.828
rerank(bm25) cand=5             0.833   80/96  0.795    73  │   494ms    237ms
rerank(bm25) cand=20            0.906   87/96  0.860    79  │  1760ms   1068ms
rerank(dense) cand=5            0.979   94/96  0.919    84  │   521ms    289ms
rerank(dense) cand=20           0.979   94/96  0.921    84  │  1789ms   1317ms
rerank(hybrid) cand=5           0.927   89/96  0.886    82  │   529ms    373ms
rerank(hybrid) cand=20          0.979   94/96  0.916    83  │  1844ms   1197ms

⚠ 새 모델을 들였다

decisions/010 은 리랭커를 고르지 않았다. 그래서 결정 기록 206 을 썼다 — 010 을 덮는 것이 아니라 빈칸을 채운다. 대조군을 재지 않았다 — 한국어 전용 리랭커와 붙여 본 적이 없다.

설정

CrossEncoderReranker(inner, scorer, candidates=5) · 운영은 RETRIEVAL_RERANK_MODEL_DIR(비우면 끔). 리랭커는 ai/ 에만 있다 — server/main.py 는 ai/provider.py 팩토리를 부를 뿐 torch 를 import 하지 않는다(계약 2 KEPT).