본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 17. 06:36

AI 평가(Evals), 파트 3: 거짓말을 하지 않는 골든 데이터셋 (Golden Datasets)

요약

프로덕션 환경에서 AI 모델의 성능을 정확히 측정하기 위한 '골든 데이터셋(Golden Datasets)' 구축 방법을 다룹니다. 실제 입력값의 분포를 반영하는 대표성과 고품질의 참조 답변을 확보하는 것이 핵심입니다.

핵심 포인트

  • 골든 데이터셋은 모델 출력값을 대조하는 가장 중요한 척도임
  • 실제 프로덕션의 복잡한 케이스를 반영하는 대표성이 필수적임
  • 단순한 happy-path가 아닌 엣지 케이스와 적대적 케이스를 포함해야 함
  • 참조 답변의 품질이 평가 점수의 상한선(ceiling)을 결정함

_ .NET 기반의 프로덕션 AI 구축에 관한 시리즈의 파트 3입니다. 파트 1은 개요였고, 파트 2는 오류 분석(error analysis)이었습니다. 이제 여러분이 구축한 실패 분류 체계(failure taxonomy)를 스스로를 속이지 않으면서 측정 가능한 무언가로 전환해 보겠습니다._

골든 데이터셋(Golden dataset)은 대표적인 입력값들의 집합이며, 각 입력값은 지식 있는 인간이 수용할 만한 참조 답변(reference answer)과 쌍을 이룹니다. 이는 모든 모델 출력값을 대조하는 척도(ruler)입니다. 그리고 제 경험상, 이는 평가 파이프라인(eval pipeline)에서 가장 중요하면서도 가장 소홀히 다뤄지는 자산입니다. 왜냐하면 허술한 척도는 스스로를 드러내지 않기 때문입니다. 점수는 여전히 녹색(양호)으로 나오겠지만, 단지 잘못된 것을 측정하고 있을 뿐입니다.

이 포스트는 진실을 말해주는 골든 세트(golden set)를 구축하는 방법에 관한 것입니다.

실제 적용 모습

TextStack에서는 각 AI 기능마다 약 30개의 수동 큐레이션된 케이스(hand-curated cases)가 일반 JSON 형식으로 저장되며, 런타임에 프로덕션 엔드포인트(production endpoint)가 받는 것과 정확히 일치하는 타입화된 레코드(typed record)로 로드됩니다:

public record ExplainGolden(
    string Word,
    string Sentence,
...

디스크에 저장된 일반 JSON이며, 대소문자를 구분하지 않고 역직렬화(deserialised)됩니다. 데이터베이스도 없고, 플랫폼 종속성(platform lock-in)도 없습니다. 데이터셋은 코드 리뷰에서 차이점(diff)을 확인할 수 있는 체크인된 아티팩트(artifact)입니다:

var goldens = GoldenData.Load<ExplainGolden>("explain.json");

형식은 쉬운 부분입니다. 정직함은 _콘텐츠(content)_의 네 가지 속성에 달려 있습니다.

1. 대표성(Representativeness) — 데모가 아닌 현실을 반영하라

여러분의 세트는 어렵고, 이상하며, 적대적인(adversarial) 케이스를 포함하여, 프로덕션 환경에서 기능이 마주치는 실제 입력값의 분포를 반영해야 합니다. 여기서 파트 2의 성과가 나타납니다. 실패 분류 체계(failure taxonomy)는 어떤 종류의 입력이 문제를 일으키는지 알려주므로, 여러분은 의도적으로 해당 케이스들을 세트에 채워 넣을 수 있습니다.

그 반대 상황, 즉 쉽고 순탄한 경로(happy-path)의 케이스로만 구성된 세트는 평가(eval)가 거짓말을 하게 만드는 가장 흔한 방식입니다. 모델은 이를 완벽하게 통과하고 평균 점수는 올라가지만, 정작 중요한 입력값들은 전혀 측정되지 않습니다. 의도적으로 계층화(Stratify)하십시오: 도메인, 길이, 언어, 엣지 케이스(edge cases) 등을 포함해야 합니다. TextStack의 Explain 세트의 경우, 이는 기술적 구절과 일상적인 산문, 흔한 단어와 희귀한 단어, 그리고 여러 타겟 언어를 포함하는 것을 의미합니다. 단순히 똑같은 쉬운 조회 작업의 30가지 변형을 만드는 것이 아닙니다.

2. 참조 품질(Reference quality) — 당신이 측정하는 기준점(ceiling)

참조 정답(reference answer)은 해당 케이스에서 무엇이 "좋은" 것인지를 정의하므로, 게으른 참조는 전체 점수의 의미를 제한해 버립니다. 만약 _idempotent(멱등성)_를 설명하는 참조가 단순히 사전적 정의를 바꾸어 쓴 것에 불과하다면, 당신의 평가자(judge)는 기꺼이 사전적 정의에 높은 점수를 줄 것입니다. 이는 당신이 제거하려고 노력했던 바로 그 실패 모드(failure mode)입니다.

참조는 해당 도메인을 이해하는 사람이 작성하거나 검증해야 합니다. Explain의 경우, 이는 진정으로 훌륭한 문맥 내 설명(in-context explanations)을 의미합니다. 즉, 그 단어가 여기, 문장에서 무엇을 의미하는지, 당신이 설명을 듣고 싶어 하는 바로 그 방식이어야 합니다. 참조는 기준점(bar)입니다. 제품이 실제로 도달하기를 원하는 수준으로 기준을 설정하십시오.

3. 누출(Leakage) — 실제 훈련/테스트 분할(train/test split)을 유지하라

여기에 미묘한 통계적 죄악이 있습니다. 만약 점수를 매기는 것과 동일한 케이스를 대상으로 프롬프트를 튜닝한다면, 당신은 테스트 데이터에 과적합(overfitting)되는 것이며, 당신의 수치는 허구입니다. 당신은 기능(feature)이 아니라 그 30개의 예시에 최적화한 것입니다. 이는 테스트 세트로 학습(training)하는 것의 프롬프트 엔지니어링 버전입니다.

반복 작업(iterating)을 하는 동안 절대 들여다보지 않는 데이터 조각을 남겨두십시오. 한 부분으로 튜닝하고, 남겨둔(held-out) 부분으로 보고하십시오. 30개의 케이스를 대상으로 하기에는 번거롭게 느껴질 수 있지만, 이러한 규율이 반복 작업 중에도 점수를 의미 있게 유지해 줍니다. 데이터 분할은 모델 가중치(model weights)뿐만 아니라 프롬프트에서도 똑같이 실질적인 원칙입니다.

4. 크기와 신선도(Size and freshness) — 하한선이자 살아있는 자산

30개의 케이스는 의도적인 _하한선 (floor)_이지, 목표치가 아닙니다. 이는 비용을 적게 들이면서 중대한 퇴보 (regression)를 포착하기에 충분하며, 자주 실행할 수 있을 만큼 작고 모든 참조 데이터의 품질을 높게 유지할 수 있을 만큼 작습니다. (작은 변화를 감지하기에는 통계적으로 부족합니다. 이 부분은 다음 포스트에서 다룹니다.) 크기보다 더 중요한 것은 이 세트가 살아있어야 (alive) 한다는 점입니다. 프로덕션 (production) 환경에서 발견되는 모든 새로운 실패 모드 (failure mode)는 새로운 케이스를 확보해야 합니다. 전혀 변하지 않는 골든 데이터셋은 서서히 현실과 닮지 않게 되며, 오래된 잣대는 거짓을 말하는 잣대가 됩니다.

트래픽이 없는 완전히 새로운 기능처럼 실제 예시가 진정으로 부족한 경우에는, 합성 (synthetic) 케이스로 부트스트래핑 (bootstrap)할 수 있습니다 (강력한 모델을 사용하여 분류 체계 (taxonomy)의 차원 전반에 걸쳐 현실적인 입력을 생성하도록 합니다). 이는 정당한 시작점이지만, 이를 비계 (scaffolding)처럼 취급하십시오. 트래픽이 유입됨에 따라 합성 케이스를 실제 케이스로 교체해야 합니다. 왜냐하면 실제 사용자는 그 어떤 생성기 (generator)보다 더 창의적이기 때문입니다.

소리 없는 살인자: 프로덕션으로부터의 데이터셋 드리프트 (dataset drift)

이제 완벽해 보이는 골든 데이터셋을 조용히 무효화하는 함정이자, 제가 리뷰어에게 가장 확인해달라고 요청하고 싶은 부분입니다.

당신은 API 엔드포인트 (endpoint)에 기능의 프롬프트 (prompt)를 작성합니다. 평가 (eval)를 작성하고, 당연하게도 테스트에서도 프롬프트를 다시 작성합니다. 두 개의 복사본이 생깁니다. 누군가 긴급 수정을 위해 프로덕션 프롬프트를 수정했지만 테스트 복사본은 건드리지 않습니다. 그 순간부터 당신의 평가는 프로덕션에 더 이상 존재하지 않는 프롬프트를 측정하게 됩니다. 점수는 계속 초록색(정상)을 유지하지만, 그 밑에서 제품은 변해버렸습니다. 테스트가 매우 자신감 있게 보고하기 때문에 아무도 눈치채지 못합니다.

해결책은 징계가 아니라 구조적인 것입니다. 프로덕션과 평가 호출 _모두_가 사용하는 하나의 빌더 (builder)로 프롬프트를 추출하십시오. 그러면 드리프트 (drift)가 발생할 두 번째 복사본이 존재하지 않게 됩니다.

// 한 번 빌드되어 엔드포인트와 평가 모두에 의해 호출됩니다 — 두 곳이 서로 다를 수 없습니다.
public static class ExplainPrompt
{
...

평가의 케이스-요청 매핑 (case-to-request mapping)은 해당 공유 빌더를 직접 연결하며, 결정적으로 요청은 기능의 태그 (tag)에 의해 선택된, 프로덕션이 사용하는 것과 **동일한 모델 게이트웨이 (model gateway)**를 통과하게 됩니다.

private static LlmRequest ToRequest(ExplainGolden g) => new(
    SystemPrompt: ExplainPrompt.BuildSystemPrompt(g.Genre, g.TargetLang),
    Messages: [new LlmMessage("user", ExplainPrompt.BuildUserPrompt(g.Word, g.Sentence))],
...

이 포스트에서 한 가지만 기억해야 한다면: 프롬프트의 복사본을 실행하는 평가는 평가를 하지 않는 것보다 나쁩니다. 왜냐하면 잘못된 확신 (false confidence)을 만들어내기 때문입니다. 동일한 프롬프트, 동일한 게이트웨이 (gateway), 동일한 경로를 거쳐야 합니다. 그렇지 않으면 당신은 유령을 측정하고 있는 것입니다.

함정 (The pitfalls)

  • 해피 패스(Happy-path) 전용 세트 — 제품의 성능은 떨어지는데 점수만 올라갑니다. 실패 분류 체계 (failure taxonomy)를 통해 데이터를 보충하세요.
  • 취약한 참조 답변 (Weak reference answers) — 점수의 의미를 제한하며, 당신이 잡으려는 바로 그 실패를 보상할 수도 있습니다.
  • 훈련/테스트 누수 (Train/test leakage) — 동일한 사례로 튜닝하고 점수를 매기는 것은 허구에 과적합 (overfit)되는 것입니다.
  • 고정된 세트 (A frozen set) — 입력값은 변합니다 (drift). 전혀 성장하지 않는 데이터셋은 더 이상 존재하지 않는 제품을 서서히 측정하게 됩니다.
  • 영원한 합성 데이터 (Synthetic-forever) — 초기 단계 (bootstrap)에는 괜찮지만, 의존하기에는 위험합니다. 실제 트래픽은 훨씬 더 기이합니다.
  • 중복된 프롬프트 (A duplicated prompt) — 드리프트 (drift)의 함정입니다. 하나의 공유된 빌더를 사용하여 실제 게이트웨이를 통과해야 합니다.

핵심 요약 (The takeaway)

골든 데이터셋 (Golden dataset)은 한 번 생성하고 잊어버리는 형식적인 절차가 아닙니다. 그것은 세심하게 큐레이션되고, 정직하게 분할되며, 지속적으로 갱신되는 자(ruler)입니다. 그리고 반드시 실제 프롬프트를 실제 경로를 통해 실행해야 하며, 그렇지 않으면 아무것도 측정하지 못하는 것입니다. 데이터셋을 제대로 구축하면 모든 다운스트림 (downstream) 수치가 의미를 갖게 됩니다. 잘못 구축하면 초록색 불빛(합격 신호)으로 당신에게 거짓말을 하는 측정 도구를 만든 셈이 됩니다.

시리즈 다음 편: 올바르게 수행하는 LLM-as-judge — 문단을 신뢰할 수 있는 숫자로 바꾸는 방법, 판사(judge)를 망가뜨리는 편향 (biases), 그리고 왜 당신의 판사에게도 자체적인 평가 (eval)가 필요한지에 대해 다룹니다.

TextStack은 당신이 계속 포기하게 되는 난해한 기술 서적을 끝까지 읽을 수 있도록 도와주는 리더 (reader)입니다. .NET에서 모든 현대적인 AI 프리미티브 (observability, evals, RAG, agents)를 실제 프로덕션 기능으로 구축합니다. textstack.app에서 체험하거나, github.com/mrviduus/textstack에서 코드를 읽어보세요.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0