들어가며: 왜 지금 LLM Eval과 실험의 관계를 다시 봐야 할까
AI 프로덕트를 만들다 보면 이런 고민에 빠지곤 합니다. "LLM Judge가 Variant A가 더 좋다고 했는데, 실제 유저 반응은 어떨까?" 혹은 "A/B 테스트 돌리기엔 시간이 너무 아까운데, Eval만 믿고 배포해도 될까?"
스포티파이 데이터 과학팀이 공개한 흥미로운 통계가 있습니다. 스포티파이에서 진행된 A/B 테스트 중 실제로 출시까지 이어진 긍정적 결과는 약 12% 에 불과했습니다. 하지만 나머지 88%가 무의미한 것은 아닙니다. 약 64%의 테스트는 '회귀 발견', '아이디어 기각', '가설 정제' 같은 가치 있는 학습을 만들어냈습니다.
즉, 실험의 승률(win rate)은 실험의 진정한 가치를 과소평가하게 만듭니다. 그리고 여기에 LLM Eval이라는 새로운 도구가 등장하면서, 우리는 'Eval vs 실험'이라는 이분법적 사고에서 벗어나 'Eval → 실험'으로 이어지는 깔때기(Funnel) 구조를 이해해야 합니다.
이 글은 스포티파이 엔지니어링 블로그에 게시된 "Better Experiments with LLM Evals — A funnel, not a fork"를 기반으로, 국내 AI 프로덕트 개발 환경에 맞게 재해석했습니다.

Eval이 해주는 것과 해주지 못하는 것
Schultzberg와 Ottens(2024)는 이 문제를 **Verification(검증)**과 **Validation(확인)**이라는 두 개념으로 명확히 구분합니다.
| 구분 | Eval (LLM Judge) | A/B 테스트 (실험) |
|---|---|---|
| 역할 | 출력이 품질 기준에 부합하는지 검증 | 실제 유저가 예측대로 반응하는지 확인 |
| 비용 | 낮음 (오프라인, 자동화 가능) | 높음 (온라인, 트래픽 분할 필요) |
| 측정 대상 | 관련성, 일관성, 톤, 의도 정렬 등 | 비즈니스 지표, 장기 사용자 행동 |
| 한계 | 측정하지 않는 차원이 존재 | 시간과 리소스 소모 큼 |
Eval이 진짜로 하는 일
Eval은 실험 대역폭을 낭비하지 않도록 가능성이 낮은 후보를 미리 걸러내는 필터 역할을 합니다. 예를 들어, 팀이 신뢰를 해치는 콘텐츠를 탐지하는 LLM Judge를 만들었다고 가정해봅시다.
# 예시: LLM Judge를 활용한 신뢰 위반 콘텐츠 필터링
import openai
def trust_violation_judge(response_text: str) -> dict:
"""
LLM Judge가 응답 텍스트의 신뢰 위반 여부를 평가합니다.
반환값: {"score": 0~1, "reason": "..."}
"""
prompt = f"""
다음 응답이 사용자에게 부적절한 추천을 포함하거나,
신뢰를 해칠 가능성이 있는지 평가해줘.
점수는 0(안전) ~ 1(위험) 사이로 줘.
응답: "{response_text}"
점수와 이유를 JSON으로 출력해.
"""
result = openai.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
response_format={"type": "json_object"}
)
return eval(result.choices[0].message.content)
# 사용 예
sample_response = "이 영화는 당신에게 딱이에요! (하지만 실제로는 폭력적 장면이 많습니다)"
scores = trust_violation_judge(sample_response)
print(scores) # {'score': 0.85, 'reason': '사용자 선호도와 무관한 추천, 잠재적 신뢰 손상'}
이 Judge는 팀이 미처 알지 못했던 패턴을 표면화합니다. 예를 들어 "특정 장르의 영화를 싫어하는 사용자에게 그 장르를 강하게 추천하는 패턴" 같은 것들이죠. 이 패턴들은 제품 개선으로 이어집니다. 그리고 개선이 배포된 후, 동일한 Judge로 개선 효과를 확인할 수 있습니다. 위반 사례가 줄었는지 보면 됩니다.
Eval이 절대 해주지 못하는 것
하지만 Eval은 다음과 같은 질문에 답할 수 없습니다.
- "개선된 버전을 받은 사용자가 실제로 더 나은 경험을 했는가?"
- "신뢰 손실이 결국 이탈(churn)로 이어지는 것을 막았는가?"
이 질문은 반드시 **실험(Experiment)**이 필요합니다.
또 하나 중요한 점: 당신이 측정하지 않는 차원들이 항상 존재합니다. 스포티파이의 경우, 출시된 실험의 약 42%가 세션 길이 감소, 크래시율 증가, 리텐션 하락 같은 2차 지표(guardrail metrics)에서 회귀를 발견해 롤백됩니다. 어떤 Eval도 오프라인에서는 이 문제를 잡아내지 못했습니다.

두 개의 보정 레이어, 하나의 피드백 루프
Eval은 본질적으로 **프록시(proxy)**입니다. 점수로 실제 원하는 결과를 대체하는 것이죠. 이 대체는 점수가 실제 결과를 잘 추적할 때만 유효합니다. 여기에 LLM Judge가 전통적인 정량적 지표(랭킹 점수, 정밀도, 재현율) 위에 두 번째 보정 레이어를 추가합니다.
두 레이어 모두 온라인 결과에 대한 검증이 필요합니다. 그리고 두 레이어 모두 **드리프트(drift)**할 수 있습니다.
예를 들어, Anthropic이 Opus 4.5 모델을 출시했을 때, Qodo의 코딩 Eval에서는 개선이 전혀 나타나지 않았습니다. 하지만 실제로는 **더 긴 작업(longer tasks)**에서 모델이 크게 개선되었고, 이는 통제된 실험에서만 발견될 수 있었습니다. 반대 방향의 오보정도 가능합니다.
오프라인-온라인 보정 루프
# 예시: Eval 점수와 실험 결과를 비교하여 보정 계수 계산
import numpy as np
from sklearn.metrics import mean_squared_error
def calibration_error(eval_scores: list, experiment_effects: list) -> float:
"""
Eval 점수와 실험 효과 크기 간의 평균 제곱 오차를 계산합니다.
값이 작을수록 Eval이 실험 결과를 잘 예측하고 있음을 의미합니다.
"""
# eval_scores: LLM Judge가 각 Variant에 부여한 점수 (0~1)
# experiment_effects: 실제 실험에서 측정된 효과 크기 (예: 리텐션 변화율)
return np.sqrt(mean_squared_error(eval_scores, experiment_effects))
# 예제 데이터
eval_scores = [0.9, 0.7, 0.6] # Judge가 Variant A,B,C에 준 점수
experiment_effects = [0.03, 0.02, -0.01] # 실제 리텐션 변화
error = calibration_error(eval_scores, experiment_effects)
print(f"보정 오차: {error:.3f}") # 0.05 미만이면 양호
이 루프를 지속적으로 운영하면 Eval이 점점 더 정교한 검증 도구로 진화합니다. 미래에는 AI가 발전함에 따라 Eval이 검증(Verification)을 넘어 확인(Validation)에 가까워질 수도 있습니다. 하지만 그때까지도 오프라인/온라인 보정 루프는 Eval이 얼마나 신뢰할 수 있는지 투명하게 보여주는 장치로 남을 것입니다.
속도 압박에 대한 경고
"A/B 테스트는 비용이 너무 많이 들어요."라는 말을 자주 듣습니다. 하지만 실험 없이 배포했다가 주요 비즈니스 지표에서 큰 회귀를 발견하지 못하는 비용이 훨씬 더 큽니다. 시스템이 복잡할수록 리스크를 제한(bound the risk)하는 것이 중요합니다.
관련 글: React, 드디어 독립했다 – React Foundation 출범과 생태계 변화 완전 정리

실무 적용: 루프를 닫아라 (Close the Loop)
- Eval을 초기에 자주 실행하여 최상의 처방(treatment)을 찾으세요.
- 실험을 통해 실제 유저와 시스템이 예측대로 반응하는지 확인하고, 최적화하지 않은 지표도 모니터링하세요.
- 빠른 방향성 테스트(quick directional test)는 반복과 데이터 수집용
- 출시 결정(rigorous test)은 엄격한 실험용
- A/B 테스트 데이터 자체에 LLM Eval을 다시 적용하세요. Judge가 선호한 버전이 실제로 사용자에게 더 좋은 성과를 냈는지 확인합니다.
- Eval 점수와 실험 결과 간의 차이가 크다면, 그것이 진단의 황금(Gold)입니다. 각 사이클이 다음 보정에 도움을 줍니다.
국내 AI 생태계에서의 적용 맥락
국내 스타트업이나 SI 환경에서는 A/B 테스트 인프라가 부족한 경우가 많습니다. 이럴 때는 Eval을 먼저 강화하는 전략이 효과적입니다. 예를 들어:
- 고객센터 챗봇의 응답 품질을 LLM Judge로 일일 평가하고, 하위 10% 케이스를 수동 검토
- Judge가 발견한 패턴을 바탕으로 프롬프트 엔지니어링 개선
- 개선 후 동일 Judge로 재평가 → 점수 향상 확인 → 그다음에야 A/B 테스트 도입
이 기술의 한계 및 주의사항
- Eval은 절대 실험을 대체할 수 없습니다. Eval은 검증(Verification) 도구이지 확인(Validation) 도구가 아닙니다.
- LLM Judge 자체의 편향(Bias) 을 항상 염두에 두어야 합니다. Judge가 특정 스타일의 응답을 과대평가하거나, 문화적 맥락을 놓칠 수 있습니다.
- 장기적인 사용자 행동은 Eval로 포착하기 어렵습니다. 예를 들어 "이 기능이 3개월 후 리텐션에 어떤 영향을 미칠까?"는 Eval이 답할 수 없는 질문입니다.
다음 단계 학습 방향
- Eval 파이프라인 구축 실습: Daggr 공개 코드로 짜고 눈으로 확인하는 AI 워크플로우 빌더를 참고하여 실제 Eval 워크플로우를 코드로 구현해보세요.
- Guardrail Metrics 설계: 스포티파이의 사례처럼, 최적화 대상이 아닌 지표 중 무엇을 모니터링할지 정의해보세요.
- 오프라인-온라인 보정 루프 구축: 작은 규모의 프로젝트부터 Eval 점수와 실제 KPI를 비교하는 대시보드를 만들어보세요.
핵심은 이것입니다: Eval을 실험의 대체재가 아니라, 실험의 성공률을 높이는 전처리 단계로 활용하라. 루프를 닫을 때, 당신의 AI 시스템은 점점 더 똑똑해집니다.