5.7.1 유닛 테스트용 최소 기능 데이터셋(Minimal Functional Dataset) 구성

5.7.1 유닛 테스트용 최소 기능 데이터셋(Minimal Functional Dataset) 구성

유닛 테스트(Unit Test)의 황금률은 ’속도(Speed)’다. 수천 번의 커밋(Commit) 속에서 끊임없이 구동되어야 하는 테스트 스위트가 모델 평가를 핑계로 수천 건의 프롬프트를 처리하느라 분 단위의 시간을 소모한다면, 그 파이프라인은 결국 개발자들에게 버림받게 된다. 더군다나 LLM API를 직접 호출하는 방식(VCR이 없는 환경 등)을 채택했다면, 무수한 테스트 데이터는 곧 막대한 클라우드 과금으로 직결된다.

따라서 AI 파이프라인의 핵심 로직을 검증하기 위한 골든 샘플(Golden Sample)은 방대한 빅데이터가 아니라, 철저하게 가지치기된 **최소 기능 데이터셋(Minimal Functional Dataset, MFD)**으로 응축되어야 한다.

1. 최소 기능 데이터셋(MFD)의 설계 철학

MFD의 목표는 “가장 적은 수의 케이스로 가장 넓은 범위의 코드 경로(Code Path)와 프롬프트 로직을 찔러보는 것“이다. 비슷비슷한 정상(Happy Path) 문장 100개를 테스트하는 것은 컴파일 체력 낭비일 뿐이다. 진정한 MFD는 비즈니스 로직의 결절점(Node)마다 하나씩, 스나이퍼처럼 배치된 5~10개의 정밀한 샘플들로 구성된다.

완벽한 MFD를 구성하기 위한 필수적인 픽스처(Fixture)의 분류는 다음과 같다.

  1. 결정적 정답 투척 (Clear Positive): 모호함이 0%인 완벽한 입력. (예: “2023년 10월 5일에 발생한 5만원 결제를 취소해주세요.”) 파서(Parser)의 기본 작동을 보장하는 베이스라인이다.
  2. 명백한 거절 유도 (Clear Negative): 시스템이 정중하게 ’처리할 수 없음’을 반환해야 하는 입력. (예: “너희 회사 사장님 전화번호 내놔.”) 안전성 필터와 폴백(Fallback) 로직이 살아있는지 검사한다.
  3. 경계값 충돌 (Boundary Condition): 비즈니스 룰의 턱밑을 간질이는 입력. (예: “환불 기한이 오늘까지인데, 내일 환불해 줘.”) LLM의 추론이 내부 코드 룰 기반의 오라클과 정면충돌하지 않는지 검증한다.

2. 데이터셋의 물리적 구조화 (JSON Lines 기반 관리)

MFD는 코드베이스 내부에 깔끔하게 보관되고 버전 관리(Git)의 통제를 받아야 하므로, 기계와 인간이 모두 읽기 편한 JSON이나 JSONL(JSON Lines) 포맷으로 독립 파일에 저장할 것을 권장한다.

[tests/fixtures/mfd_refund_logic.json]

[
  {
    "scenario_id": "TC_001",
    "description": "정상적인 환불 기한 내 요청 (Clear Positive)",
    "user_input": "어제 산 바지 환불할게요.",
    "expected_oracle_verdict": "APPROVE"
  },
  {
    "scenario_id": "TC_002",
    "description": "욕설이 섞인 비정상 요청 (Policy Violation)",
    "user_input": "이딴 쓰레기 옷 당장 환불해 X새끼야",
    "expected_oracle_verdict": "REJECT_WITH_WARNING"
  }
]

3. MFD 구동과 결정론적 매트릭스 테스팅

파이썬의 pytest 환경에서는 @pytest.mark.parametrize와 같은 데코레이터를 사용하여 MFD 파일을 읽어 들이고, 이 최소한의 샘플들을 파이프라인에 병렬로 쏟아부을 수 있다.

import json
import pytest

# MFD 픽스처 파일 로드
with open("tests/fixtures/mfd_refund_logic.json") as f:
    mfd_dataset = json.load(f)

# 데이터셋을 반복하며 매트릭스 테스트(Matrix Testing) 수행
@pytest.mark.parametrize("test_case", mfd_dataset, ids=lambda tc: tc["scenario_id"])
def test_refund_logic_with_mfd(test_case):
    # AI 에이전트 구동
    actual_verdict = my_refund_ai_agent.process(test_case["user_input"])
    
    # MFD의 기댓값과 실제 AI의 결괏값이 100% 일치하는지 결정론적 오라클 검증
    assert actual_verdict == test_case["expected_oracle_verdict"]

MFD는 크기가 작으므로 VCR(응답 녹화) 패턴을 적용하기도 수월하며, 프롬프트를 대규모로 리팩토링할 때마다 불과 수십 초 안에 시스템의 퇴행(Regression) 여부를 100%의 타율로 알려주는 파이프라인의 심전도(ECG) 모니터로 활약한다. 우리는 가장 영리하게 선별된 극소수의 데이터만으로 거대한 언어 모델의 멱살을 움켜쥐어야 한다.