AI 평가(Evals), 파트 5: 숫자에서 게이트로 CI 및 프로덕션에서의 평가
요약
.NET 환경에서 프로덕션 AI를 구축할 때 품질을 자동화된 엔지니어링 프로세스로 통합하는 방법을 다룹니다. CI(지속적 통합) 단계에서 평가(Evals)를 게이트로 활용하여 회귀를 방지하고, 비용 효율적인 평가 전략을 수립하는 실무적인 가이드를 제공합니다.
핵심 포인트
- 평가는 단순 지표 확인을 넘어 CI/CD의 자동화된 게이트 역할을 해야 함
- 단위 테스트처럼 품질 최저선을 기준으로 통과/실패를 결정하는 구조 필요
- 모든 평가에는 생성 및 판사 호출 비용이 발생하므로 전략적 실행이 필수적
- PR 시에는 소규모 하위 집합을, 전체 스위트는 정기적으로 실행하는 패턴 권장
Part 5는 .NET으로 프로덕션 AI를 구축하는 시리즈의 마지막 편입니다. 우리는 평가(evals)란 무엇인지, 오류 분석(error analysis), 골든 데이터셋(golden datasets), 그리고 신뢰할 수 있는 심사관(trustworthy judge)와 같은 조각들을 만들어 왔습니다. 이제 이들이 제 역할을 하도록 만듭니다.
지금쯤이면 AI 기능에 대해 방어 가능한 품질 점수를 산출할 수 있습니다. 하지만 그저 보는 점수는 허세 지표(vanity metric)일 뿐입니다. 모든 작업의 핵심 목적은 품질을 엔지니어링 프로세스가 자동으로 조치하는 무언가로 만드는 것입니다. 마치 실패한 단위 테스트(unit test)가 잘못된 커밋(commit)을 막는 방식과 같습니다. 이는 평가를 위한 두 가지 환경을 의미합니다: 배포 전에 작동하는 **게이트(gate)**와 그 이후의 **모니터링(monitoring)**입니다.
홈 1: CI — 회귀에 대한 안전망
TextStack의 심사관은 Microsoft.Extensions.AI.Evaluation의 사용자 정의 IEvaluator이기 때문에, 평가는 단지 dotnet test일 뿐입니다. MEAI 평가기는 루브릭(rubric)의 축과 전반적인 점수를 수치적 지표로 방출하며, 품질 _최저선(floor)_은 전체에 대한 통과/실패 해석으로 표현됩니다:
// 평가기에서: 전체 지표는 최저선 대비 통과/실패로 해석됩니다.
if (overallFloor is { } floor)
overall.Interpretation = new EvaluationMetricInterpretation(...)
이것은 심각한 고장(
우리 코드베이스의 솔직한 상태는 이렇습니다. 현재 기초적인 실행(floor)과 온디맨드(on-demand) 실행은 존재하지만, 자동화된 기준값 대비 회귀(baseline-versus-regression) 게이트(gate)가 다음 단계입니다. 제가 이를 의도적으로 강조하는 이유는, "우리는 평가 기반 개발(eval-driven development)을 한다"라고 주장하는 많은 사례가 실제로는 "아무도 기준으로 삼지 않는 숫자 하나를 가지고 있다"는 의미인 경우가 많기 때문입니다. 어려운 80%인 측정 도구는 이미 구축되었습니다. 이제 래칫(ratchet, 단계적 개선을 고정하는 장치)을 연결하는 나머지 20%의 가벼운 작업이 남았습니다.
CI가 강제하는 제약: 평가(evals)에는 비용이 든다
모든 평가 케이스는 실제 생성(generation) 및 실제 판사(judge) 호출을 수반합니다. 모든 커밋마다 전체 스위트(suite)를 실행하는 것은 느리고 비용이 많이 들기 때문에, 평가는 의도적으로 이루어져야 합니다. TextStack의 평가들은 **선택 사항(opt-in)**입니다. 태그를 지정하여 기본 CI에서는 건너뛰도록 설정되어 있으며, 제공자(provider)가 구성되지 않은 경우 스스로 건너뜁니다.
OPENAI_API_KEY=… dotnet test tests/TextStack.AiEvals --filter Category=Eval
기본 CI는 통과(green) 상태를 유지하며 비용이 들지 않습니다. 비용이 발생하는 진실은 의도적으로 실행됩니다. 실용적인 패턴은 다음과 같습니다. 빠른 신호를 얻기 위해 풀 리퀘스트(pull request) 시에는 작고 저렴한 하위 집합(subset)을 실행하고, 전체 스위트는 매일 밤 또는 릴리스 전에 실행합니다. 평가 비용을 다른 클라우드 비용처럼 취급하십시오. 예산을 책정하고, 무제한으로 실행되도록 두지 마십시오.
두 번째 영역: 프로덕션 — 모니터링 및 가드레일(guardrails)
아무리 잘 큐레이션된 골든 세트(golden set)라 할지라도, 그것은 당신이 상상한 입력값들의 스냅샷일 뿐입니다. 프로덕션은 당신이 상상하지 못한 입력값을 보냅니다. 따라서 오프라인 게이트는 시스템의 절반일 뿐이며, 나머지 절반은 라이브 트래픽을 대상으로 실행됩니다.
이 지점에서 평가(evals)와 관측성(observability)은 하나가 됩니다. TextStack의 모든 AI 호출은 해당 기능(feature) 태그가 붙어 기록됩니다 — 비용, 지연 시간(latency), 토큰, 에러 등 — 그리고 실행 결과는 내부 /ai-quality 대시보드(Traces 및 Evals 탭)에 표시되는 eval_runs 테이블에 저장되며, 관리자용 "Run evals" 버튼을 통해 온디맨드로 스위트를 트리거할 수 있습니다. 판사(judge)가 오프라인과 온라인에서 동일한 컴포넌트이기 때문에, 기능별로 실제 출력값을 샘플링하여 동일한 루브릭(rubric, 평가 기준)으로 점수를 매길 수 있습니다. 여기서 두 가지 모드가 도출됩니다:
- 백그라운드 모니터링 (Background monitoring) — 실제 출력값의 일부(slice)를 샘플링하여 판단하고, 사용자가 불만을 제기하기 전에 드리프트 (drift)를 포착할 수 있도록 시간이 지남에 따라 점수를 관찰합니다.
- 가드레일 (Guardrails) — 리스크가 큰 출력값의 경우, 크리티컬 패스 (critical path) 내에서 판단을 수행하며, 결과가 실패할 경우 차단(block), 재시도(retry) 또는 폴백 (fallback)을 수행합니다. (주의해서 사용하십시오: 요청에 판단 모델 호출에 상응하는 지연 시간 (latency)과 비용이 추가됩니다.)
플라이휠 (The flywheel)
이 두 가지 환경을 결합하면 복리로 작용하는 루프가 형성됩니다. 프로덕션에서 새로운 실패 모드 (failure mode)가 발생하면 → 이에 대한 에러 분석 (error analysis)을 수행하고 → 이는 새로운 골든 케이스 (golden case)가 됩니다 → 이제 당신의 게이트 (gate)가 이를 방어하게 되며 → 품질이 상승하고 → 더 깨끗한 출력값이 더 깨끗한 트래픽을 생성합니다. 매 회전마다 다음 회귀 (regression)가 배포되는 것을 더 어렵게 만듭니다. 단일 대시보드가 아니라, 이러한 지속적인 개선의 플라이휠 (flywheel)이야말로 평가 (eval) 시스템의 진정한 결과물입니다.
함정 (The pitfalls)
- 아무도 게이트로 사용하지 않는 숫자 — 나쁜 점수가 빌드 (build)를 실패시키거나 담당자에게 알림을 보내지 못한다면, 그것은 장식에 불과합니다.
- 회귀 게이트로 오해받는 고정된 하한선 (fixed floor) — 하한선은 파손을 잡아낼 뿐, 2% 더 나빠진 변화를 잡아내지는 못합니다. 당신은 두 가지 모두를 원해야 합니다.
- 모든 커밋에 대한 평가 (Evals on every commit) — 비용과 대기 시간 때문에 습관화하기 어려울 것입니다. PR (Pull Request)에서는 서브셋 (subset)을 사용하고, 전체 스위트 (full suite)는 매일 밤 실행하십시오.
- 오프라인 전용 (Offline-only) — 골든 세트 (golden set)가 전혀 상상하지 못한 입력값으로부터 발생하는 회귀 (regression)를 배포하게 될 것입니다.
- 도처에 깔린 가드레일 (Guardrails everywhere) — 크리티컬 패스 (critical path) 내에서 판단하는 것은 강력하지만 지연 시간 (latency) 비용이 발생합니다. 중요한 출력값에 대해서만 예약하여 사용하십시오.
- 절대 읽지 않는 온라인 점수 — 보지 않는 모니터링은 그저 더 비싼 로그 (log)일 뿐입니다.
시리즈 요약 (The series, in one line each)
시작부터 끝까지, 이 학문 분야의 전체 과정은 다음과 같습니다:
- Evals는 비결정론적 코드(non-deterministic code)를 위한 테스트 스위트입니다 — 대표 샘플에 대한 등급이 매겨진 판단(graded judgement)입니다.
- 오류 분석(Error analysis)이 우선입니다 — 실패 사례를 읽고 이름을 붙이세요. 분류 체계(taxonomy)가 무엇을 측정할지를 결정합니다.
- 골든 세트(Golden set)는 척도입니다 — 대표성이 있고, 데이터 누출(leak)이 없으며, 최신 상태여야 하고, 실제 프롬프트와 게이트웨이(gateway)를 통해 실행되어야 합니다.
- 판단자(Judge) 또한 모델입니다 — 방어적이고, 전용이며, 라우팅되고, Cohen's κ를 통해 인간과 비교하여 검증되어야 합니다.
- 점수는 반드시 게이트(gate)가 되어야 합니다 — 배포 전 회귀(regression)를 포착하기 위한 CI, 배포 후 드리프트(drift)를 포착하기 위한 모니터링이 필요합니다.
이 중 어느 것도 Python이나 무거운 플랫폼을 요구하지 않습니다. .NET에서는 ILlmService 접점(seam), JSON 형식의 골든 데이터셋, Microsoft.Extensions.AI.Evaluation 상의 커스텀 IEvaluator, 그리고 선택적 테스트 카테고리로 구현됩니다 — 실제 제품 위에서, 프로덕션 환경에서 구축됩니다. 제대로 수행된다면, Evals는 _"이 AI 기능은 괜찮은 것 같아요"_라는 말을 _"나는 이것을 증명할 수 있으며, 그것이 더 이상 사실이 아니게 되는 순간을 즉시 알 수 있습니다"_로 바꿔줍니다. 이것이 AI를 출시하는 것과 AI로 도박을 하는 것의 차이입니다.
TextStack은 당신이 계속 포기하게 되는 밀도 높은 기술 서적을 끝까지 읽을 수 있도록 돕는 리더(reader)입니다 — 이 도구는 모든 현대적 AI 프리미티브(observability, evals, RAG, agents)를 .NET 상의 실제 프로덕션 기능으로 구축합니다. textstack.app에서 체험해 보거나, github.com/mrviduus/textstack에서 코드를 읽어보세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기