TDD의 종말: ‘Evaluation Engineering’이 새로운 소스 코드인 이유

발행: (2026년 1월 2일 오전 04:44 GMT+9)
7 분 소요
원문: Dev.to

Source: Dev.to

최근에 주니어 엔지니어가 LLM 에이전트를 위한 단위 테스트를 작성하려는 모습을 보았습니다.

그들은 response == "I can help with that"이라는 조건을 검증하려고 했습니다. AI가 “I would be happy to help with that.”이라고 답변해서 테스트가 실패했습니다. 엔지니어는 한숨을 쉬고 문자열을 수정한 뒤 다시 실행했습니다. 또 다시 실패했습니다.

이것이 오늘날 AI 엔지니어링의 현실입니다: 확률적 시스템을 결정론적 상자에 억지로 넣으려다 보니 워크플로우가 깨지고 있습니다.

전통적인 소프트웨어에서는 구현(parse_date())을 작성하고 그 다음에 테스트(assert parse_date("2024-01-01") == date(2024, 1, 1))를 작성합니다. 하지만 AI에서는 the AI writes the implementation. 우리의 역할은 로직을 작성하는 것이 아니라 시험을 작성하는 것이 됩니다.

나는 이를 Evaluation Engineering이라고 부르며, 올해 여러분이 작성할 가장 가치 있는 코드가 될 것입니다.

패러다임 전환: TDD에서 Eval‑DD로

옛 세계에서는 Human이 Coder였고 Machine이 Executor였습니다. 새로운 세계에서는 AI가 Coder이고 Human이 Examiner입니다.

AI의 답변에 대한 모든 창의적인 변형을 포괄하는 단위 테스트를 작성할 수 없습니다. 대신 **Test‑Driven Development (TDD)**에서 **Evaluation‑Driven Development (Eval‑DD)**으로 전환해야 합니다.

Source:

평가 엔지니어링의 3대 기둥

저는 단위 테스트를 대체할 간단한 프레임워크를 만들었습니다. 이는 모든 AI 코드베이스에 필요한 세 가지 핵심 구성 요소로 이루어져 있습니다.

1. 골든 데이터셋 (“스펙”)

프로즈 형식의 사양 작성을 중단하세요. LLM에게는 쓸모가 없습니다. Eval‑DD에서는 데이터셋 자체가 사양입니다.

# The Dataset IS the Spec
dataset.add_case(
    id="edge_001",
    input="Parse this date: 2024-13-01",  # Invalid month
    expected_output="ERROR",
    tags=["invalid", "edge_case"],
    difficulty="hard"
)

이 데이터셋은 “좋은” 결과가 어떤 모습인지 정확히 정의합니다. 이것이 유일한 진실의 원천입니다. AI가 이 데이터셋을 통과하면 프로덕션에 투입할 준비가 된 것이고, 실패하면 아직 준비되지 않은 것입니다.

2. 스코어링 루브릭 (“판정관”)

대부분의 팀은 이진 정확도만을 평가하지만, 실제 답변은 정확하지만 독성이 있거나 안전하지만 쓸모가 없을 수 있습니다. ScoringRubric 클래스를 사용하면 가중치를 부여한 다차원 평가가 가능합니다.

rubric = ScoringRubric("Customer Service Rubric", "Evaluates correctness AND tone")

# Correctness is important...
rubric.add_criteria(
    dimension="correctness",
    weight=0.5,
    description="Does it solve the problem?",
    evaluator=correctness_evaluator
)

# ...but so is not being a jerk.
rubric.add_criteria(
    dimension="tone",
    weight=0.4,
    description="Is it polite and empathetic?",
    evaluator=tone_evaluator
)

AI가 “그냥 비밀번호 찾기를 클릭하면 돼요, 당연하죠” 라고 답한다면 다음과 같은 점수를 받게 됩니다:

  • 정확도: 10/10
  • 톤: 0/10
  • 최종 점수: 5/10 (실패)

이는 단순 assert 문으로는 포착할 수 없는 미묘한 차이를 반영합니다.

3. 평가 러너 (“테스트 스위트”)

러너는 골든 데이터셋에 대해 AI를 실행하고, 루브릭으로 채점하여 pytest를 대체합니다. 통과율을 보고하고 프롬프트 엔지니어링이 제대로 작동했는지 알려줍니다.

runner = EvaluationRunner(dataset, rubric, my_ai_function)
results = runner.run(verbose=True)

if results['pass_rate'] > 0.9:
    print("🎉 AI meets requirements!")
else:
    print("❌ AI needs improvement")

왜 이것이 중요한가

It changes how you work.

  • Rubric을 먼저 작성하세요. 프롬프트를 만들기 전에 성공이 어떤 모습인지 정의하세요.
  • 프롬프트를 반복하세요, 코드는 아니에요. 테스트가 실패하면 Python 로직을 다시 쓰는 대신 시스템 프롬프트나 few‑shot 예시를 조정하세요.
  • “소스 코드”가 이동합니다. 지적 재산은 더 이상 래퍼 코드가 아니라; IP는 평가 스위트입니다.

시니어 엔지니어의 새로운 직무

AI가 당신의 코딩 일을 빼앗을까 걱정한다면, 걱정하지 마세요. 일은 이제 바뀌었습니다.

이제 어려운 부분은 코드를 생성하는 것이 아니라(커서, 코파일럿이 할 수 있습니다) 다음과 같습니다:

  • Golden Dataset 정의하기 (에지 케이스를 포착하기).
  • Rubric 조정하기 (엔지니어링 판단을 가중치로 인코딩하기).
  • Failures 분석하기 (AI가 왜 실수했는지 를 파악하기).

우리는 결정론적 논리의 시대를 떠나 확률적 엔지니어링의 시대에 진입하고 있습니다. 프롬프트로 AI에게 잘해 달라고 애원하지 마세요. 평가를 시작하세요.

Back to Blog

관련 글

더 보기 »

RGB LED 사이드퀘스트 💡

markdown !Jennifer Davis https://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%...

Mendex: 내가 만드는 이유

소개 안녕하세요 여러분. 오늘은 제가 누구인지, 무엇을 만들고 있는지, 그리고 그 이유를 공유하고 싶습니다. 초기 경력과 번아웃 저는 개발자로서 17년 동안 경력을 시작했습니다.