3장. 정답 fixture가 운영의 기준점이다
평가 데이터는 샘플 입력이 아니다
개발 예제의 sample.json은 대개 프로그램이 실행되는지만 보여 준다. 평가 fixture는 다르다. 입력, 기대 결과, 그 결과를 정한 근거와 위험 등급을 함께 보존한다. 팀이 정책을 바꾸면 기대 결과도 승인 절차를 거쳐 바뀐다.
이 책의 fixtures/claims.json에는 여섯 가지 서로 다른 경계가 있다.
- 중복 결제 소액 자동 승인
- 배송 파손 중액 수동 검토
- 영수증이 빠진 배송 파손
- 단순 변심 거절
- 고액 서비스 장애 수동 검토
- 신청 기간을 넘긴 중복 결제 거절
이 구성이 중요한 이유는 행복 경로보다 서로 비슷해 보이지만 결과가 다른 쌍을 만들기 때문이다. CLM-1001과 CLM-1006은 둘 다 중복 결제이고 결제 ID가 있다. 다른 것은 신청 나이다. 모델이 사유만 보고 승인하면 두 사례의 대비가 회귀를 드러낸다.
데이터 분할보다 누출 방지가 먼저다
실전에서는 개발 세트, 회귀 세트, 출시 전 블라인드 세트를 구분한다. 그러나 파일을 세 개로 나누기만 해서는 충분하지 않다. 프롬프트 작성자가 블라인드 정답을 자주 열어 보거나, 실제 고객 로그를 그대로 복사해 개인 정보를 남기면 평가 신뢰가 깨진다.
추천하는 소유권은 다음과 같다.
- 제품·운영 담당자: 기대 결과와 업무 근거 승인
- 개발자: 실행기와 계측 구현
- QA·안전 담당자: 블라인드 사례와 위험 가중치 관리
- 개인정보 담당자: 비식별 기준과 보존 기간 승인
작은 팀에서는 한 사람이 여러 역할을 맡을 수 있다. 그래도 변경 기록에서 어떤 모자를 쓰고 승인했는지 남겨야 한다.
실습: 실패 유형을 세기
lab/lib.mjs의 score 함수는 전체 정확도와 함께 다음을 센다.
const unsafe = results.filter(
x => x.actual === 'approve' && x.expected !== 'approve'
).length;
실제 환불 손실이 서로 다르면 사례마다 riskWeight를 추가해 가중 합계를 계산할 수 있다. 단, 가중치가 위험 승인을 상쇄하게 해서는 안 된다. 예를 들어 안전한 사례를 많이 넣어 평균 점수를 올려도 위험 승인 1건은 그대로 배포 차단 조건이어야 한다.
실패 훈련
새 fixture를 상상해 보자. 신청 14일째와 15일째, 금액 50,000원과 50,001원, 사진 ID가 빈 문자열인 경우다. 경계 양쪽을 한 쌍으로 넣으면 >와 >= 실수를 빠르게 찾을 수 있다. 이를 경계 쌍이라고 부르자.
완료 기준
- 샘플 데이터와 평가 fixture의 차이를 설명할 수 있다.
- 행복 경로, 경계 쌍, 금지 행동 사례를 각각 하나 이상 만들었다.
- 실제 고객 로그를 정답 세트로 옮길 때 필요한 비식별·승인 절차를 적었다.