LLM-as-a-Judge 프레임워크는 지금 빠르게 갈라지고 있습니다. API 프론티어 판사(GPT-4o, Claude Opus)에 프롬프트를 얹는 방향이 있고, 오픈소스로 파인튜닝한 전용 판사 모델 방향이 있고, 아예 API 호출 없이 코드로 판사를 합성하는 방향이 있습니다. 각 방향의 대표 프레임워크는 G-Eval, Prometheus 2, PAJAMA, Themis입니다. 그리고 증류된 판사(Distilled Judge)가 이 모두를 아우르는 비용 최적화 전략으로 자리잡았습니다. 무엇이 언제 맞는지, 각 프레임워크의 원리·구현·한계를 실전 코드와 함께 정리합니다.
4편이 다루는 것 → G-Eval (Liu et al. 2023, EMNLP) — CoT + Form-filling + 확률 가중 점수의 작동 원리 → Prometheus 2 (Kim et al. 2024, EMNLP) — DA/PWC 통합 오픈소스 판사, 가중치 병합 방법 → PAJAMA (Huang et al. 2025, ICML WS) — 프로그램 합성 판사, 3500× 비용 절감 원리 → Themis (Hu et al. 2024, EMNLP) — 시나리오 의존 프롬프트, 참조 없는 NLG 평가 → 증류된 판사 파이프라인 — 대형 판사의 판정을 소형 모델에 전수 → 프레임워크 선택 기준 — 태스크·비용·제어 수준·도메인에 따른 결정 트리
왜 프레임워크가 필요한가
"GPT-4에 '이 응답 1~10점으로 평가해줘'라고 하면 되지 않나?"
될 때도 있습니다. 하지만 이렇게 하면 세 가지 문제가 동시에 발생합니다. 점수가 어떤 기준에서 나왔는지 알 수 없고(불투명성), 같은 프롬프트에 같은 응답을 넣어도 점수가 달라지고(불안정성), 6개월 뒤 GPT 버전이 바뀌면 이전 점수와 비교할 수 없게 됩니다(캘리브레이션 표류).
프레임워크는 이 세 문제를 체계적으로 해결하기 위한 구조화된 방법입니다. G-Eval은 CoT 추론과 확률 기반 점수화를 결합해 기존 참조 기반 지표보다 인간 판단과의 상관성을 크게 높였습니다. Prometheus 2는 GPT-4의 세밀한 평가 능력을 오픈소스 모델에 증류해, 투명성·제어성·비용 문제를 동시에 해결하려 했습니다.
1. G-Eval — 가장 유연한 프레임워크
출처: Liu et al. 2023, EMNLP ("NLG Evaluation using GPT-4 with Better Human Alignment")
핵심 아이디어 세 가지:
G-Eval은 세 주요 컴포넌트로 구성됩니다. 사용자가 "태스크 소개"와 "평가 기준"을 정의한 프롬프트, 이를 받아 상세한 "평가 단계"를 생성하는 자동 CoT, 그리고 점수화 함수입니다.
① 자동 CoT 생성
사용자가 기준을 자연어로 정의하면, 판사 LLM이 평가 단계를 자동으로 생성합니다. 사용자가 단계를 직접 설계하지 않아도 됩니다.
from anthropic import Anthropic
import json
client = Anthropic()
# 1단계: 평가 기준 → 평가 단계 자동 생성
STEP_GENERATION_PROMPT = """당신은 NLG 출력 품질 평가 전문가입니다.
다음 평가 기준을 바탕으로, LLM 응답을 평가하기 위한
구체적인 단계별 절차를 생성하세요.
[태스크]
{task_description}
[평가 기준]
{criteria}
요구사항:
- 각 단계는 명확하고 실행 가능해야 합니다
- 단계는 순서대로 수행됩니다
- 각 단계는 판단의 근거가 됩니다
- 4~7개 단계로 구성하세요
JSON으로만 출력:
{{"evaluation_steps": ["단계1", "단계2", ...]}}
"""
def generate_eval_steps(
task_description: str,
criteria: str,
judge_model: str = "claude-sonnet-4-6",
) -> list[str]:
"""기준에서 평가 단계 자동 생성 (1회 실행, 재사용)"""
raw = client.messages.create(
model=judge_model,
max_tokens=512,
messages=[{"role": "user", "content": STEP_GENERATION_PROMPT.format(
task_description=task_description,
criteria=criteria,
)}]
).content[0].text.strip()
return json.loads(raw)["evaluation_steps"]
# 사용 예시: 요약 품질 평가용 단계 생성
steps = generate_eval_steps(
task_description="뉴스 기사 자동 요약 시스템 평가",
criteria="일관성: 요약이 원문과 사실적으로 일치하는가? 원문에 없는 내용을 추가하지 않았는가?",
)
# → ['1. 원문의 핵심 사실을 파악한다', '2. 요약에서 각 주장을 확인한다', ...]
② Form-filling 평가
생성된 단계를 이용해 응답을 평가합니다. "빈칸 채우기"처럼 각 단계를 수행한 결과를 채워나갑니다.
# 2단계: 생성된 단계로 실제 평가
G_EVAL_SCORING_TEMPLATE = """다음 단계에 따라 응답의 품질을 평가하세요.
[소스 텍스트]
{source}
[평가할 요약]
{response}
[평가 단계]
{steps_formatted}
각 단계를 순서대로 수행한 뒤, 1-5점으로 최종 점수를 부여하세요.
점수 기준:
1: 기준을 전혀 충족하지 못함
2: 기준을 약간 충족
3: 기준을 보통 수준으로 충족
4: 기준을 잘 충족
5: 기준을 완벽하게 충족
JSON으로만 출력:
{{"step_analyses": [{{"step": "단계명", "finding": "관찰 내용"}}, ...],
"score": 1-5,
"justification": "2-3문장 근거"}}
"""
def g_eval_score(
source: str,
response: str,
eval_steps: list[str],
judge_model: str = "claude-opus-4-7",
use_prob_weighting: bool = False,
) -> dict:
"""
G-Eval 핵심 평가 함수.
use_prob_weighting=True: 토큰 확률 가중 점수 (API 지원 시)
"""
steps_formatted = "\n".join(
f"{i+1}. {step}" for i, step in enumerate(eval_steps)
)
raw = client.messages.create(
model=judge_model,
max_tokens=768,
messages=[{"role": "user", "content": G_EVAL_SCORING_TEMPLATE.format(
source=source,
response=response,
steps_formatted=steps_formatted,
)}]
).content[0].text.strip()
result = json.loads(raw)
# use_prob_weighting=True일 때:
# 각 점수(1~5)의 토큰 로그 확률을 가중 평균하면
# 단일 정수 샘플링보다 분산이 낮아짐
# Anthropic API는 현재 logprobs를 직접 노출하지 않으므로
# 실용적으로는 정수 점수를 여러 번 샘플링해 평균내는 방식 사용
return result
③ 확률 가중 점수화
CoT 단계를 포함하면 Spearman ρ가 2~3포인트 향상되고, 확률 가중 점수화는 분산을 줄이고 의미 판별력을 높입니다. Anthropic API가 logprobs를 직접 노출하지 않으므로, 실용적으로는 여러 번 샘플링 후 평균을 냅니다.
def g_eval_multi_sample(
source: str,
response: str,
eval_steps: list[str],
judge_model: str = "claude-sonnet-4-6",
n_samples: int = 5,
) -> dict:
"""
확률 가중 점수화의 실용적 대안: 다중 샘플링 후 평균.
단일 샘플보다 분산이 낮아집니다.
"""
scores = []
for _ in range(n_samples):
result = g_eval_score(source, response, eval_steps, judge_model)
scores.append(result["score"])
return {
"mean_score": round(sum(scores) / len(scores), 2),
"std": round(float(__import__("statistics").stdev(scores)), 2),
"scores": scores,
"stable": max(scores) - min(scores) <= 1, # 최대 1점 차이면 안정적
}
G-Eval 완전 파이프라인
class GEvalPipeline:
"""G-Eval 전체 파이프라인: 단계 생성 → 캐싱 → 평가"""
def __init__(self, task: str, criteria: dict[str, str]):
"""
criteria: {"차원명": "기준 설명", ...}
예: {"coherence": "요약이 원문과 사실적으로 일치하는가?",
"conciseness": "불필요한 내용 없이 핵심만 담았는가?"}
"""
self.task = task
self.criteria = criteria
self._cached_steps: dict[str, list[str]] = {}
def get_eval_steps(self, dimension: str) -> list[str]:
"""평가 단계 캐싱 — 동일 기준은 한 번만 생성"""
if dimension not in self._cached_steps:
self._cached_steps[dimension] = generate_eval_steps(
task_description=self.task,
criteria=self.criteria[dimension],
)
return self._cached_steps[dimension]
def evaluate(
self,
source: str,
response: str,
judge_model: str = "claude-opus-4-7",
) -> dict:
results = {}
for dim, _ in self.criteria.items():
steps = self.get_eval_steps(dim)
score_result = g_eval_score(source, response, steps, judge_model)
results[dim] = score_result["score"]
overall = round(sum(results.values()) / len(results), 2)
return {"dimension_scores": results, "overall": overall}
# 사용
pipeline = GEvalPipeline(
task="뉴스 기사 요약 품질 평가",
criteria={
"coherence": "요약이 원문과 사실적으로 일치하는가?",
"conciseness": "불필요한 내용 없이 핵심만 담았는가?",
"fluency": "자연스럽고 읽기 쉬운 문장인가?",
},
)
result = pipeline.evaluate(
source="[원문 뉴스 기사]",
response="[평가할 요약]",
)
G-Eval 한계: G-Eval은 가장 다재다능한 유형의 지표로, 거의 모든 사용 사례를 인간 수준의 정확도로 평가할 수 있습니다. 단, 주관적이고 사용 사례 특화 평가에 가장 적합합니다. 반면 API 비용이 높고, 판사 모델 업데이트 시 캘리브레이션 표류가 발생하며, 단계 생성 자체가 판사 모델의 품질에 의존합니다.
2. Prometheus 2 — 오픈소스 전용 판사
출처: Kim et al. 2024, EMNLP ("Prometheus 2: An Open Source Language Model Specialized in Evaluating Other Language Models")
핵심 아이디어: Prometheus 2는 GPT-4의 세밀한 평가 능력을 에뮬레이션하기 위해 파인튜닝됩니다. 직접 평가(DA)에는 Feedback Collection 데이터셋으로, 페어와이즈 비교(PWC)에는 Preference Collection 데이터셋으로 각각 별도 모델을 훈련한 뒤 가중치 병합으로 단일 모델을 만듭니다.
from prometheus_eval import PrometheusEval
from prometheus_eval.prompts import ABSOLUTE_PROMPT, RELATIVE_PROMPT
# Hugging Face에서 모델 로드 (로컬 실행, API 비용 없음)
# pip install prometheus-eval
judge = PrometheusEval(
model_id="prometheus-eval/prometheus-7b-v2.0",
absolute_grade_template=ABSOLUTE_PROMPT,
relative_grade_template=RELATIVE_PROMPT,
)
# ── 절대 평가 (Direct Assessment) ──────────────────
rubric_da = """
점수 기준:
1: 사실 오류가 있거나 질문과 무관한 응답
2: 부분적으로 정확하지만 중요한 내용 누락
3: 정확하고 관련 있지만 완전하지 않음
4: 정확하고 완전하며 유용함
5: 정확하고 완전하며 탁월하게 유용함
"""
instructions = ["Python에서 리스트를 정렬하는 방법은?"]
responses = ["sorted() 함수나 .sort() 메서드를 사용합니다..."]
ref_answers = ["Python에서 리스트를 정렬하는 방법은 두 가지입니다..."]
feedbacks, scores = judge.absolute_grade(
instructions=instructions,
responses=responses,
rubric=rubric_da,
reference_answers=ref_answers, # 선택적 — 없어도 동작
)
# scores: [4] feedbacks: ["응답이 두 가지 방법을 모두 언급했지만..."]
# ── 페어와이즈 비교 (Pairwise Comparison) ──────────
response_a = "sorted() 함수를 사용합니다."
response_b = "sorted()와 .sort()의 차이를 설명하면..."
feedbacks_pw, winners = judge.relative_grade(
instructions=instructions,
responses_A=[response_a],
responses_B=[response_b],
rubric=rubric_da,
reference_answers=ref_answers,
)
# winners: ["B"] → response_b가 더 나은 응답
가중치 병합의 의미
Prometheus 2의 BiGGen-Bench 버전은 Claude-3-Opus보다 절대 평가 태스크에서 높은 성능을 달성했습니다. 가중치 병합이 단순 공동 훈련보다 나은 결과를 내는 이유는, 두 태스크(DA, PWC)의 특성이 달라 각각 독립적으로 최적화한 뒤 합치는 것이 더 효과적이기 때문입니다.
# Prometheus 2 모델 선택 기준
PROMETHEUS_MODELS = {
"prometheus-7b-v2.0": {
"size": "7B",
"vram": "~14GB",
"use_case": "일반 목적, 중간 속도",
"pearson_r_with_gpt4": "0.60~0.65",
},
"prometheus-8x7b-v2.0": {
"size": "8×7B MoE",
"vram": "~95GB (4-bit 양자화 시 ~48GB)",
"use_case": "최고 성능, 고급 평가",
"pearson_r_with_gpt4": "0.65~0.70",
},
"prometheus-bgb-8x7b-v2.0": {
"size": "8×7B (BiGGen-Bench 특화)",
"vram": "~95GB",
"use_case": "다양한 능력 평가, Claude-3-Opus 수준",
"pearson_r_with_gpt4": "최고",
},
}
Prometheus 2 한계: 영어 중심 훈련 데이터, 도메인 일반화의 한계(BiGGen-Bench 외 태스크에서 성능 저하), GPU 요구사항(7B도 14GB VRAM), 그리고 훈련 데이터가 GPT-4 판정을 증류한 것이므로 GPT-4의 편향을 일부 상속합니다.
3. PAJAMA — 프로그램이 판사가 될 때
출처: Huang et al. 2025, ICML Workshop ("Time To Impeach LLM-as-a-Judge: Programs are the Future of Evaluation", arXiv:2506.10403)
이것은 패러다임 전환입니다. LLM에게 "이 응답을 평가하라"고 하는 대신, LLM에게 "이 기준을 평가하는 코드를 작성하라"고 합니다. 작성된 코드를 로컬에서 실행합니다.
PAJAMA는 판단 일관성을 평균 15.83% 개선하고 편향된 응답을 평균 23.7% 줄였습니다. 프로그램 판정을 모델로 증류하면 RewardBench의 CHAT-HARD 서브셋에서 Prometheus 대비 2.19%, JudgeLM 데이터셋 대비 8.67% 더 높은 성능을 달성하면서 비용은 약 3500배 절감합니다.
작동 원리
# PAJAMA 파이프라인
# 1단계: LLM으로 판사 프로그램(코드) 합성
# 2단계: 합성된 프로그램들을 약한 감독(Weak Supervision)으로 앙상블
# 3단계: 로컬 실행
# ── 1단계: 판사 프로그램 합성 ──────────────────────
PROGRAM_SYNTHESIS_PROMPT = """다음 평가 기준에 따라 LLM 응답을 평가하는
Python 함수를 작성하세요.
[평가 기준]
{criteria}
요구사항:
- 함수 시그니처: def judge(question: str, response: str) -> dict
- 반환값: {{"score": float(0~1), "reason": str, "passed": bool}}
- 외부 API 호출 없이 순수 Python 로직만 사용
- 평가 로직을 명확하고 감사 가능한 방식으로 구현
- 다음 기준 중 하나에 집중: 정확성/관련성/완전성/안전성/형식준수
Python 코드만 출력 (함수 정의만):"""
def synthesize_judge_program(
criteria: str,
judge_model: str = "claude-opus-4-7",
) -> str:
"""평가 기준을 실행 가능한 Python 함수로 변환"""
raw = client.messages.create(
model=judge_model,
max_tokens=1024,
messages=[{"role": "user", "content": PROGRAM_SYNTHESIS_PROMPT.format(
criteria=criteria
)}]
).content[0].text.strip()
# 코드 블록 제거 (```python ... ```)
if raw.startswith("```"):
raw = raw.split("```")[1]
if raw.startswith("python"):
raw = raw[6:]
return raw.strip()
# 사용 예시: 3개 기준에 대해 3개 프로그램 합성
criteria_list = [
"응답이 질문에 직접적으로 답하는가?",
"응답에 사실 오류나 오해의 소지가 있는 내용이 없는가?",
"응답이 유해하거나 편향된 내용을 포함하지 않는가?",
]
judge_programs = []
for criteria in criteria_list:
program_code = synthesize_judge_program(criteria)
judge_programs.append(program_code)
# ── 2단계: 프로그램 실행 + 약한 감독 앙상블 ──────────
import ast
import traceback
def execute_judge_program(
program_code: str,
question: str,
response: str,
) -> dict | None:
"""합성된 판사 프로그램 안전 실행"""
try:
# 안전성 검사: ast로 위험한 호출 탐지
tree = ast.parse(program_code)
for node in ast.walk(tree):
if isinstance(node, ast.Call):
func_name = ""
if isinstance(node.func, ast.Attribute):
func_name = node.func.attr
elif isinstance(node.func, ast.Name):
func_name = node.func.id
# 외부 I/O, 시스템 호출 차단
if func_name in {"open", "exec", "eval", "__import__",
"subprocess", "os", "sys"}:
return None
# 함수 정의 실행
namespace = {}
exec(program_code, namespace)
if "judge" not in namespace:
return None
result = namespace["judge"](question, response)
return result
except Exception:
return None # 실행 실패 시 이 프로그램 무시
def pajama_ensemble(
question: str,
response: str,
judge_programs: list[str],
weights: list[float] | None = None,
) -> dict:
"""
여러 판사 프로그램의 결과를 약한 감독으로 앙상블.
weights: 각 프로그램의 신뢰도 가중치 (None이면 균등)
"""
results = []
for i, program in enumerate(judge_programs):
result = execute_judge_program(program, question, response)
if result and "score" in result:
w = weights[i] if weights else 1.0
results.append((result, w))
if not results:
return {"score": 0.5, "confidence": "low", "n_programs": 0}
# 가중 평균
total_weight = sum(w for _, w in results)
weighted_score = sum(r["score"] * w for r, w in results) / total_weight
return {
"score": round(weighted_score, 3),
"confidence": "high" if len(results) >= 3 else "medium",
"n_programs_executed": len(results),
"n_programs_total": len(judge_programs),
"individual_scores": [r["score"] for r, _ in results],
}
PAJAMA 비용 비교
60,000개 예시 기준: PAJAMA는 $0.053, LLM-as-a-Judge는 $133~$184입니다.
60K 평가 기준 비용 비교:
LLM-as-a-Judge (API): $133~$184
PAJAMA (프로그램): $0.053
비율: ~3,500배 차이
왜 이렇게 싼가?
1. 프로그램 합성은 한 번만 (재사용)
2. 실행은 로컬 Python 인터프리터 (API 호출 없음)
3. 앙상블도 로컬 실행 (CPU만 필요)
PAJAMA 한계: 프로그램으로 표현할 수 없는 평가 기준(창의성, 미묘한 어조)에는 적합하지 않습니다. 합성된 코드의 정확성 검증이 필요하며, 반복적인 기준 재사용이 발생하는 문제를 6가지 다양성 기준으로 완화하지만 완전히 해결하지 못합니다. 수학·코드·안전성 같이 체크 가능한 기준에 가장 강력합니다.
4. Themis — 시나리오 의존 평가
출처: Hu et al. 2024, EMNLP ("Themis: A Reference-free NLG Evaluation Language Model with Flexibility and Interpretability")
기존 접근법들은 GPT-4 같은 독점 모델에 의존하거나(비용·재현 불가), 참조 답안 의존·유연성 부족·낮은 해석성 문제를 가집니다. Themis는 이 두 가지 한계를 동시에 해결하는 참조 없는 NLG 평가 모델입니다.
핵심 차별점: 시나리오 의존 프롬프트
Themis는 시나리오 의존적 평가 프롬프트와 두 가지 통제 지시 생성 방법을 포함하며, 교사 모델로부터 평가 능력을 효과적으로 증류하면서 지속 개발의 유연성을 유지합니다.
# Themis는 9개 NLG 태스크 × 여러 평가 차원에 맞는
# 시나리오별 프롬프트 템플릿을 내장합니다
THEMIS_SCENARIO_PROMPTS = {
"summarization": {
"coherence": """[요약 일관성 평가]
원문: {source}
요약: {response}
원문의 사실과 요약 내용을 대조해 일관성을 평가합니다.
1. 원문의 핵심 사실들을 파악합니다.
2. 요약의 각 주장이 원문과 일치하는지 확인합니다.
3. 원문에 없는 내용이 추가됐는지 확인합니다.
점수(1-5)와 근거를 JSON으로: {{"score": N, "rationale": "..."}}""",
"consistency": "...",
},
"dialogue": {
"engagement": """...""",
"naturalness": """...""",
},
"story_generation": {
"coherence": """...""",
"creativity": """...""",
},
# 9개 태스크 전체...
}
def themis_evaluate(
task: str,
dimension: str,
source: str,
response: str,
judge_model: str = "claude-sonnet-4-6",
) -> dict:
"""시나리오에 맞는 프롬프트로 평가"""
if task not in THEMIS_SCENARIO_PROMPTS:
raise ValueError(f"지원하지 않는 태스크: {task}")
if dimension not in THEMIS_SCENARIO_PROMPTS[task]:
raise ValueError(f"태스크 {task}에서 {dimension} 미지원")
prompt = THEMIS_SCENARIO_PROMPTS[task][dimension].format(
source=source, response=response
)
raw = client.messages.create(
model=judge_model, max_tokens=256,
messages=[{"role": "user", "content": prompt}]
).content[0].text.strip()
return json.loads(raw)
Themis는 Alibaba Cloud API로 서비스되며, Python OpenAI SDK와 호환됩니다. 데이터, 벤치마크, 모델 체크포인트가 오픈소스로 공개됩니다.
Themis vs Prometheus 2 선택 기준
항목 Prometheus 2 Themis
| 훈련 데이터 | Feedback/Preference Collection | NLG-Eval (58개 데이터셋, 0.5M 샘플) |
| 강점 | 커스텀 루브릭 자유도 | NLG 9개 태스크 특화 |
| 참조 답안 | 강력 권장 | 불필요 (참조 없이 동작) |
| 해석성 | CoT 피드백 제공 | 시나리오 프롬프트로 명확한 근거 |
| API 서비스 | HuggingFace 모델 | Alibaba Cloud API |
5. 증류된 판사 파이프라인 — 비용과 성능의 균형
네 프레임워크 중 어느 것을 선택하든, 프로덕션 규모에서 대형 API 판사(Opus 4.7, GPT-5.5)를 매 요청마다 쓰는 것은 비용이 지속 불가능합니다. **증류된 판사(Distilled Judge)**는 이 문제의 현실적 해결책입니다.
원리: 대형 판사의 판정 데이터로 소형 모델을 파인튜닝해, 대형 판사 수준의 판정 능력을 소형 모델에 이식합니다.
# ── 증류 데이터 수집 파이프라인 ──────────────────
def collect_distillation_data(
samples: list[dict], # [{"question": ..., "response": ...}, ...]
teacher_judge: str = "claude-opus-4-7",
eval_steps: list[str] = None,
n_samples_per_item: int = 3, # 안정성을 위해 3회 평균
) -> list[dict]:
"""
교사 판사의 판정을 수집해 증류 훈련 데이터 생성.
목표: 2,000~10,000개 판정 수집
"""
distillation_data = []
for sample in samples:
scores = []
rationales = []
for _ in range(n_samples_per_item):
result = g_eval_score(
source=sample.get("context", ""),
response=sample["response"],
eval_steps=eval_steps or [],
judge_model=teacher_judge,
)
scores.append(result["score"])
rationales.append(result.get("justification", ""))
# 안정적인 판정만 수집 (표준편차 낮은 것)
import statistics
if len(set(scores)) > 1:
std = statistics.stdev(scores)
if std > 0.8: # 불안정한 판정 제외
continue
distillation_data.append({
"question": sample["question"],
"response": sample["response"],
"teacher_score": round(sum(scores) / len(scores), 1),
"teacher_rationale": rationales[0], # 대표 근거
"score_std": round(statistics.stdev(scores), 2) if len(scores) > 1 else 0,
"teacher_model": teacher_judge,
})
return distillation_data
# ── 판사 계층 구조 ────────────────────────────────
JUDGE_HIERARCHY = {
"gold": {
"model": "claude-opus-4-7",
"cost_per_1m": 5.00,
"use_case": "황금 세트 캘리브레이션, 고위험 평가, 증류 교사",
"throughput": "느림",
},
"standard": {
"model": "claude-sonnet-4-6",
"cost_per_1m": 3.00,
"use_case": "일반 품질 모니터링, A/B 테스트",
"throughput": "보통",
},
"fast": {
"model": "claude-haiku-4-5-20251001",
"cost_per_1m": 0.25,
"use_case": "대량 스크리닝, CI 게이트",
"throughput": "빠름",
},
"local": {
"model": "prometheus-7b-v2.0 (로컬)",
"cost_per_1m": 0,
"use_case": "최대 처리량, 비용 민감 환경",
"throughput": "GPU 의존",
},
}
def route_judge(
task_importance: str, # "critical" | "standard" | "bulk"
requires_explanation: bool = False,
) -> str:
if task_importance == "critical" or requires_explanation:
return JUDGE_HIERARCHY["gold"]["model"]
elif task_importance == "standard":
return JUDGE_HIERARCHY["standard"]["model"]
else:
return JUDGE_HIERARCHY["fast"]["model"]
6. 프레임워크 선택 기준 — 결정 트리
[질문 1] 참조 답안이 있는가?
→ 있음: Prometheus 2 (참조 활용 시 최고 성능)
→ 없음: 다음 질문
[질문 2] 특정 NLG 태스크(요약/대화/스토리)인가?
→ 예: Themis (태스크 특화 프롬프트)
→ 아니오: 다음 질문
[질문 3] 평가 기준이 코드로 표현 가능한가?
(수학, 코드 정확성, 형식 준수, 안전성 등)
→ 예: PAJAMA (3500× 비용 절감)
→ 아니오: 다음 질문
[질문 4] GPU 인프라가 있는가?
→ 있음: Prometheus 2 로컬 (API 비용 없음)
→ 없음: 다음 질문
[질문 5] 평가 기준이 자주 바뀌는가?
→ 예: G-Eval (단계 자동 생성, 유연성 최고)
→ 아니오: G-Eval 또는 Prometheus 2 API
7. 프레임워크별 수치 비교
프레임워크 인간 일치율 비용 참조 필요 강점 약점
| G-Eval | Spearman 0.514 (요약) | API 호출 | 선택적 | 유연성, 어떤 기준이든 | 캘리브레이션 표류 |
| Prometheus 2 | Pearson 0.60~0.70 with GPT-4 | 무료 (로컬) | 권장 | 오픈소스, 재현성 | GPU 필요, 영어 중심 |
| PAJAMA | Consistency +15.83% | $0.053/60K | 불필요 | 비용, 감사 가능성 | 코드화 불가 기준 |
| Themis | NLG 태스크 고성능 | API | 불필요 | 태스크 특화 | 범위 제한적 |
| Distilled Judge | 교사 수준 근접 | 0 (로컬) | 교사 필요 | 비용·속도 | 초기 증류 비용 |
✅ 4편 정리
"원시 판사 점수는 캘리브레이션 없이 크로스 스터디나 시간 비교에 직접 사용해선 안 됩니다. 점수는 표류합니다." 이것이 프레임워크를 선택하는 것보다 더 중요한 원칙입니다.
프레임워크 언제 쓰나
| G-Eval | 기준이 자주 바뀌고 참조가 없는 오픈엔드 평가 |
| Prometheus 2 | 재현성·비용·투명성이 모두 중요한 팀 |
| PAJAMA | 코드로 검증 가능한 기준, 대규모 배치 |
| Themis | 요약·대화 등 NLG 태스크 특화 |
| Distilled Judge | 프로덕션 규모, 속도·비용이 주 제약 |
선택보다 중요한 것은 어떤 프레임워크를 쓰더라도 황금 세트 + Cohen's κ + 캘리브레이션 주기를 갖추는 것입니다. 5편에서 이것을 구체적으로 다룹니다.
LLM-as-a-Judge 완전정리 시리즈 — 완결
- ✅ 1편 — 왜 기존 지표는 죽었고, 세 패러다임은 무엇인가 https://cell-devlog.tistory.com/265
- ✅ 2편 — 판사는 어디서 거짓말하나: 7가지 편향 해부 https://cell-devlog.tistory.com/266
- ✅ 3편 — 편향 잡는 법: Position Swap부터 Cross-family까지 https://cell-devlog.tistory.com/267
- ✅ 4편 — G-Eval vs Prometheus 2 vs PAJAMA vs Themis https://cell-devlog.tistory.com/268
- ✅ 5편 — 판사를 평가하기: Cohen's κ, Bradley-Terry, 황금 세트 설계 https://cell-devlog.tistory.com/269
- ✅ 6편 — 프로덕션 파이프라인: 샘플링·CI 게이트·캘리브레이션 주기 https://cell-devlog.tistory.com/270
- ✅ 7편 — 한계와 대안: LLM 판사가 절대 못 하는 것들 https://cell-devlog.tistory.com/271
'AI Agent' 카테고리의 다른 글
| LLM as a Judge 완전정리 6편 — 프로덕션 파이프라인: 샘플링·CI 게이트·캘리브레이션 주기 (0) | 2026.05.26 |
|---|---|
| LLM as a Judge 완전정리 5편 — 판사를 평가하기: Cohen's κ, Bradley-Terry, 황금 세트 설계 (0) | 2026.05.26 |
| LLM as a Judge 완전정리 3편 — 편향 잡는 법: 전략별 코드와 효과 비교 (0) | 2026.05.26 |
| LLM as a Judge 완전정리 2편 — 판사는 어디서 거짓말하나: 7가지 편향 해부 (0) | 2026.05.26 |
| LLM as a Judge 완전정리 1편 — 왜 기존 평가 지표는 죽었고, 무엇이 그 자리를 차지했나 (0) | 2026.05.26 |