LLM-as-Judge는 너무 관대합니다. 저렴한 해결책: Judge, Refute (그리고 어쩌면) Arbitrate
요약
LLM-as-Judge 방식의 고질적인 문제인 관대함 편향을 해결하기 위해 Judge(판사)와 Refuter(반박자)를 분리하는 설계를 제안합니다. 두 모델의 의견이 일치하면 결과를 수용하고, 불일치할 때만 결정권자(Arbitrator)를 호출하여 비용 효율적으로 평가 정확도를 높이는 방법론을 다룹니다.
핵심 포인트
- LLM은 단일 채점 시 관대하게 점수를 주는 경향이 있음
- Judge와 Refuter 역할을 분리하여 적대적 검증 구조 구축
- 의견 일치 시 추가 호출 없이 종료하여 비용 절감
- 불일치 시에만 결정권자를 호출하는 에스컬레이션 전략
만약 당신이 다른 LLM의 출력물(품질 게이트, 평가 하네스(eval harness), "이것이 루브릭(rubric)을 통과하는가"에 대한 체크)을 채점하도록 LLM을 연결했다면, 아마도 잘 알려진 경향성에 직면했을 것입니다. 바로 채점 기준을 완화하여 점수를 주는 경향입니다. 모델은 '통과'라고 말하고 싶어 합니다. 모델 비용을 두 배로 늘리지 않으면서 이를 강화하는 패턴이 여기 있습니다. 바로 판사(Judge)가 오직 그것을 비판하기 위해서만 존재하는 모델에 맞서 자신의 판결을 방어하게 만드는 것입니다.
요약 (TL;DR)
- LLM-as-judge 설정은 관대함(leniency)을 보이는 잘 알려진 경향이 있습니다. 그럴듯하게 들리는 출력을 생성한 것과 동일한 모델 계열이 그럴듯하게 들리는 출력을... 그럴듯하다고 판단하는 경향이 있기 때문입니다.
- 해결책: 채점을 두 가지 역할로 나눕니다. 루브릭(rubric)에 따라 점수를 매기는 **판사 (Judge)**와, 판사의 판결을 뒤집는 것만이 유일한 동기인 **반박자 (Refuter)**입니다.
- 만약 두 모델의 의견이 일치하면, 결과를 그대로 사용합니다. 이것이 저렴한 경로입니다. 이미 지불한 두 번의 모델 호출 외에 추가적인 호출이 필요하지 않기 때문입니다.
- 만약 의견이 불일치한다면, 처음부터 전체 문맥을 보는 것이 아니라 오직 불일치 사항만을 확인하는 **타이브레이커 (tie-breaker, 결정권자)**로 에스컬레이션(escalate)합니다.
- 에스컬레이션 결정 자체는 단순한 결정론적 코드(
if verdict_a == verdict_b)이므로, 제어 흐름을 지루하고 감사 가능한(auditable) 상태로 유지함으로써 실제 판단을 위한 모델 호출을 절약할 수 있습니다.
더 읽기 전에 증거에 관한 참고 사항: 위에서 언급한 관대함 경향은 LLM-as-judge 설정에서 널리 관찰되는 패턴이며, 그 메커니즘(자기 일치, 적대적 압박 부재)은 이에 대한 합리적인 설명입니다. 하지만 아래의 구체적인 패턴은 제가 제안하는 것이지, 대규모 라벨링된 벤치마크를 통해 검증한 것은 아닙니다. 이를 측정된 결과가 아닌, 시도해 볼 가치가 있는 설계로 취급해 주십시오.
문제점: 당신의 판사는 채점 기준을 완화합니다
"LLM-as-judge"는 이제 어디에나 있습니다: 콘텐츠 품질 게이트(content quality gates), RAG 답변 점수 산정, 코드 리뷰 봇, 테스트 출력 평가 등에서 말이죠. 하지만 주의 깊게 살펴보면 빠르게 나타나는 실패 모드(failure mode)가 있습니다. 바로 자기 채점(self-grading)과 단일 모델 채점(single-model grading)은 관대하게 편향되는 경향이 있다는 점입니다. 모델에게 "이것이 통과됩니까?"라고 물으면, 결함이 아주 명백하지 않는 한 기본적으로 '예'라고 답하는 경향이 있습니다. 왜냐하면 그 정당화(justification)가 옳은지 여부와 상관없이, 관대하게 들리는 근거를 생성하는 것은 언어 모델이 매우 잘하는 작업 중 하나이기 때문입니다.
더 강력한 모델을 판사로 사용하는 순진한 해결책(naive fix)은 약간의 도움은 되지만 비용이 많이 듭니다. 이는 실제 메커니즘을 해결하지 못합니다. 즉, 합의를 추구하는 모드(agreement-seeking mode)에서 단 한 번 질문을 받은 단일 채점자는 스스로의 의견에 반박해야 할 구조적 압박을 느끼지 못합니다.
이러한 아이디어들이 개별적으로는 새로운 것이 아닙니다. 이는 이미 평가(eval) 관행에 존재하는 두 가지 흐름과 맞닿아 있습니다: 모델이 단순히 판결을 내리는 것이 아니라 판결에 대해 논쟁하는 적대적 또는 토론 프레임워크(adversarial or debate framings), 그리고 여러 채점자가 투표하고 불일치(disagreement)를 주목해야 할 신호로 삼는 배심원단 구성(jury-of-judges setups)이 그것입니다. 아래에 소개할 내용은 일반적인 목적의 토론 프로토콜보다는 비용 폭포형 라우팅(cost-cascade routing, 저렴한 경로를 먼저 시도하고 저렴한 경로로 해결되지 않을 때만 비싼 모델을 사용하는 방식)과 결합된, 이 두 가지의 최소화된 버전입니다.
해결책: 판결하고, 반박하고, (어쩌면) 중재하라
이 패턴은 하나의 역할 대신 세 가지 역할을 가집니다:
- Judge (판사): 명시적인 루브릭(rubric)에 따라 출력을 점수화합니다. 일반적인 채점 단계입니다.
- Refuter (반박자): 판사의 판결과 근거를 전달받으며, 출력에 대한 일반적인 검토를 하는 것이 아니라 오직 해당 판결을 뒤집을 근거를 찾는 것만이 유일한 임무임을 명시적으로 전달받습니다.
- Tie-breaker (결정자/중재자): 판사와 반박자가 의견이 불일치할 때만 호출됩니다. 두 판결과 두 근거를 모두 확인하고 최종 결정을 내립니다. 이 단계만이 여러분의 가장 뛰어난(가장 비싼) 모델을 필요로 하는 유일한 단계입니다.
flowchart TD
IN(["Output + Rubric"]) --> J["Judge (cheap model)<br/>scores vs rubric"]
J -->|"verdict"| R["Refuter (cheap model)<br/>tries to overturn it"]
...
적대적 프레이밍 (Adversarial framing)은 모델이 무엇을 최적화할지를 변화시킵니다. "이것을 평가하라"는 지시를 받은 채점자는 그럴듯하게 들리는 '통과 (pass)' 판정을 내립니다. 반면, "당신의 유일한 임무는 이 특정 판정을 뒤집는 것이며, 만약 실질적인 근거를 찾을 수 없다면 그렇게 말하라"는 지시를 받은 채점자는 진정한 검토 (scrutiny)에 더 가까운 결과를 내놓습니다. 왜냐하면 명시적으로 공격 임무를 부여받은 상황에서 첫 번째 판정에 동의하는 것은 더 이상 저항이 가장 적은 경로 (path of least resistance)가 아니기 때문입니다. 동의하는 경우 또한 비용이 저렴합니다. 두 번의 호출로 끝납니다. 반면 불일치 (disagreement) 사례는 충분히 드물기 때문에, 설령 해당 모델의 호출 비용이 10배 더 비싸더라도 이를 더 강력한 모델로 라우팅하는 것은 여전히 감당할 만한 수준입니다.
실제 사례 예시
메커니즘을 구체화하기 위해, 하나의 예시적인 과정을 살펴보겠습니다. 이는 세 가지 역할이 어떻게 상호작용하는지 보여주기 위해 만들어진 가상의 예시이며, 실제 운영 로그나 측정된 결과가 아닙니다.
루브릭 (Rubric) (고객 지원 답변 품질 게이트용):
- 고객이 명시한 질문에 직접적으로 답변한다.
- 승인이 필요하다는 언급 없이 환불, 크레딧 또는 예외 사항을 허용하지 않는다.
- 단순히 "저희 정책에 따라"라고만 하지 않고, 근거가 되는 특정 정책 섹션을 인용한다.
평가 대상 출력물:
"저희 반품 정책의 섹션 4.2에 따라 고객님의 주문을 확인했습니다. 주문 후 35일이 경과하여 30일 기간을 넘겼지만, 고객님의 오랜 이용 기간을 고려하여 일회성 예외 환불을 승인해 드렸습니다. 영업일 기준 3~5일 이내에 처리될 것입니다."
판사(Judge) 판결: 실패 (FAIL). 제시된 이유: 환불이 승인 과정이 필요하다는 점을 알리지 않은 채 명시된 정책 기간 외에 허용되었습니다. 판사는 이를 항목 2의 "승인이 필요함" 문구를 위반한 것으로 해석합니다. 그 외에는 답변이 질문에 답하고 섹션 4.2를 인용하고 있으므로 항목 1과 3을 충족합니다.
반박자(Refuter)의 재반박: FAIL(실패) 판정을 뒤집을 근거를 찾으라는 지시를 받은 반박자는 항목 2의 정확한 문구를 다시 읽습니다: "승인이 필요하다고 말하지 않고(without saying it needs approval)", "실제로 인간에 의해 승인되지 않고(without actually being approved by a human)"가 아닙니다. 출력값에는 "제가 직접 승인했습니다(I've gone ahead and approved)"라고 되어 있으며, 반박자는 이것이 침묵하거나 표시되지 않은 예외 상황이 아니라 이미 명시적인 승인 문구로서 기능한다고 주장합니다. 결론적으로, 이 FAIL 판정은 루브릭(rubric)의 문구가 명확하게 다루지 않는 사례에 항목 2를 과도하게 적용한 것이라고 결론지으며, **PASS(통과)**를 반환합니다.
타이브레이커(Tie-breaker): Judge(판사)는 FAIL을, Refuter(반박자)는 PASS를 선언했기 때문에 호출되었습니다. 두 판결, 양측의 근거, 루브릭, 그리고 출력값을 모두 고려했을 때, 타이브레이커는 Judge의 손을 들어줍니다: 항목 2는 단순히 에이전트 자신의 답변 내에 "승인됨"이라고 표현되었는지 여부가 아니라, 승인이 실제로 획득되었고 그에 따라 표시되었는지에 관한 것이며, 출력값 어디에도 별도의 승인 기록이 참조되지 않았기 때문입니다. 최종 판결: FAIL. 단, 루브릭 항목 2의 문구가 충분히 모호하여 두 명의 지정된 역할이 이를 서로 다르게 해석할 수 있으므로, 아마도 문구를 더 엄격하게 다듬을 필요가 있다는 노트를 남깁니다.
마지막 노트는 깊이 생각해 볼 가치가 있습니다. 타이브레이커는 단순히 의견 불일치를 해결한 것이 아니라, 정확히 어떤 루브릭 라인이 그 불일치를 일으켰는지를 지목했습니다.
최소 구현 (Minimal implementation)
from dataclasses import dataclass
from enum import Enum
...
judge()와 refute()가 서로 다른 모델 이름인 cheap-model-a와 cheap-model-b를 기본값으로 사용한다는 점에 주목하십시오. 이는 단순한 장식이 아니라 의도된 설계입니다. 이 패턴의 핵심 논거는 단일 채점자(grader)는 스스로의 의견에 반대해야 할 구조적 압박이 없다는 것입니다. 두 역할을 정확히 동일한 제공자의 동일한 가중치(weights)를 가진 모델로 지정하는 것은 동일한 위험을 다시 도입하는 것과 같습니다. 특정 유형의 출력을 잘못 판단하는 공유 모델은 두 역할 모두에서 동일하게 잘못 판단할 가능성이 있기 때문입니다. 서로 다른 체크포인트(checkpoints)나 제공자를 사용하는 것이 가장 깔끔한 해결책입니다. 만약 현재 설정에서 그것이 실용적이지 않다면, 최소한 두 호출 사이의 시스템 프롬프트(system prompt)와 샘플링 온도(sampling temperature)를 다르게 설정하십시오. 그리고 이를 확인하기 전까지는 이 패턴의 보호 효과를 완전한 것이 아닌 부분적인 것으로 간주해야 합니다.
그리고 이를 하나로 묶어주는 제어 흐름(control flow)은 또 다른 모델 호출 대신 의도적으로 평범한 코드로 유지됩니다:
def quality_gate(output: str, rubric: str, tiebreaker_model="strong-model") -> Judgment:
first = judge(output, rubric)
second = refute(output, rubric, first)
...
에스컬레이션(escalation) 트리거는 if first.verdict == second.verdict입니다. 이는 "에스컬레이션을 해야 할까요?"라고 묻는 네 번째 모델 호출이 아니라, 단순한 비교입니다. 이러한 라우팅 로직(routing logic)을 결정론적(deterministic)인 코드로 유지하면, 이를 로그로 남기고, 테스트하고, 비용을 확실하게 추론할 수 있습니다. 결정 자체가 확률적인 판단이 아니기 때문에, 타이브레이커(tie-breaker) 호출을 실제로 수행하기 전에 정확히 몇 번의 호출이 발생할지 알 수 있습니다.
불일치 기반 에스컬레이션이 "항상 최상의 모델을 사용하기"보다 나은 이유
명백한 대안은 "판단자로 항상 비싼 모델을 실행하는 것"입니다. 이는 단일 저가형 판단자를 사용하는 것보다 다소 더 정확하겠지만, 근본적인 메커니즘은 변하지 않습니다. 한 번의 채점을 요청받은 단일 강력한 모델은 여전히 적대적 압박(adversarial pressure)이 없는 단일 채점자일 뿐이며, 단지 더 비쌀 뿐입니다. 또한 저가형 판단자와 저가형 반박자(refuter)가 어차피 동의했을 압도적 다수의 항목에 대해서도 매번 그 프리미엄을 지불해야 합니다.
Judge-refute-arbitrate (판단-반박-중재) 구조는 정보 이득(information gain)이 가장 높은 곳, 즉 두 개의 지정된 역할이 합의에 도달하지 못한 사례에만 비싼 모델을 정확히 사용합니다. 그 외의 모든 경우에는 적대적 배치(adversarial arrangement)를 통한 두 번의 저렴한 호출이, 그렇지 않았다면 비싼 모델 한 번이 단독으로 수행해야 했을 작업을 대신 처리합니다.
반박자(refuter)가 반대만을 위한 슬롯머신이 되지 않도록 하는 가드레일 (Guardrails)
이 시스템을 운영할 때 주의해야 할 두 가지 실패 모드(failure modes)는 다음과 같습니다:
- 조작된 이의 제기 (Manufactured objections). 만약 평가 하네스(eval harness)가 반박자에게 반대하는 것에 대해 암묵적으로라도 보상을 준다면, 반박자는 항상 반대하는 법을 배우게 될 것입니다. 프롬프트에는 명시적인 탈출구(escape hatch)가 필요합니다: "실질적인 근거를 찾을 수 없다면 그렇게 말하십시오." 반박자의 출력물에 대한 자체 평가를 통해, 첫 번째 판결이 실제로 견고할 때 반박자가 실제로 "이를 뒤집을 수 없음"이라고 말하는지 가끔 확인해야 합니다. 결코 양보하지 않는 반박자는 적대적인 것이 아니라, 그저 노이즈(noisy)일 뿐입니다.
- 근거 없는 루브릭 (Ungrounded rubric). 두 역할 모두 "이것이 좋아 보이는가"가 아닌, 동일하고 명시적인 루브릭 (rubric)을 가져야 합니다. 공유된 루브릭 없이 적대적 프레임워크(adversarial framing)만 사용하면, 중재할 공통 기반 없이 확신에 찬 두 가지 의견만 생성될 뿐이며, 이는 결정권자(tie-breaker)의 업무(그리고 나중에 이 모든 과정을 감사할 수 있는 능력)를 훨씬 더 어렵게 만듭니다.
또한 결정권자(tie-breaker)의 판단을 구체적으로 주기적으로 감사(auditing)할 가치가 있습니다. 결정권자는 오직 의견 불일치 시에만 작동하므로, 루브릭 자체가 모호한 지점이 어디인지 알려주는 가장 신호가 강한(highest-signal) 샘플이 됩니다. 동일한 실패 카테고리에서 결정권자로의 에스컬레이션(escalation)이 반복된다면, 이는 더 똑똑한 모델이 필요한 것이 아니라 루브릭의 경계선을 더 날카롭게 다듬어야 함을 의미합니다.
이 패턴이 효용을 발휘하는 지점
이는 과거의 콘텐츠 품질 게이트(quality gates)를 일반화한 것입니다. 예를 들어, "이 PR(Pull Request)이 기준을 충족하는가"를 결정하는 코드 리뷰 봇(code review bots), "이 답변이 검색된 컨텍스트(retrieved context)에 근거하고 있는가"를 점수 매기는 RAG 파이프라인(RAG pipelines), "이 테스트가 실제로 의미 있는 무언가를 단언(assert)하는가"를 확인하는 테스트 생성 파이프라인(test-generation pipelines) 등이 이에 해당합니다. 다른 LLM의 출력을 단순히 승인(rubber-stamp)하기 위해 단일 LLM 호출에 의존해 온 곳이라면 어디든 이 패턴을 적용할 수 있습니다. 이 패턴은 첫날부터 루브릭(rubric)이 완벽할 것을 요구하지 않습니다. 단지 "동의(agree)"와 "비동의(disagree)"가 서로 다르게 라우팅(routing)할 가치가 있는, 구별 가능한 결과여야 한다는 점만을 요구합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기