diff --git a/app/services/search_telemetry.py b/app/services/search_telemetry.py index 3260420..bc6e05c 100644 --- a/app/services/search_telemetry.py +++ b/app/services/search_telemetry.py @@ -103,17 +103,22 @@ def compute_confidence(results: list[Any], mode: str) -> float: # 코사인 유사도 그대로 return _cosine_to_confidence(top_score) - # text / hybrid: 강한 텍스트 매치 우선 판정 - if "title" in reason and top_score >= 4.0: - return 0.95 - if any(k in reason for k in ("tags", "note")) and top_score >= 3.0: - return 0.85 - if "summary" in reason and top_score >= 2.5: - return 0.75 - if "content" in reason and top_score >= 2.0: - return 0.65 + # hybrid에서 텍스트+벡터 합성 매치는 reason에 "+vector" 접미. 신뢰 가산. + has_vector_boost = "+vector" in reason + boost = 0.10 if has_vector_boost else 0.0 + + # text / hybrid: 강한 텍스트 매치 우선 판정. + # 임계값은 search.py의 가중치 합산 분포(텍스트base + FTS bonus + 0.5*cosine)를 반영. + if "title" in reason and top_score >= 3.5: + return min(1.0, 0.95 + boost) + if any(k in reason for k in ("tags", "note")) and top_score >= 2.5: + return min(1.0, 0.85 + boost) + if "summary" in reason and top_score >= 2.0: + return min(1.0, 0.75 + boost) + if "content" in reason and top_score >= 1.5: + return min(1.0, 0.65 + boost) if "fts" in reason and top_score >= 1.0: - return 0.55 + return min(1.0, 0.55 + boost) # vector-only hit (텍스트 0건 → 코사인 raw, amplify 금지) if reason == "vector":