AI 연재 2/9 — 판단이 맞는지 어떻게 아는가: 평가셋, LLM 판정자, 트레이싱
1편에서 파이프라인을 단계로 쪼개고 구조화 출력으로 형식을 고정했다. 그런데 형식이 맞는 것과 판단이 맞는 것은 다르다. 이번 편은 "잘 돌아간다는 걸 어떻게 증명하는가"다.
솔직히 이 주제는 개발자들 사이에서도 가장 대충 넘어가는 부분이다. 데모 몇 개 돌려 보고 "괜찮은데?" 하는 순간 평가는 끝난다. 그리고 프롬프트를 한 줄 고친 뒤에 어디가 나빠졌는지 아무도 모른다.
평가셋은 작게, 실패에서 시작한다
Anthropic의 "Demystifying evals for AI agents"에서 가장 실용적인 조언은 시작 규모다. 실제 실패 사례에서 뽑은 20~50개의 단순한 과제로 시작하라는 것이다. 수천 개짜리 벤치마크를 만들려다 아무것도 못 하는 것보다 낫다.
(이 글은 요약 도구를 통해 읽었고, 정확한 게시일과 저자는 확인하지 못했다. 인용 전 원문을 직접 확인하기를 권한다.)
같은 글에서 채점기를 세 종류로 나눈다.
| 종류 | 장점 | 약점 |
|---|---|---|
| 코드 기반 | 빠르고 객관적 | 정상적인 변형에도 실패 처리하기 쉽다 |
| 모델 기반 | 유연하다 | 비결정적이고 보정이 필요하다 |
| 사람 | 기준점이 된다 | 느리고 비싸다 |
보상 신청 예시로 옮기면 이렇다. 승인/보류/거절 같은 enum 결과는 코드로 채점한다. 근거 설명이 타당한지는 모델이나 사람이 본다. 둘을 섞어야 한다.
한 가지 더 짚을 개념이 있다. pass@k와 pass^k다. 같은 글의 정의로는 pass@k는 k번 시도 중 한 번이라도 성공할 확률이고, pass^k는 k번 모두 성공할 확률이다. k가 커지면 pass@k는 오르고 pass^k는 떨어진다. 고객 응대처럼 매번 일관돼야 하는 서비스에서는 pass^k 쪽이 현실을 더 잘 반영한다. 한 번 맞았다고 믿을 수 없다는 뜻이다.
평가셋을 두 종류로 나누는 것도 도움이 된다. 어려운 과제로 구성되고 통과율이 낮은 capability eval, 그리고 거의 100%를 유지해야 하는 regression eval. 개선된 capability 과제는 시간이 지나면 regression으로 졸업한다. 또 하나, 같은 글은 평가 트랜스크립트를 직접 읽는 것이 필수라고 강조한다. 점수만 보면 채점기가 잘못된 건지 모델이 잘못된 건지 구분이 안 된다.
OpenAI 쪽 가이드도 같은 방향이다. eval-driven development, 즉 과제를 평가로 먼저 정의하고 돌려서 분석한 뒤 반복하라는 접근이다. 참고로 이 문서에는 OpenAI Evals 플랫폼이 2026-10-31에 읽기 전용이 되고 2026-11-30에 종료될 예정이라는 공지가 있었다. 이관 경로는 자세히 확인하지 못했다. 이 공지가 주는 교훈은 간단하다. 평가셋은 특정 플랫폼에 가두지 말고 JSONL 같은 자체 포맷으로 직접 들고 있자.
LLM을 판정자로 쓸 때 조심할 것
사람이 일일이 채점할 수 없으니 LLM에게 채점을 맡기는 건 자연스러운 선택이다. 이 방식의 대표 논문이 Zheng 등의 "Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena"(2023, arXiv 2306.05685)다. 초록 기준으로 GPT-4급 판정자가 인간 선호와 80% 이상 일치했고, 이는 사람들 사이의 일치 수준과 비슷하다고 보고한다. 동시에 한계도 명시한다. 위치 편향(position bias), 장황함 편향(verbosity bias), 자기 모델 선호(self-enhancement bias), 그리고 제한적인 추론 능력이다.
초록만 보고 쓰기엔 아쉬워서 본문 PDF도 읽었다. 확인한 수치는 이렇다. 표에서 읽은 숫자라 정확한 행 대응은 원문 대조를 권한다.
- 위치 편향: 두 답변의 순서를 바꿨을 때 같은 결과가 나오는 비율(consistency)이 GPT-4 65.0%, GPT-3.5 46.2%, Claude-v1 23.8%였다. 판정자에 따라 편차가 크다.
- 완화 1, 위치 스왑: 순서를 바꿔 두 번 판정하고 두 번 모두 이긴 쪽만 승자로 인정하며, 엇갈리면 무승부로 처리한다. few-shot 예시를 주면 GPT-4의 consistency가 65.0%에서 77.5%로 올랐지만, 논문은 일관성이 높다고 정확도가 높은 건 아니라고 덧붙이고 프롬프트가 길어져 호출 비용이 약 4배가 된다고 적었다.
- 장황함 편향: 정보는 늘리지 않고 목록 항목만 바꿔 쓴 "repetitive list" 공격에 Claude-v1과 GPT-3.5는 91.3%가 속았고 GPT-4는 8.7%였다. 이 논문은 이 편향에 대한 전용 완화책은 제시하지 않았다.
- 자기 선호 편향: GPT-4가 자기 모델의 승률을 사람보다 10%p, Claude-v1이 25%p 높게 줬지만 GPT-3.5는 그렇지 않았고, 논문 스스로 데이터가 적어 존재 여부를 판정할 수 없다고 결론 내렸다. 즉 "시사되지만 입증되지 않았다"가 정확한 표현이다.
- 일치율: 동점을 제외하면 GPT-4와 인간 전문가의 일치가 85%, 인간끼리가 81%였다.
- 수학·추론 채점은 기본 프롬프트가 20문항 중 14개를 틀렸고, 정답을 함께 주는 reference-guided 방식은 3개로 줄었다.
판정자에게 정답 기준을 같이 주는 게 효과가 컸다는 점이 실무적으로 가장 쓸모 있었다. 다만 2023년 모델 기준 수치라서 오늘의 모델에 그대로 적용된다고 말할 수는 없다.
실무로 옮길 때 지킬 만한 원칙은 이렇다. 출처가 있는 건 첫째 항목뿐이고 나머지는 편향 목록에서 도출한 설계 권고다.
- 판정자는 사람 라벨과 보정한다. Anthropic 글도 모델 채점기는 보정이 필요하다고 한다. 사람이 채점한 샘플과 일치도를 먼저 재 본 뒤에 믿는다.
- 위치 편향이 의심되면 두 답변의 순서를 바꿔 두 번 채점한다.
- 루브릭은 구체적이고 이진에 가깝게 쓴다. "좋은 답변인가?" 대신 "근거로 인용한 서류가 실제로 해당 주장을 뒷받침하는가?"
- 생성 모델과 다른 계열의 판정자를 쓰는 걸 고려한다.
- 판정 프롬프트를 바꾸면 이전 점수와 직접 비교하지 않는다. 판정자도 버전 관리 대상이다.
판정자 점수를 진실로 취급하는 순간, 평가가 가장 위험한 도구가 된다. 틀린 판정자는 틀린 방향으로 자신 있게 개선을 이끈다.
오프라인, 온라인, 그리고 회귀
평가는 두 시점에 돈다.
오프라인 평가는 배포 전이다. 프롬프트, 모델, 스키마를 바꿀 때마다 CI에서 평가셋을 돌린다. 회귀 평가가 이 역할이다. 모델 버전은 고정(pin)해 두고, 업그레이드는 회귀 평가를 통과한 뒤에 한다. 이건 일반적인 엔지니어링 습관이다.
온라인 평가는 배포 후다. 실제 트래픽의 일부를 샘플링해 사람이나 판정자가 검토하고, 사용자 피드백을 모으고, 입력 분포가 변하는지(드리프트) 본다. 여기서 발견된 실패 사례가 오프라인 평가셋으로 환류되면 평가셋이 점점 현실에 가까워진다. 이 순환이 평가의 핵심이다.
흔한 실패 몇 가지를 적어 둔다. 전부 일반 지식이고 인용할 출처는 없다.
- 평균 정확도만 본다. 보상 승인에서 오승인과 오거절의 비용은 다르다. 클래스별, 오류 유형별로 봐야 한다.
- 평가셋에 쉬운 케이스만 있다.
- 평가셋에 맞춰 프롬프트를 튜닝하다가 평가셋에 과적합된다. 일부는 튜닝에 쓰지 않는 홀드아웃으로 남긴다.
트레이싱: 왜 이 결과가 나왔는지 따라가기
평가가 "맞는가"를 알려준다면 트레이싱은 "왜"를 알려준다. 한 건의 보상 신청이 추출, 분류, 판단, 후처리를 거치는 전 과정을 하나의 trace로 묶고, 각 단계를 span으로 기록한다.
표준화 노력도 있다. OpenTelemetry에는 GenAI semantic conventions가 있고, 내가 확인한 시점의 상태는 아직 Development, 즉 안정판이 아니다. 속성명이 바뀔 수 있다. 내용도 확인한 범위에서만 적으면 이렇다.
- 규약은 원래
semantic-conventions저장소에 있었지만 별도 저장소(semantic-conventions-genai)로 옮겨졌다고 opentelemetry.io의 기존 페이지에 안내돼 있다. 이전 시점이 2026-06이라는 건 블로그 글 같은 2차 자료로만 확인했다. - 안정판 승격 여부는 2026-07 기준 2차 자료에서 승격 사례가 없다는 정도만 알고, 오늘 시점은 확인하지 못했다. 환경변수로 최신 실험판을 고르는 방식(
OTEL_SEMCONV_STABILITY_OPT_IN)이 있다는 것도 2차 자료다. - 추론 호출 span의 필수 속성은
gen_ai.operation.name,gen_ai.provider.name,gen_ai.request.model이다. - 토큰 사용량은
gen_ai.usage.input_tokens,gen_ai.usage.output_tokens로 기록한다. - 프롬프트와 응답 원문(
gen_ai.input.messages등)은 개인정보가 포함될 가능성이 높아서 opt-in으로 두라는 경고가 붙어 있다.
여기에 우리 쪽 속성을 더 붙이는 게 실용적이다. 프롬프트 버전, 스키마 버전, 재시도 횟수, 검증 게이트 통과 여부 같은 것들이다. 이건 표준에 있는 게 아니라 내 제안이다.
원문 저장은 정책부터
프롬프트와 응답 원문을 전부 로그에 남기면 디버깅은 편해지지만 개인정보 문제가 따라온다. 마스킹, 보존 기간, 접근 권한을 정하고 나서 저장 여부를 결정하자. 보상 서비스처럼 서류가 오가는 시스템이라면 더 그렇다.
벤더 SDK 고유의 로깅 포맷에만 의존하면 나중에 바꾸기 힘들다. 다만 OTel의 GenAI 규약이 아직 불안정하니 어느 쪽에 걸지는 조금 고민이 된다. 이 고민은 아직 못 풀었다.
연재 목차: 1편 · 2편(현재) · 3편 고위험 판단 설계
참고자료
- Anthropic, Demystifying evals for AI agents
- Zheng et al., Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena (2023)
- OpenAI, Evals 가이드
- OpenTelemetry, GenAI semantic conventions (spans)
