1 정의
Human evaluation이란, 도메인 전문가 또는 훈련된 평가자가 Agent의 응답을 직접 읽고 사전 정의된 루브릭(rubric)에 따라 점수를 부여하는 평가 방식이다.
자동 평가의 보완: LLM-as-Judge가 포착하지 못하는 뉘앙스, 도메인 정확성, 실용성을 평가한다
비용이 높고 느리지만, 평가의 최종 기준(gold standard)이다
자동 평가의 타당성(validity)을 검증하는 기준점 역할을 한다
역학: Expert panel review, Endpoint adjudication committee
IT: Human evaluation, Human-in-the-Loop (HITL) assessment
2 왜 인간 평가가 필요한가
2.1 자동 평가의 한계
| 한계 | 예시 |
|---|---|
| 표면적 유사성 편향 | ROUGE/BERTScore가 높지만, 핵심 개념이 틀린 응답 |
| LLM-as-Judge 편향 | 자기가 생성한 스타일의 응답에 높은 점수를 주는 경향 |
| 도메인 특수성 | “표준 용어”와 “표준 단어”의 차이를 일반 LLM이 평가하기 어려움 |
| 실용성 판단 불가 | 정확하지만 실무에서 쓸 수 없는 형식의 응답 |
구체적 실패 사례: MINERVA Data Standardization Helper에서 LLM-as-Judge가 Relevance 5점을 준 응답이 실제로는 사용 불가능한 경우가 있다. “컬럼명 cust_nm의 표준 용어를 추천하라”에 대해 “고객명(customer name)입니다”라고 답하면 LLM은 의미적으로 정확하다고 판단하지만, 실무에서는 표준 도메인 코드, 데이터 타입, 길이 제약까지 포함해야 실제로 채택할 수 있다. 이 괴리를 자동 지표만으로는 감지할 수 없다.
2.2 인간 평가가 필수인 상황
- 초기 시스템 검증: 자동 평가 파이프라인을 구축하기 전
- 자동 평가 보정: LLM-as-Judge의 점수가 인간 판단과 일치하는지 검증
- High-stakes 의사결정: 프로덕션 전환, 모델 교체 등 중대한 결정
- 새로운 태스크 도입: 기존 자동 지표가 적용되지 않는 새 Agent 기능
3 평가 루브릭 설계
3.1 루브릭이란
루브릭은 평가 기준과 점수 할당 규칙을 명시한 문서이다. 평가자 간 일치도를 높이는 핵심 도구이다.
3.2 설계 원칙
- 구체적 행동 기술: “좋은 응답”이 아니라 “정답 키워드 3개 중 2개 이상 포함”
- 등간 척도: 각 점수 간 차이가 균등하게 느껴지도록 설계
- 경계 사례 명시: 3점과 4점의 경계에 해당하는 구체적 예시를 포함
- 도메인 용어 정의: 평가에 필요한 도메인 지식을 루브릭에 포함
3.3 MINERVA QnA Chatbot 루브릭 예시
## Relevance (질의-응답 적합도)
| 점수 | 기준 | 구체적 예시 |
|------|------|------------|
| 5 | 질의의 모든 측면에 직접 답하며, 추가 정보도 유용하다 | Q: "표준 용어와 표준 단어의 차이?" → 정의 비교 + 관계 설명 + 예시 |
| 4 | 핵심 질문에 답하며, 부가적 측면 1~2개 누락 | 정의 비교는 정확하나 예시 없음 |
| 3 | 관련 내용이나, 질의의 핵심을 부분적으로만 다룸 | 표준 용어만 설명하고 비교 없음 |
| 2 | 주제는 관련되나, 질문에 대한 실질적 답변이 아님 | 데이터 표준화 일반론만 서술 |
| 1 | 질의와 무관한 응답 | 완전히 다른 주제 |
## Faithfulness (문서 근거성)
| 점수 | 기준 |
|------|------|
| 5 | 모든 주장이 검색 문서에서 직접 확인 가능 |
| 4 | 대부분 문서에 근거, 합리적 추론 1~2개 포함 |
| 3 | 핵심은 문서 근거, 일부 근거 없는 서술 존재 |
| 2 | 부분적으로만 문서와 일치, 상당 부분 근거 없음 |
| 1 | 문서와 거의 무관하거나 명백히 모순 |
## Completeness (답변 완전성)
| 점수 | 기준 |
|------|------|
| 5 | 기대 답변의 핵심 요소를 모두 포함하고 추가 가치도 제공 |
| 4 | 핵심 요소 대부분 포함 (80% 이상) |
| 3 | 핵심 요소의 절반 정도 포함 |
| 2 | 핵심 요소 일부만 포함 (30% 미만) |
| 1 | 핵심 요소가 거의 없음 |4 평가자 간 일치도 (Inter-Rater Reliability)
4.1 왜 일치도가 중요한가
평가자 A는 4점, 평가자 B는 2점을 주면 이 평가 결과를 신뢰할 수 없다. 평가자 간 일치도가 충분히 높아야 인간 평가가 의미 있다.
4.2 Cohen’s Kappa (κ)
2명의 평가자 간 일치도를 측정한다. 우연에 의한 일치를 보정한다.
\[ \kappa = \frac{p_o - p_e}{1 - p_e} \]
- \(p_o\): 관찰된 일치율
- \(p_e\): 우연에 의한 기대 일치율
직관적으로, κ는 “두 평가자가 진짜 합의한 정도”를 측정한다. 5점 척도에서 두 사람이 아무 생각 없이 랜덤으로 점수를 매겨도 20% 정도는 우연히 일치한다. κ는 이 우연 일치를 빼고 남는 “진짜 합의”만 계산한다. κ=0.60이면 “우연을 뺀 후에도 60%의 합의가 있다”는 뜻이고, κ=0이면 “평가자 간 합의가 동전 던지기 수준”이라는 뜻이다. Quadratic weighting은 4점 vs 5점(1점 차이)보다 1점 vs 5점(4점 차이)에 훨씬 큰 페널티를 주어, 극단적 불일치를 더 심각하게 반영한다.
from sklearn.metrics import cohen_kappa_score
def evaluate_inter_rater(rater1_scores, rater2_scores):
"""2명의 평가자 간 일치도 측정"""
kappa = cohen_kappa_score(rater1_scores, rater2_scores, weights="quadratic")
# 해석 기준 (Landis & Koch, 1977)
interpretation = {
(0.81, 1.00): "거의 완전 일치 (Almost Perfect)",
(0.61, 0.80): "상당한 일치 (Substantial)",
(0.41, 0.60): "보통 일치 (Moderate)",
(0.21, 0.40): "약한 일치 (Fair)",
(0.00, 0.20): "미약한 일치 (Slight)",
(-1.00, 0.00): "일치하지 않음 (Poor)",
}
label = "Unknown"
for (lo, hi), desc in interpretation.items():
if lo <= kappa <= hi:
label = desc
break
return {
"kappa": round(kappa, 3),
"interpretation": label,
"acceptable": kappa >= 0.60,
"action": (
"평가 진행 가능" if kappa >= 0.60
else "루브릭 재교육 또는 개선 필요"
)
}4.3 ICC (Intraclass Correlation Coefficient)
3명 이상의 평가자 간 일치도, 또는 연속형 점수의 일치도를 측정한다.
Cohen’s κ가 2명 전용이라면, ICC는 3명 이상으로 확장한 것이다. 비유하면, κ는 두 명의 심사위원이 일치하는지 보는 것이고, ICC는 심사위원단 전체의 채점 패턴이 일관되는지 보는 것이다. ICC(2,1)은 “무작위로 뽑은 평가자 한 명의 점수가 다른 평가자의 점수를 얼마나 예측하는가”를 측정한다.
import pingouin as pg
import pandas as pd
def compute_icc(ratings_df, rater_col="rater", item_col="item", score_col="score"):
"""ICC(2,1): 무작위 효과 모델 기반 일치도
Args:
ratings_df: columns=[rater, item, score]
"""
icc_results = pg.intraclass_corr(
data=ratings_df,
targets=item_col,
raters=rater_col,
ratings=score_col
)
# ICC(2,1): two-way random, single measures
icc_2_1 = icc_results[icc_results["Type"] == "ICC2"].iloc[0]
return {
"icc": round(icc_2_1["ICC"], 3),
"ci_95": (round(icc_2_1["CI95%"][0], 3), round(icc_2_1["CI95%"][1], 3)),
"interpretation": (
"우수" if icc_2_1["ICC"] >= 0.75
else "양호" if icc_2_1["ICC"] >= 0.60
else "불충분 — 루브릭 개선 필요"
)
}4.4 일치도가 낮을 때의 대응
| κ / ICC | 판정 | 조치 |
|---|---|---|
| ≥ 0.80 | 우수 | 평가 진행 |
| 0.60 ~ 0.79 | 양호 | 불일치 사례 토론 후 진행 |
| 0.40 ~ 0.59 | 보통 | 루브릭 개정 + 재교육 + pilot 재실시 |
| < 0.40 | 불충분 | 루브릭 전면 재설계 |
왜 κ ≥ 0.60을 최소 기준으로 삼는가: κ < 0.60이면 두 평가자의 점수 차이가 평균 1~2점에 달한다. 5점 척도에서 1.5점 차이는 “3점(부분적 답변)” vs “4.5점(거의 완벽)”을 구분하지 못한다는 뜻이다. 이런 평가로 구성 A(평균 3.8점)와 구성 B(평균 4.1점)의 차이를 판정하면, 0.3점 차이가 실제 품질 차이인지 평가자 간 변동인지 알 수 없다. 평가자 간 변동이 처치 효과보다 크면, 표본을 아무리 늘려도 올바른 결론에 도달할 수 없다.
5 자동 평가 vs 인간 평가 상관 검증
5.1 절차
Step 1: 인간 평가 셋 구축
→ 200~300개 질의-응답 쌍을 2명 이상의 평가자가 평가
Step 2: 동일 셋에 자동 평가 적용
→ LLM-as-Judge로 동일 기준으로 평가
Step 3: 상관 분석
→ Spearman ρ 또는 Pearson r 계산
Step 4: 판정
→ ρ ≥ 0.7: 자동 평가로 대체 가능
→ 0.5 ≤ ρ < 0.7: 자동 평가 사용 가능하나 주기적 인간 보정 필요
→ ρ < 0.5: 자동 평가 신뢰 불가, 인간 평가 비중 확대
from scipy.stats import spearmanr
import numpy as np
def validate_auto_evaluation(human_scores, auto_scores):
"""자동 평가와 인간 평가의 상관을 검증한다"""
corr, p_value = spearmanr(human_scores, auto_scores)
# 점수 차이 분포
diffs = np.array(auto_scores) - np.array(human_scores)
return {
"spearman_rho": round(corr, 3),
"p_value": p_value,
"mean_diff": round(np.mean(diffs), 3), # 양수 = 자동이 관대
"std_diff": round(np.std(diffs), 3),
"auto_bias": (
"자동 평가가 관대" if np.mean(diffs) > 0.3
else "자동 평가가 엄격" if np.mean(diffs) < -0.3
else "편향 없음"
),
"reliability": (
"대체 가능" if corr >= 0.7
else "보정 후 사용" if corr >= 0.5
else "신뢰 불가"
),
}5.2 보정(Calibration) 방법
자동 평가가 체계적으로 편향되어 있으면 선형 보정을 적용한다:
from sklearn.linear_model import LinearRegression
def calibrate_auto_scores(human_scores, auto_scores, new_auto_scores):
"""인간 점수 기준으로 자동 점수를 보정한다"""
model = LinearRegression()
model.fit(np.array(auto_scores).reshape(-1, 1), human_scores)
calibrated = model.predict(np.array(new_auto_scores).reshape(-1, 1))
return {
"calibrated_scores": calibrated,
"slope": round(model.coef_[0], 3),
"intercept": round(model.intercept_, 3),
"interpretation": (
f"보정 식: human_equiv = {model.coef_[0]:.2f} × auto + {model.intercept_:.2f}"
)
}6 평가 프로세스 설계
6.1 실무 워크플로우
평가 대상 선정 (무작위 샘플링 또는 층화 샘플링)
↓
평가자 배정 (각 항목 최소 2명)
↓
독립 평가 (평가자 간 논의 금지)
↓
일치도 계산 (κ ≥ 0.60?)
↓
┌─ YES → 평가 결과 확정
└─ NO → 불일치 항목 토론 → 합의 또는 3번째 평가자
6.2 평가 항목 수 결정
def required_evaluation_items(
expected_correlation: float = 0.7,
ci_width: float = 0.15,
confidence: float = 0.95
) -> int:
"""자동-인간 상관 검증에 필요한 평가 항목 수
Fisher's z transformation 기반
"""
from scipy.stats import norm
z = norm.ppf((1 + confidence) / 2)
# 상관계수의 표준오차: 1/√(n-3)
n = (2 * z / ci_width) ** 2 + 3
return int(np.ceil(n))
# 상관 0.7, 신뢰구간 폭 ±0.15 → 약 140개 항목 필요
n_items = required_evaluation_items()
print(f"필요 평가 항목 수: {n_items}")6.3 MINERVA 적용
| 단계 | 활동 | 항목 수 | 평가자 |
|---|---|---|---|
| Pilot | 루브릭 검증 + 평가자 훈련 | 30 | 2명 |
| 일치도 확인 | κ ≥ 0.60 확인 | 50 | 2명 |
| 본 평가 | 자동-인간 상관 검증 | 150 | 2명 |
| 정기 보정 | 자동 평가 드리프트 확인 | 50/월 | 1명 |
7 관련 주제
선행 지식
- 오프라인 평가 설계 — LLM-as-Judge 자동 평가
- Agent 실험 메트릭 설계 — 평가 지표 체계
시리즈 다음 포스트
- 실험 결과 분석과 의사결정 — 정량+정성 평가 결과의 종합 판단
다른 카테고리 연결
- 통계 기초 — 상관 분석, 분산 분석의 이론적 기반