Back to posts

에이전트 eval 함수 해부 글 짚어보기 (2) — 왜 eval을 만들어야 하는가

수동 테스트의 한계부터 eval-driven development까지, eval이 에이전트 개발에 가져다주는 가치를 원문을 따라 해설한다.

2026년 4월 14일

들어가며: 수동 테스트로 충분하지 않나?

에이전트를 처음 만들 때는 eval이 과잉처럼 보인다. 프롬프트를 고치고, 직접 써보고, 감(intuition)으로 판단한다. 팀원 몇 명이 dogfooding하면서 "이 응답 이상한데?"라고 슬랙에 올리면 그게 곧 품질 관리다. 놀라울 정도로 멀리까지 갈 수 있다.

원문도 이 지점을 솔직하게 인정한다.

In the early stages of building an AI application, manual testing,
dogfooding, and intuition can take you surprisingly far. At this point,
investing in rigorous evaluation can seem like unnecessary overhead.

"불필요한 오버헤드"라는 표현이 핵심이다. 에이전트 개발 초기에는 task를 직접 돌려보고 결과를 눈으로 확인하는 것이 가장 빠른 피드백 루프다. grader를 작성하고 자동화 파이프라인을 구축하는 시간에 기능 하나를 더 만들 수 있다. 이 계산은 틀리지 않았다 -- 초기에는.

문제는 이 전략이 특정 지점에서 붕괴한다는 것이다.


breaking point: "flying blind"

에이전트가 프로덕션에 나가고 사용자가 늘어나면, 팀이 직접 써보는 것으로는 커버할 수 없는 시나리오가 폭발적으로 늘어난다. 프롬프트 한 줄을 바꿨을 때 수백 가지 시나리오 중 어디에 영향이 가는지 알 수 없다. 원문은 이 상태를 "flying blind"라고 부른다.

After launching a product and scaling up, teams often encounter their
first real crisis when users begin reporting that the agent has gotten
worse after recent changes. The team finds itself "flying blind" —
without a reliable way to verify whether the agent has actually
degraded, improved, or stayed the same.

이 단계에서 디버깅은 완전히 반응적(reactive)이 된다. 원문이 묘사하는 루프를 보자.

Debugging becomes reactive: wait for user complaints, try to reproduce
the issue manually, apply a fix, and hope nothing else has regressed.
  1. 사용자 불만을 기다린다
  2. 수동으로 재현을 시도한다
  3. 수정을 적용한다
  4. 다른 곳이 망가지지 않았기를 바란다

"hope nothing else has regressed" -- 이 문장이 핵심 고통이다. 수동 테스트 기반 팀은 회귀(regression)를 감지할 수단 자체가 없다. 구체적으로 세 가지가 불가능하다.

Specifically, teams cannot:
- Distinguish real regressions from noise
- Automatically test changes against hundreds of scenarios before
  shipping
- Measure whether improvements in one area come at the cost of
  regressions in another

real regression과 noise를 구분할 수 없다는 것은, 사용자가 "에이전트가 나빠졌다"고 할 때 그것이 실제 회귀인지, 엣지 케이스인지, 기분 탓인지 판별할 방법이 없다는 뜻이다. shipping 전에 수백 가지 시나리오에 자동으로 돌려볼 수 없다는 것은, 매번 "이번에는 괜찮겠지" 하며 배포한다는 뜻이다. 한 영역의 개선이 다른 영역의 퇴보를 대가로 한 것인지 측정할 수 없다는 것은, 트레이드오프가 보이지 않는 상태에서 의사결정을 한다는 뜻이다.

이 세 가지가 동시에 불가능한 상태가 바로 "flying blind"다. eval은 이 세 문제를 모두 해결하기 위해 존재한다.


사례 연구 — Claude Code

원문은 Anthropic 자체 제품인 Claude Code가 eval을 어떻게 도입했는지를 설명한다. 흥미로운 점은 Claude Code 역시 처음부터 eval을 갖추고 시작하지 않았다는 것이다.

Claude Code started with fast iteration based on feedback from Anthropic
employees and external users. Later added evals—first for narrow areas
like concision and file edits, and then for more complex behaviors like
over-engineering.

초기에는 내부 직원과 외부 사용자의 피드백을 기반으로 빠르게 반복했다. eval은 나중에 추가되었다. 그리고 eval이 추가된 순서가 의미심장하다.

  1. concision (간결함): 에이전트 응답이 불필요하게 길지 않은가?
  2. file edits (파일 편집): 코드 수정이 정확한가?
  3. over-engineering (과잉 설계): 사용자가 요청한 것 이상으로 복잡하게 만들지 않는가?

처음 두 개는 비교적 좁은(narrow) 영역이다. 응답 길이는 토큰 수로 측정할 수 있고, 파일 편집은 diff 기반으로 정답 비교가 가능하다. 세 번째인 over-engineering은 훨씬 복잡한 행동(behavior)이다. "필요 이상으로 복잡하게 만들었는가"를 판단하려면 LLM grader가 필요할 가능성이 높다.

이 순서는 eval 도입의 일반적인 패턴을 보여준다. 측정하기 쉬운 것부터 시작해서 점차 복잡한 행동으로 확장한다. 처음부터 "에이전트가 좋은 코드를 짜는가?"를 eval하려 하면 grader 설계에서 막힌다. 대신 "응답이 500토큰 이하인가?"부터 시작하면 즉시 돌릴 수 있다.

원문이 특히 강조하는 것은 eval이 연구팀과 제품팀의 협업을 촉진했다는 점이다.

These evals helped identify issues, guide improvements, and focus
research-product collaborations.

eval이 없으면 연구팀에 "에이전트가 코드를 너무 복잡하게 짜요"라고 말할 수 있을 뿐이다. eval이 있으면 "over-engineering eval의 통과율이 62%입니다. 특히 리팩토링 task에서 43%로 떨어집니다"라고 말할 수 있다. 후자가 연구팀이 최적화할 수 있는 형태의 정보다. eval은 팀 간 커뮤니케이션의 해상도를 높인다.

Claude Code는 eval만으로 품질을 관리하지 않았다. 원문은 eval이 다른 도구들과 결합된다고 밝힌다.

Combined with production monitoring, A/B tests, user research.

프로덕션 모니터링은 실제 사용 패턴에서의 이상을 감지하고, A/B 테스트는 변경의 인과 효과를 검증하고, 사용자 연구는 정량적 수치가 놓치는 정성적 문제를 포착한다. eval은 이 도구 생태계의 한 축이다. 하지만 다른 도구들이 eval을 대체할 수는 없다. A/B 테스트는 배포 후에야 결과가 나오고, 모니터링은 이미 문제가 발생한 후에 알려준다. eval만이 배포 전에 변경의 영향을 시뮬레이션할 수 있다.


사례 연구 — Descript

Descript는 비디오 편집 도구를 만드는 회사다. 에이전트가 사용자의 비디오 편집 작업을 돕는다. 이 사례가 흥미로운 이유는 eval의 차원(dimension)을 어떻게 설계했는지가 명확하게 드러나기 때문이다.

Descript built evals around three dimensions: don't break things,
do what I asked, and do it well.

세 가지 차원을 보자.

  1. Don't break things — 에이전트가 기존 프로젝트를 망가뜨리지 않는가?
  2. Do what I asked — 사용자가 요청한 것을 실제로 수행했는가?
  3. Do it well — 수행 결과의 품질이 높은가?

이 세 차원은 계층 구조를 이룬다. 1번이 가장 기본이다. 아무리 잘 해도 기존 편집을 날려버리면 안 된다. 2번은 정확성이다. "이 클립 3초 잘라줘"라고 했는데 5초를 잘랐다면 실패다. 3번은 품질이다. 잘라는 했는데 트랜지션이 어색하거나 오디오가 끊기면 좋지 않은 결과다.

이 계층 구조는 grader 설계에 직접 영향을 준다. 1번 차원은 자동화 가능한 assertion으로 확인할 수 있다 -- 프로젝트 파일이 유효한가, 기존 트랙이 보존되었는가. 2번 차원은 구조적 비교가 가능하다 -- 요청된 편집이 적용되었는가. 3번 차원은 주관적 판단이 필요하므로 LLM grader가 적합하다.

Descript의 eval 시스템은 시간이 지나면서 진화했다.

Evolved from manual grading to LLM graders with criteria defined by
product team and periodic human calibration.

처음에는 사람이 직접 채점했다. 수동 채점(manual grading)은 정확하지만 느리고 확장되지 않는다. 매번 사람이 비디오 편집 결과를 열어보고 "이거 잘 됐나?"를 확인해야 한다. 팀이 이를 LLM grader로 전환하되, 채점 기준은 프로덕트 팀이 정의하고, **주기적으로 사람이 교정(calibration)**하는 구조를 만들었다.

이 구조가 중요하다. LLM grader는 사람의 판단을 완전히 대체하지 않는다. 대신 사람의 판단을 증폭시킨다. 프로덕트 팀이 "좋은 편집이란 이런 것이다"를 기준으로 정의하면, LLM grader가 그 기준을 수백 개 trial에 일관되게 적용한다. 주기적 교정은 grader가 표류(drift)하지 않도록 잡아준다.

최종적으로 Descript는 두 개의 별도 eval suite를 운영한다.

Now regularly run two separate suites for quality benchmarking and
regression testing.
  1. Quality benchmarking suite: 현재 에이전트의 절대적 품질 수준을 측정한다. "지금 우리 에이전트가 전체적으로 얼마나 잘하는가?"
  2. Regression testing suite: 변경 전후를 비교한다. "이번 변경이 기존 성능을 떨어뜨리지 않았는가?"

이 두 suite의 분리는 실용적이다. Quality benchmarking은 넓은 범위의 task를 포함하되 빈도가 낮을 수 있다 (예: 주 1회). Regression testing은 변경할 때마다 빠르게 돌려야 하므로 핵심 시나리오에 집중한다. 목적이 다르면 suite를 분리하는 것이 맞다.


사례 연구 — Bolt

Bolt는 세 사례 중 가장 현실적인 시나리오를 보여준다. 이미 널리 쓰이는 에이전트에 eval을 늦게 도입한 경우다.

Bolt started building evals later, after already having a widely used
agent.

이미 많은 사용자가 쓰고 있는 에이전트에 eval을 뒤늦게 붙이는 것은 "달리는 차의 타이어를 교체하는" 상황이다. 새 기능 개발을 멈추고 eval 인프라를 구축하기는 어렵다. 그럼에도 Bolt 팀은 3개월 만에 eval 시스템을 구축했다.

In 3 months, built an eval system that: runs their agent and grades
outputs with static analysis, uses browser agents to test apps, and
employs LLM judges for behaviors like instruction following.

Bolt의 eval 시스템은 세 가지 grading 방식을 조합한다.

Static analysis

에이전트가 생성한 코드를 정적 분석(static analysis)으로 검증한다. 코드가 문법적으로 올바른가, 타입 에러가 없는가, 린트 규칙을 통과하는가. 이것은 가장 저렴하고 빠른 grading이다. 1편의 용어로 말하면 deterministic grader에 해당한다. 사람의 판단이 개입하지 않고, 모호함이 없다.

Browser agents

에이전트가 만든 앱을 브라우저 에이전트가 직접 실행해서 테스트한다. "회원가입 버튼을 클릭하면 폼이 나타나는가?"를 실제로 브라우저에서 돌려본다. 이것은 end-to-end 테스트의 eval 버전이다. static analysis가 "코드가 문법적으로 맞는가"를 확인한다면, browser agent는 "코드가 실제로 동작하는가"를 확인한다.

LLM judges

instruction following 같은 행동은 정적 분석이나 브라우저 테스트로 판단할 수 없다. "사용자가 한국어로 작성해달라고 했는데 영어로 작성했는가?"는 LLM이 판단해야 한다. 이것은 1편의 LLM grader에 해당한다.

세 가지 방식의 조합이 보여주는 원칙은 이것이다: 하나의 grading 방식으로 모든 차원을 커버할 수 없다. 코드 품질, 기능 동작, 행동 패턴은 각각 다른 방식으로 측정해야 한다. Bolt는 이를 3개월 안에 구축했다는 점에서, eval 시스템이 반드시 대규모 선행 투자를 요구하지 않는다는 것을 보여준다.


eval의 시간축별 가치

원문은 eval의 가치를 시간 순서대로 설명한다. 초기, 중기, 후기로 나눠 보자.

초기: 요구사항 명확화

eval의 첫 번째 가치는 뜻밖에도 자동화 테스트가 아니라 사양 명확화다.

Early on, evals force product teams to specify what success means.
Two engineers reading the same spec could have different interpretations
on edge cases. Building an eval suite resolves this ambiguity by making
expected behavior explicit and testable.

두 엔지니어가 같은 명세를 읽고 엣지 케이스에 대해 다른 해석을 할 수 있다. "에이전트가 사용자의 파일을 수정할 때, 기존 주석은 보존해야 하는가?" 한 엔지니어는 당연히 보존해야 한다고 생각하고, 다른 엔지니어는 새 코드에 맞게 갱신해야 한다고 생각한다. 명세에 이 수준의 디테일이 적혀 있는 경우는 드물다.

eval을 만들면 이 모호함이 강제로 해소된다. task를 정의하려면 "주석이 포함된 파일을 수정하는 시나리오"를 구체적으로 만들어야 하고, grader를 만들려면 "주석 보존 여부"에 대한 판정 기준을 명시해야 한다. eval을 만드는 행위 자체가 명세를 정밀하게 만든다.

이 가치는 eval을 실제로 실행하기 전에 이미 발생한다. eval suite를 설계하는 과정에서 팀은 "성공이란 무엇인가"에 대해 합의하게 된다.

중기: 모델 업그레이드 속도

Teams without evals face weeks of manual testing when upgrading models.
Teams with evals can quickly determine where the new model is stronger
or weaker, tune prompts accordingly, and upgrade confidently in days
rather than weeks.

모델 업그레이드는 에이전트 개발에서 반복적으로 발생하는 이벤트다. 새 모델이 나올 때마다 "우리 에이전트에 적용하면 어떨까?"를 평가해야 한다. eval 없는 팀은 이 과정에 몇 주가 걸린다. 팀원들이 주요 시나리오를 수동으로 돌려보고, 결과를 비교하고, 감으로 판단한다. eval이 있는 팀은 새 모델로 전체 suite를 돌리면 며칠이면 판단이 끝난다.

차이는 단순히 속도뿐이 아니다. eval이 있으면 "새 모델이 코드 생성에서 15% 좋아졌지만 instruction following에서 8% 떨어졌다"는 수준의 정보를 얻을 수 있다. 이 정보가 있어야 "instruction following 프롬프트를 조정하면 새 모델로 넘어갈 수 있겠다"는 판단이 가능하다.

후기: 무료 부산물과 소통 채널

eval suite가 성숙해지면 원래 의도하지 않았던 부산물이 생긴다.

Evals naturally produce baselines, regression tests, and metrics like
latency, token usage, cost per task, and error rates.

eval을 돌리면 task별 latency, token usage, cost per task, error rate 같은 메트릭이 자동으로 축적된다. 이 데이터는 eval과 별개로 가치가 있다. "지난달 대비 평균 토큰 사용량이 20% 증가했다"는 정보는 eval이 아니라 비용 최적화에 쓰인다. 하지만 eval 인프라가 없었다면 이 데이터를 별도로 수집해야 했을 것이다.

원문이 가장 강하게 주장하는 후기 가치는 프로덕트-리서치 소통 채널로서의 역할이다.

Evals can become the highest-bandwidth communication channel between
product and research teams, defining metrics that researchers can
optimize against.

"highest-bandwidth communication channel"이라는 표현에 주목하자. 프로덕트 팀이 연구팀에 "에이전트가 더 똑똑해졌으면 좋겠어요"라고 요청하는 것은 저대역폭 커뮤니케이션이다. 대신 "이 100개 task에서 현재 통과율이 58%인데 80%까지 올려야 합니다"라고 전달하면, 연구팀은 정확히 무엇을 최적화해야 하는지 알 수 있다. eval suite는 팀 간 커뮤니케이션을 정량화된 목표로 변환한다.

복리 효과

The compounding value is easy to miss — costs are visible upfront,
benefits accumulate later.

eval의 비용은 선불(upfront)이다. task를 만들고, grader를 작성하고, 인프라를 구축하는 데 시간이 들어간다. 이 비용은 즉시 보인다. 반면 가치는 후불이다. 회귀를 감지하고, 모델 업그레이드를 가속하고, 팀 간 소통을 개선하는 효과는 시간이 지나면서 축적된다.

이 비대칭이 많은 팀이 eval 도입을 미루는 이유다. 당장 다음 달의 비용은 보이지만, 6개월 뒤의 회귀 감지 가치는 보이지 않는다. 원문은 이것을 복리(compounding) 에 비유한다. 저축의 복리처럼, eval의 가치도 초기에는 미미하지만 시간이 지나면서 기하급수적으로 커진다.


eval-driven development

원문의 가장 도발적인 주장은 eval을 사후 검증이 아니라 사전 정의에 쓰라는 것이다.

Build evals to define planned capabilities before agents can fulfill
them, then iterate until the agent performs well.

일반적인 개발 흐름은 이렇다: 기능을 구현한다 → 테스트를 만든다 → 통과할 때까지 수정한다. eval-driven development는 순서를 뒤집는다: eval을 먼저 만든다 → 에이전트를 개선한다 → eval을 통과할 때까지 반복한다.

이것은 TDD(Test-Driven Development)와 구조적으로 동일하다. 차이는 대상이다. TDD가 코드의 correctness를 사전에 정의하듯, eval-driven development는 에이전트의 capability를 사전에 정의한다.

원문은 Anthropic 내부에서 이 방식을 어떻게 활용하는지 설명한다.

Internally, Anthropic often builds features that work "well enough"
today but are bets on what models can do in a few months. Capability
evals that start at low pass rate make this visible.

Anthropic은 현재 모델로는 "잘 됐으면 좋겠지만 아직 안 되는" 기능을 eval로 미리 정의해둔다. 예를 들어 "에이전트가 10개 파일에 걸친 리팩토링을 올바르게 수행하는가?"라는 eval의 통과율이 현재 30%라고 하자. 이 eval은 실패하고 있지만, 그것이 정상이다. 이것은 미래 모델에 대한 베팅이다.

새 모델이 출시되었을 때 이 eval의 통과율이 65%로 올라갔다면, 해당 기능을 프로덕션에 투입할 시점이 가까워졌다는 신호다. eval이 없었다면 이 기회를 정량적으로 포착할 수 없었을 것이다.

이 패턴은 eval의 역할을 확장한다. eval은 과거를 검증하는 도구일 뿐 아니라 미래를 정의하는 도구가 된다.

기여 범위의 확대

People closest to product requirements and users are best positioned
to define what success looks like. PMs, customer success managers, and
salespeople can use Claude Code to contribute eval tasks as PRs.

eval task는 코드가 아니다. "이 시나리오에서 에이전트가 이렇게 동작해야 한다"는 것을 기술하는 것이다. 이 기술은 엔지니어보다 프로덕트 매니저, 고객 성공 매니저, 영업 담당자가 더 잘할 수 있다. 이들이 사용자의 고통을 가장 가까이서 관찰하기 때문이다.

원문은 이들이 Claude Code를 활용해 eval task를 PR로 기여할 수 있다고 말한다. 엔지니어만 eval을 만드는 것이 아니라, 사용자에 가장 가까운 사람들이 eval을 정의하고, 기술적 구현은 도구가 돕는 구조다. 이것은 eval의 민주화다.


마무리: 비용은 선불, 가치는 후불

이번 편에서 다룬 것을 정리하면 이렇다.

  • 초기: 수동 테스트로 충분한 시기가 있다. 하지만 프로덕션 스케일링 후 "flying blind" 상태에 빠진다.
  • 사례: Claude Code, Descript, Bolt 모두 eval을 나중에 도입했다. 세 팀 모두 결국 eval이 필요해졌다.
  • 시간축별 가치: 요구사항 명확화 → 회귀 방지와 baseline 추적 → 모델 업그레이드 가속과 프로덕트-리서치 소통 채널.
  • eval-driven development: eval을 먼저 만들고 에이전트를 맞추는 방식. 미래 모델 능력에 대한 베팅을 가시적으로 만든다.

eval의 복리 효과를 다시 떠올리자. 비용은 선불이다 -- task를 만들고, grader를 작성하고, 인프라를 구축하는 데 시간이 들어간다. 가치는 후불이다 -- 회귀를 감지하고, 업그레이드를 가속하고, 팀 간 소통을 개선하는 효과는 시간이 지나야 보인다. 이 비대칭을 이해하면, eval에 투자하지 않는 것이 오히려 비싼 선택이라는 것을 알 수 있다.

다음 편에서는 eval의 핵심 구성 요소인 grader 설계를 다룬다. deterministic grader, LLM grader, human grader를 언제 어떻게 조합하는지, 원문을 따라 해부한다.

원문: Anthropic — Demystifying Evals