RAG 평가와 LLM-as-a-Judge

Judge 편향과 안정성 — median, σ, 재판정

2026. 07. 07.
AIRAGEvaluationLLM-as-a-Judge

앞 글에서 LLM-as-a-Judge를 세웠다. 이제 진짜 어려운 얘기다.

같은 (컨텍스트, 답) 쌍을 판정자에게 5번 물어보면
매번 다른 점수가 나온다.

판정자 자체가 흔들리는데 그걸 어떻게 신뢰할 수 있나? 이번 글은 그 흔들림의 정체(편향)와, 흔들림을 억제하는 기법(안정화)을 다룬다.


Judge bias 4종

LLM 판정자가 흔들리는 이유는 랜덤성 하나가 아니다. 연구에서 반복해서 관측되는 편향이 크게 넷 있다.

1. Position bias

같은 두 답 A, B를 순서만 바꿔서 비교시키면
LLM이 앞에 오는 답을 선호하는 경향이 있다.

이건 특히 pairwise judge(둘 중 어느 게 나은가?)에서 심하다. 싱글 스코어링(0~1로 매김)에서는 덜 하지만, 여러 문단을 순서대로 평가할 때는 여전히 남는다.

대응: A/B 순서를 랜덤 셔플하거나, 양쪽 순서로 두 번 물어보고 평균낸다.

2. Verbosity bias

긴 답이 짧은 답보다 높은 점수를 받는다.

"자세하다"는 게 좋아 보이니까 판정자가 자연스럽게 그쪽으로 기운다. 그런데 실제로는 긴 답이 오히려 환각을 더 잘 섞는다. faithfulness는 verbosity가 늘수록 오히려 떨어져야 정상이다.

대응: rubric에 "길이는 평가하지 말라"고 명시한다. 길이 자체를 하나의 지표로 따로 뺀다.

3. Self-preference bias

모델이 자기가 만든 답을 자기가 판정하면 후하게 준다.

이건 이 시리즈 다음 편(cross-model judge)에서 정면으로 다룬다. 지금은 이름만 기억.

4. Calibration bias

"0.8이 뭘 뜻하는지"에 대한 감각이 판정자마다 다르다.
같은 답이라도 어떤 모델은 0.7, 어떤 모델은 0.9를 준다.

절대값 비교가 위험한 이유가 여기 있다. 오늘 0.8이 어제 0.9보다 나쁘다고 단정할 수 없다 — 판정자 감각이 바뀌었을 가능성이 있다.

대응: 절대 스코어보다 델타(어제→오늘)를 본다. 그리고 판정자 모델을 자주 바꾸지 않는다.


흔들림을 어떻게 줄이나

편향의 원인은 위처럼 여럿이지만, 실무에서 통제할 수 있는 손잡이는 크게 세 개다.

1) 여러 번 판정하고 median 을 쓴다
2) 분산이 크면 자동으로 재판정한다
3) rubric을 아주 구체적으로 쓴다

1. N회 median 판정

같은 (컨텍스트, 답)을 판정자에게 N번(보통 3~5회) 물어보고 중앙값을 최종 점수로 쓴다.

raw scores:  [0.85, 0.90, 0.62, 0.88, 0.86]
mean:        0.822
median:      0.86

평균 대신 중앙값을 쓰는 이유는 outlier에 덜 흔들리기 때문이다. 0.62 하나가 평균을 크게 끌어내리는데, 중앙값은 그걸 무시해준다.

3회로 시작해도 충분히 안정적이다. 5회는 확실히 안정적이지만 비용이 늘고, 7회부터는 개선폭이 급격히 줄어든다.

2. σ 임계 자동 재판정

median만으로 모든 케이스가 잡히지는 않는다. 분산 자체가 큰 케이스를 따로 처리해야 한다.

raw scores: [0.30, 0.85, 0.20, 0.90, 0.88]
median:     0.85
σ (표준편차): 0.322  ← 너무 큼

median이 0.85로 나왔지만, 이 케이스는 판정자가 "확신 못 하는 케이스"다. 0.85를 그대로 쓰면 위험하다. σ가 임계값(예: 0.15)을 넘으면 자동 재판정을 걸어서 그 답을 사람에게 넘기거나, 다른 모델로 다시 판정한다.

if σ > 0.15:
    escalate to secondary judge (다른 모델)
    or flag as "unstable" for human review

이렇게 하면 판정자 신뢰도가 확 올라간다. 자신 없는 케이스만 골라내는 필터가 무료로 붙는 셈이다.

3. rubric을 세밀하게

Rubric이 두루뭉술하면 판정이 흔들린다. 반대로 rubric이 구체적일수록 판정자 간·판정 간 일관성이 올라간다.

나쁜 예:

"답이 얼마나 정확한지 0~1로 판정하라."

좋은 예:

답의 각 문장을 아래 규칙으로 채점한 뒤 평균을 낸다.

1) 문장이 사실 진술이 아니면(의견, 인사, 안내) 채점에서 제외한다.
2) 사실 진술이면 컨텍스트에서 근거 문장을 찾는다.
   - 근거가 명확: 1.0
   - 근거가 부분적: 0.5
   - 근거가 없음:  0.0
3) 답 안에 컨텍스트에 없는 숫자·고유명사가 있으면 무조건 0.0.
4) 길이는 평가하지 않는다.

출력은 JSON:
{
  "per_sentence": [...],
  "final_score": 0.0~1.0,
  "reason": "..."
}

Rubric이 세밀할수록 재현성이 올라간다. 그리고 나중에 판정 로그를 볼 때 "왜 이렇게 매겼는지"가 사람이 읽을 수 있게 남는다.


실측 감각

프로젝트에서 15종목 × 5회 판정을 돌린 실측이다.

1회 판정만 썼을 때:
  종목 간 grounded 편차 σ = 0.11
  같은 종목 재판정 편차 σ = 0.08

5회 median 후:
  종목 간 grounded 편차 σ = 0.09
  같은 종목 재판정 편차 σ = 0.03

"같은 종목을 판정자에게 다시 물어봤을 때 얼마나 흔들리는가"가 0.08 → 0.03으로 떨어졌다. 이 정도면 판정 결과가 실제로 파이프라인 변경의 신호인지 노이즈인지 구분이 된다.

σ 임계 재판정을 붙인 뒤에는 15종목 중 2종목이 "unstable"로 걸렸다. 그 2종목은 사람 리뷰로 넘겼는데, 둘 다 실제로 판정하기 애매한 답이었다. 판정자가 자기 자신 없는 케이스를 잘 골라낸 셈이다.


rag-retriever/03과의 연결

이 시리즈에서 판정자를 세밀하게 다루고 있지만, 원래 rag-retriever/03 검색 품질 평가 편에서 LLM-as-Judge를 짧게 언급했다. 거기서는 "이런 지표가 있다" 정도로 넘어갔는데, 이 편이 그 심화판이다.

정리하면:

rag-retriever/03  → 검색이 잘 되는지 재는 지표 (Recall@k, MRR, nDCG)
rag-eval/01       → 생성까지 포함한 판정 지표 (RAGAS 5개)
rag-eval/02 (여기) → 그 판정자를 어떻게 흔들리지 않게 만들 것인가

세 편을 세트로 읽으면 "검색과 생성을 어떻게 평가할지"가 하나의 그림으로 정리된다.


다음 편 예고

편향 4개 중 self-preference bias는 이번 편에서 이름만 언급했다. 그건 판정자를 한 개 쓰는 한 근본적으로 해결이 안 되기 때문이다.

다음 편에서는 판정자를 두 개 쓴다. Sonnet과 Opus를 나란히 세워서 disagreement를 재고, 그 disagreement 자체를 파이프라인 신호로 쓰는 법을 다룬다.