feat(search): Phase 1.3 TEI reranker 통합 (코드 골격)

데이터 흐름 원칙: fusion=doc 기준 / reranker=chunk 기준 — 절대 섞지 말 것.

신규/수정:
- ai/client.py: rerank() 메서드 추가 (TEI POST /rerank API)
- services/search/rerank_service.py:
    - rerank_chunks() — asyncio.Semaphore(2) + 5s soft timeout + RRF fallback
    - _make_snippet/_extract_window — title + query 중심 200~400 토큰
      (keyword 매치 없으면 첫 800자 fallback)
    - apply_diversity() — max_per_doc=2, top score>=0.90 unlimited
    - warmup_reranker() — 10회 retry + 3초 간격 (TEI 모델 로딩 대기)
    - MAX_RERANK_INPUT=200, MAX_CHUNKS_PER_DOC=2 hard cap
- services/search_telemetry.py: compute_confidence_reranked() — sigmoid score 임계값
- api/search.py:
    - ?rerank=true|false 파라미터 (기본 true, hybrid 모드만)
    - 흐름: fused_docs(limit*5) → chunks_by_doc 회수 → rerank_chunks → apply_diversity
    - text-only 매치 doc은 doc 자체를 chunk처럼 wrap (fallback)
    - rerank 활성 시 confidence는 reranker score 기반
- tests/search_eval/run_eval.py: --rerank true|false 플래그

GPU 적용 보류:
- TEI 컨테이너 추가 (docker-compose.yml) — 별도 작업
- config.yaml rerank.endpoint 갱신 — GPU 직접 (commit 없음)
- 재인덱싱 완료 후 build + warmup + 평가셋 측정
This commit is contained in:
Hyungi Ahn
2026-04-08 12:41:47 +09:00
parent b80116243f
commit 76e723cdb1
5 changed files with 306 additions and 7 deletions

View File

@@ -149,6 +149,33 @@ def _cosine_to_confidence(cosine: float) -> float:
return 0.10
def compute_confidence_reranked(reranked_results: list[Any]) -> float:
"""Phase 1.3 reranker score 기반 confidence.
bge-reranker-v2-m3는 sigmoid score (0~1 범위)를 반환.
rerank 활성 시 fusion score보다 reranker score가 가장 신뢰할 수 있는 신호.
임계값(초안, 실측 후 조정 가능):
>= 0.95 → high
>= 0.80 → med-high
>= 0.60 → med
>= 0.40 → low-med
else → low
"""
if not reranked_results:
return 0.0
top_score = float(getattr(reranked_results[0], "score", 0.0) or 0.0)
if top_score >= 0.95:
return 0.95
if top_score >= 0.80:
return 0.80
if top_score >= 0.60:
return 0.65
if top_score >= 0.40:
return 0.50
return 0.35
def compute_confidence_hybrid(
text_results: list[Any],
vector_results: list[Any],