🔥 고급2026-09-286~8분
LLM 평가 파이프라인 설계: 모델 교체 전 회귀를 잡는 자동화 평가 아키텍처
모델 버전 업그레이드나 프롬프트 변경 시 품질 회귀를 사전에 탐지하려면 judge 모델 기반 자동 평가 파이프라인이 필수다. 평가 지표 설계부터 CI 통합까지 실전 수치와 함께 정리한다.
evaluationllm-opsci-cd
왜 수동 평가는 프로덕션에서 실패하는가
팀이 성장하면서 프롬프트 변경 빈도가 주 3회 이상이 되면, 사람이 직접 샘플링해 평가하는 방식은 세 가지 이유로 무너진다.
- 샘플 편향: 평가자가 무의식적으로 "좋아 보이는" 응답을 고름
- 커버리지 한계: 1,000개 케이스를 사람이 매번 보는 건 불가능
- 재현 불가: 기준이 사람마다, 날마다 달라져 회귀 탐지 신뢰도 하락
실측: judge 모델 평가와 인간 평가의 Spearman 상관계수는 claude-3-5-sonnet 기준 0.82~0.89 수준 (내부 데이터셋 기준). 완벽하지 않지만 자동화 gate로 충분하다.
Judge 모델 패턴 구현
import anthropic
from dataclasses import dataclass
client = anthropic.Anthropic()
JUDGE_PROMPT = """당신은 AI 응답 품질을 평가하는 전문 평가자입니다.
[입력]
{input}
[응답]
{response}
[기준]
- 정확성(0-4): 사실 오류 없음
- 완결성(0-4): 질문의 모든 요소 다룸
- 간결성(0-2): 불필요한 반복 없음
각 항목 점수와 근거를 JSON으로만 출력:
{{"accuracy": N, "completeness": N, "conciseness": N, "reason": "..."}}"""
@dataclass
class EvalResult:
accuracy: int
completeness: int
conciseness: int
total: int
reason: str
def judge(input_text: str, response: str) -> EvalResult:
import json
msg = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=256,
messages=[{
"role": "user",
"content": JUDGE_PROMPT.format(input=input_text, response=response)
}]
)
data = json.loads(msg.content[0].text)
return EvalResult(
accuracy=data["accuracy"],
completeness=data["completeness"],
conciseness=data["conciseness"],
total=data["accuracy"] + data["completeness"] + data["conciseness"],
reason=data["reason"]
)
def run_eval_suite(test_cases: list, threshold: float = 7.5) -> bool:
scores = [judge(tc["input"], tc["response"]).total for tc in test_cases]
avg = sum(scores) / len(scores)
print(f"평균 점수: {avg:.2f}/10 | 기준: {threshold}")
return avg >= threshold # CI gate: False면 배포 차단
트레이드오프와 운영 체크리스트
judge 모델 선택 트레이드오프
| 모델 | 정확도 | 비용/1000케이스 | 속도 | |------|--------|----------------|------| | claude-3-5-sonnet | 높음 | ~$1.2 | 중간 | | claude-3-5-haiku | 중간 | ~$0.25 | 빠름 |
권장: 초기 gate는 haiku로 빠르게 돌리고, 점수 경계값(±0.5) 케이스만 sonnet으로 재평가하는 2단계 판정 구조.
실패 모드
- Judge 모델이 응답 길이에 편향될 수 있음 → 간결성 항목을 별도 분리해 가중치 조정
- 테스트셋 오염: 프롬프트 개발자가 test case를 보며 튜닝하면 평가 의미 없음 → test set을 별도 repo에 격리
- 점수 인플레이션: judge에게 "엄격하게" 명시하지 않으면 평균 8점 이상으로 수렴
운영 체크리스트
- [ ] test case 최소 200개, 엣지케이스 20% 이상 포함
- [ ] 평가 결과를 시계열로 저장해 점수 추세 모니터링
- [ ] PR마다 CI에서
run_eval_suite()실행, 기준 미달 시 merge 차단 - [ ] judge 프롬프트 자체도 버전 관리 (평가 기준 변경 이력 추적)
- [ ] 월 1회 인간 평가로 judge 모델 calibration 확인