LLM 평가 하네스: 프롬프트 개선을 숫자로 증명하기
들어가며
프롬프트를 고치고 몇 가지 입력으로 돌려 보니 답이 좋아진 것 같습니다. 그런데 정말 나아졌다고 말할 수 있을까요? 반대로 공들여 고쳤는데 점수가 그대로라면, 수정이 효과가 없는 걸까요, 아니면 점수를 재는 쪽이 고장 난 걸까요?
이런 질문에 답하려면 평가 하네스가 필요합니다. 이번 글에서는 하네스의 구성과 정답지, 반복 실행, 기준선 재현, LLM 심판을 정리하고, 운영 단계의 가드레일과 어떻게 다른지까지 다룹니다.
1. 평가 하네스의 구성
평가 하네스는 같은 입력, 같은 채점기, 여러 번 실행으로 모델 출력을 재고 조건끼리 비교하는 틀입니다. 프롬프트나 모델을 바꿀 때마다 같은 절차로 돌리므로, 숫자의 차이를 바꾼 조건의 영향으로 읽을 수 있습니다.
평가 하네스는 다이어트할 때 늘 같은 조건으로 재는 저울이에요.
여기서 정답지(golden set)는 사람이 확인한 정답 묶음입니다. 모델 A와 모델 B의 출력을 서로 비교하는 것만으로는 어느 쪽이 맞는지 가릴 수 없기 때문에 필요합니다. 처음에는 수십 건이어도 괜찮지만, 쉬운 입력만 모으지 말고 실제로 틀리기 쉬운 경우를 함께 넣어야 합니다.
2. 반복 실행과 자기 편차
LLM은 같은 입력에도 답이 조금씩 갈립니다. 온도(temperature)를 0으로 둬도 마찬가지입니다. 온도는 샘플링의 무작위성을 줄일 뿐이고, 서빙 쪽의 연산이나 모델 갱신 때문에 출력이 달라질 수 있습니다.
그래서 필요한 것이 자기 편차입니다. 같은 조건을 여러 번 돌렸을 때 점수가 얼마나 흔들리는지를 뜻합니다. 조건 간 차이가 이 흔들림보다 작다면, 그 차이는 개선의 근거가 되지 못합니다.
자기 편차는 같은 체중계에 여러 번 올라갔을 때의 눈금 흔들림이에요.
- 옛 조건 0.821회
- 새 조건 0.841회
- 옛 조건 평균 0.82편차 0.03
- 새 조건 평균 0.84편차 0.03
- 차이 0.02편차 2배인 0.06보다 작음
3. 기준선 재현: 자부터 점검합니다
채점기도 코드라 고장이 납니다. 까다로운 점은 고장 나도 멈추지 않고 그럴듯한 숫자를 낸다는 것입니다. 모델 출력 형식이 바뀌어 파싱이 실패하고 전부 0점 처리되거나, 필드 이름이 바뀌어 기본값만 비교하는 식입니다.
기준선 재현은 새 조건을 재기 전에 옛 조건을 다시 돌려, 기록해 둔 수치가 나오는지 보는 확인입니다. 안 나온다면 모델이 아니라 채점기나 데이터 쪽을 먼저 의심해야 합니다. 특히 "차이 없음"이라는 결과는 누구도 의심하지 않기 때문에 조용히 넘어가기 쉽습니다.
from statistics import mean, stdev
base = score(run(OLD))
assert abs(base - BASELINE) < TOL # 자 점검: 옛 수치가 재현되는가
a = [score(run(OLD)) for _ in range(5)]
b = [score(run(NEW)) for _ in range(5)]
gap = mean(b) - mean(a)
noise = max(stdev(a), stdev(b))
# 어림 기준: 차이가 편차의 2배를 넘을 때만 개선으로 본다
print("개선" if gap > 2 * noise else "보류")2배는 빠르게 걸러 내기 위한 어림 기준입니다. 결정이 무거울수록 반복 횟수를 늘리고, 입력별로 짝지어 비교하거나 부트스트랩 신뢰 구간을 구하는 쪽이 더 믿을 만합니다.
두 가지 확인을 합치면 결과를 읽는 순서가 정해집니다.
판정 순서는 몸무게를 읽기 전에 저울이 0을 가리키는지 먼저 보는 일이에요.
| 판정 | 기준선 재현 | 차이 큼 |
|---|---|---|
| 새 조건 채택개선 인정 | ||
| 보류반복 늘리기 | ||
| 채점기 수리숫자 무시 | 해석 안 함 |
4. LLM-as-a-judge: 심판도 채점기입니다
요약의 품질이나 답변의 친절함처럼 규칙으로 재기 어려운 항목은 다른 LLM에게 채점을 맡기기도 합니다. 싸고 빠르지만 그대로 믿으면 안 됩니다. 긴 답을 후하게 주거나, 먼저 제시한 답을 선호하는 식의 편향이 있을 수 있기 때문입니다.
그래서 정답지 일부로 심판과 사람의 일치율을 먼저 재고, 답의 순서와 길이를 바꿔도 점수가 유지되는지 점검합니다. 심판도 채점기이므로 기준선 재현과 자기 편차 규칙이 똑같이 적용됩니다.
5. 가드레일: 운영 중의 검사
평가 하네스가 배포 전에 조건을 비교하는 도구라면, 가드레일은 운영 중에 요청 하나하나를 검사하는 장치입니다. 입력에서는 프롬프트 인젝션이나 범위 밖 질문을 걸러 내고, 출력에서는 JSON 스키마 위반, 개인정보 노출, 금지 표현을 확인합니다. 규칙을 어긴 답은 막거나 고쳐 쓰거나 다시 생성합니다.
def guarded_answer(question):
answer = llm(question)
if not schema_ok(answer) or has_pii(answer):
return FALLBACK_MESSAGE # 막고 안전한 안내로 대체
return answer둘은 이어져 있습니다. 가드레일에 걸린 사례를 모아 정답지에 추가하면 다음 평가가 실제 실패를 반영합니다. 가드레일 자체도 지연 시간과 오탐이 있으니, 평가 항목에 넣어 함께 잽니다.
헷갈리기 쉬운 점
- 온도 0이어도 한 번만 돌려서는 안 됩니다. 온도 0은 재현을 보장하는 설정이 아닙니다. 같은 조건을 반복해 편차를 재야 차이를 해석할 수 있습니다.
- 평균 점수가 올랐다고 개선은 아닙니다. 편차보다 작은 차이는 우연일 수 있고, 평균이 올라도 특정 유형의 입력은 크게 나빠졌을 수 있습니다. 유형별 점수도 함께 봅니다.
- "차이 없음"은 효과가 없다는 뜻만은 아닙니다. 채점기가 고장 나 양쪽 다 같은 값을 냈을 수 있습니다. 기준선 재현을 먼저 확인합니다.
면접에서 자주 받는 질문
프롬프트를 고친 뒤 나아졌다는 것을 어떻게 증명하나요?
먼저 옛 조건으로 기록된 수치가 재현되는지 확인해 채점기를 검증합니다. 그다음 같은 입력과 사람이 확인한 정답지로 두 조건을 각각 여러 번 돌리고, 조건 간 차이가 자기 편차보다 충분히 큰지 봅니다.
LLM-as-a-judge는 믿을 만한가요?
그대로 믿지 않습니다. 사람 정답지 일부로 심판과 사람의 일치율을 먼저 재고, 순서와 길이에 따른 편향을 점검합니다. 심판도 하나의 채점기이므로 기준선 재현 규칙을 똑같이 적용합니다.
검증 에이전트를 여러 개 두면 충분한가요?
독립된 검토자를 늘리면 잡아내는 오류는 늘지만, 같은 맹점을 공유하면 함께 놓칩니다. 그래서 마지막 기준은 사람 정답지와 원자료 대조로 두는 것이 안전합니다.
정리
- 평가 하네스는 같은 입력과 같은 채점기로 여러 번 돌려 조건을 비교하는 틀입니다.
- 결과를 읽기 전에 기준선이 재현되는지, 차이가 자기 편차보다 큰지를 확인합니다.
- 가드레일은 운영 중의 검사이고, 여기서 잡힌 실패는 다시 정답지로 돌아갑니다.
결과가 이상할 때는 모델보다 자를 먼저 의심하시기 바랍니다.