본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 17. 10:16

당신의 평가 스위트(Eval Suite)는 허구를 채점하고 있습니다: 테스트 케이스를 임의로 만들지 말고 트레이스(Traces)를 활용하세요

요약

에이전트 평가 시 임의로 작성된 테스트 케이스 대신 실제 프로덕션 트레이스(Traces)를 활용해야 함을 강조합니다. 수동 작성이나 합성 데이터는 실제 사용자의 복잡한 패턴을 반영하지 못해 평가의 신뢰도를 떨어뜨립니다.

핵심 포인트

  • 수동 작성된 테스트 케이스는 개발자의 편향이 반영된 '해피 패스'에 치우칠 위험이 있음
  • 합성 데이터 생성은 기존 모델의 분포를 따르므로 특이 사례(Edge cases) 포착에 한계가 있음
  • 가장 정직하고 효과적인 평가 데이터의 원천은 실제 프로덕션 트래픽(Traces)임
  • 실제 사용자의 예측 불가능한 입력을 회귀 테스트 케이스로 승격시키는 과정이 필수적임

당신의 평가 스위트(Eval Suite)는 그 안에 포함된 케이스만큼만 가치가 있으며, 거의 아무도 그 케이스들이 어디에서 왔는지에 대해 이야기하지 않습니다. 우리는 결정론적 체크(Deterministic checks) 대 모델 기반 평가(Model-as-judge), CI 게이트(CI gates) 및 드리프트 임계값(Drift thresholds)에 대해 끝없이 논쟁하지만, 정작 그 모든 기계 장치에 누군가 오후 한때에 임의로 만든 12개의 예시로 구성된 데이터셋을 입력합니다. 점수는 엄격하지만, 코퍼스(Corpus)는 허구입니다.

제가 고수할 의견은 다음과 같습니다: 에이전트 평가(Agent evaluation)에서 가장 어려운 부분은 평가자(Scorer)가 아니라 데이터셋입니다. 대표성이 없는 입력 세트에 대해 완벽한 판사(Judge)를 두는 것은 아무런 의미가 없는 확신에 찬 초록색 체크 표시를 제공할 뿐입니다. 결함 없는 어설션(Assertions)을 가질 수 있어도 여전히 고장 난 에이전트를 출시할 수 있는데, 그 이유는 당신의 평가 세트(Eval set)에 에이전트를 망가뜨리는 입력이 전혀 포함되지 않았기 때문입니다. 코퍼스(Corpus)가 곧 테스트입니다. 그 외의 모든 것은 배관(Plumbing) 작업일 뿐입니다.

수동으로 작성된 평가 케이스가 부패하는 이유

팀이 첫 번째 평가 세트(Eval set)를 구축할 때, 그들은 자리에 앉아 입력을 상상합니다. "사용자가 티켓 요약을 요청합니다." "사용자가 환불을 요청합니다." 이러한 케이스들은 치명적인 공통점을 공유합니다. 바로 프롬프트(Prompt)를 작성한 사람과 동일한 사람이 엔지니어가 '상상한' 사용자의 행동을 작성했다는 점입니다. 이는 해피 패스(Happy path)를 두 번 인코딩합니다. 한 번은 에이전트에, 한 번은 테스트에 인코딩한 뒤, 서로 일치하는 것에 대해 축하를 나눕니다.

실제 사용자는 당신의 상상처럼 행동하지 않습니다. 그들은 한 줄짜리 입력 필드에 8,000 토큰 분량의 Slack 히스토리를 붙여넣습니다. 세 가지 질문을 한꺼번에 던집니다. 당신이 설계하지 않은 용도로 제품을 사용합니다. 가장 서툰 제2외국어로 글을 씁니다. 이 중 그 어떤 것도 당신이 직접 작성한 세트에는 들어있지 않으며, 이는 그 어떤 것도 게이트(Gated)되지 않았음을 의미합니다. 즉, 그 모든 입력은 당신의 "포괄적인 평가 스위트(Comprehensive eval suite)"가 한 번도 본 적 없는, 운영 환경(Production)에서의 살아있는 수류탄과 같습니다.

합성 데이터 생성(Synthetic data generation) — "GPT에게 100개의 테스트 쿼리를 작성해달라고 요청하기" — 는 임시방편처럼 느껴지지만 실제로는 그렇지 않습니다. 모델은 이미 당신의 프롬프트가 잘 처리하고 있는 것과 동일한 분포(distribution)에서 데이터를 생성합니다. 결과적으로 쉬운 사례(easy case)의 변형 100개는 얻을 수 있지만, 특이한 사례(weird cases)는 단 하나도 얻지 못합니다. 왜냐하면 특이한 사례란 바로 어떤 모델도 생성할 생각을 하지 못할 만큼 특이하기 때문입니다. 합성 데이터 세트는 실제 리스크(risk)에는 전혀 영향을 주지 않으면서, 케이스 수와 당신의 자신감만 부풀립니다.

진실의 원천(Source of truth)은 당신의 프로덕션 트레이스(Production traces)입니다

평가 케이스(eval cases)의 유일하게 정직한 원천은 당신이 실제로 서비스하고 있는 분포, 즉 프로덕션 트래픽(production traffic)입니다. 당신의 사용자들은 매일 당신의 에이전트(agent)를 상대로 지속적이고 적대적이며 무료인 퍼징(fuzzing) 캠페인을 벌이고 있습니다. 우리의 과제는 그것을 포착하고, 중요한 입력을 찾아내어, 이를 영구적인 회귀 테스트 케이스(regression cases)로 승격시키는 것입니다.

이것이 바로 제가 트레이싱(tracing)과 평가(evaluation)를 두 개의 제품이 아닌 하나의 워크플로(workflow)로 취급하는 정확한 이유입니다. AgentLens는 모든 프로덕션 실행의 전체 실행 트레이스(execution trace)를 캡처합니다. 템플릿 보간(template interpolation) 후 모델이 실제로 본 해결된 입력(resolved input), 인자(arguments)가 포함된 모든 도구 호출(tool call), 원시 출력(raw outputs), 그리고 최종 답변까지 말이죠. 그 트레이스 저장소(trace store)는 단순한 디버깅 도구가 아닙니다. 그것은 당신의 평가 세트(eval set)를 채굴하는 원재료입니다. agent-eval은 나머지 절반입니다. 이것은 케이스를 가져와 결정론적 체크(deterministic checks)와 모델 기반 채점 루브릭(model-as-judge rubric)을 실행하고, 게이트(gate)로 사용할 수 있는 합격/불합격 판정을 반환합니다. 이 쌍(pairing)이 중요한 이유는 AgentLens는 어떤 케이스가 테스트할 가치가 있는지를 결정하고, agent-eval은 에이전트가 그 케이스를 _통과하는지_를 결정하기 때문입니다. 프로덕션으로부터의 파이프라인이 없는 채점기는 허구를 채점하는 채점기에 불과하며, 평가로 승격시키지 않는 트레이스 저장소는 아무도 읽지 않는 아카이브일 뿐입니다.

루프는 다음과 같이 작동합니다: 프로덕션 실행(production run)에서 좋지 않은 결과(싫어요, 고객 지원 에스컬레이션, 실패한 다운스트림 액션)가 발생합니다. 해당 트레이스(trace)는 당신이 가질 수 있는 가장 가치 있는 테스트 케이스(test case)입니다. 왜냐하면 그것은 실제로 발생한 실제 실패이기 때문입니다. 해결된 입력값(resolved input)을 캡처하고, 수정된 기대 동작(expected behavior)을 부착하면, 그것은 영구적인 케이스가 됩니다. 이제 그 정확한 실패는 다시는 조용히 회귀(regress)할 수 없습니다.

다음은 플래그가 지정된 트레이스를 고정된 회귀 케이스(regression case)로 변환하는 하네스(harness)입니다:

import { getTrace } from "agentlens";
import { evaluate, assert } from "agent-eval";
import { writeFileSync, readFileSync } from "node:fs";
...

가치를 증명하는 핵심 디테일은 sourceTraceId입니다. 모든 케이스는 그것이 유래된 실제 실행(run)으로 돌아가는 포인터를 지닙니다. 6개월 후에 케이스가 실패했을 때, 당신은 그것이 무엇을 증명하려 했는지 고민하며 합성된 입력(synthetic input)을 멍하니 바라보고 있는 것이 아니라, 원래의 AgentLens 트레이스를 열어 그것을 유발했던 실제 사건을 확인하게 됩니다. 당신의 평가 세트(eval set)는 당신이 수정했던 모든 실제 버그의 박물관이 되며, 게이트(gate)의 역할은 그중 어떤 것도 다시 돌아오지 못하게 보장하는 것입니다.

큐레이션(Curation)은 일회성 내보내기가 아닌 규율입니다

트레이스를 마이닝(mining)하는 것은 "모든 것을 평가 세트에 쏟아붓는 것"이 아닙니다. 실행하는 데 4시간이 걸리는 50,000개의 케이스 세트는 아무도 실행하지 않는 세트입니다. 큐레이션(Curation)이란 코퍼스(corpus)를 능동적으로 관리하는 것을 의미합니다:

  • 결과에 따라 계층화(Stratify)하세요. 실패 사례와 엣지 입력(edge inputs)을 의도적으로 오버샘플링(oversample)하십시오. 실제 운영 환경(production)을 그대로 반영하는 세트는 95%가 쉬운 사례로 구성되어 있으며, 판사(judge) 비용을 지출할 때마다 얻을 수 있는 정보가 거의 없습니다. 당신은 어려운 사례(hard tail)가 과잉 대표되기를 원해야 합니다.
  • 문자열이 아닌 동작(behavior)을 기준으로 중복을 제거하세요. 동일한 도구 선택(tool-selection) 버그를 일으키는 10개의 트레이스(traces)는 10개가 아니라 하나의 사례입니다. 실패 모드(failure mode)를 기준으로 클러스터링(cluster)하고 가장 명확한 대표 사례를 유지하십시오.
  • 더 이상 아무것도 테스트하지 않는 사례는 만료시키세요. 특정 기능이 몇 달 동안 견고하게 유지된다면, 해당 사례들을 야간 테스트 스위트(nightly suite)로 강등시키고 커밋당 게이트(per-commit gate)는 가볍고 빠르게 유지하십시오.
  • 커버리지(coverage)를 실제 지표로 추적하세요. 어떤 사용자 의도(user intents), 어떤 도구(tools), 어떤 입력 형태(input shapes)에 평가 사례가 전혀 없습니까? 그 공백들이 바로 당신의 다음 운영 사고(production incident)가 숨어 있는 지점입니다.

핵심 요약 (The takeaway)

당신이 임의로 만들어낸 데이터셋 위에 더 정교한 스코어러(scorer)를 구축하는 데 엔지니어링 노력을 쏟는 것을 멈추십시오. 레버리지(leverage)는 코퍼스(corpus)에 있습니다. AgentLens 트레이스(traces)로 캡처된 실제 운영 실패 사례를 영구적인 에이전트 평가(agent-eval) 사례로 전환하는 파이프라인을 구축하십시오. 그러면 당신의 스위트는 무엇이 잘못될 수 있다고 상상한 기록이 아니라, 무엇이 _실제로 일어났는지_에 대한 기록이 됩니다. 그것이 매주 낡아지는 대신 점점 더 강력해지는 유일한 평가 세트입니다.

당신의 사용자들은 매일 당신을 위해 무료로 테스트 케이스를 작성하고 있습니다. 유일한 질문은 당신이 그것들을 캡처하고 있느냐, 아니면 결코 쿼리(query)하지 않을 로그 파일 속으로 소멸하게 내버려 두고 있느냐 하는 것입니다.

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0