TDD의 종말: ‘Evaluation Engineering’이 새로운 소스 코드인 이유
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에게 잘해 달라고 애원하지 마세요. 평가를 시작하세요.