AI한테 주문 읽기 시험 29문제를 냈다. 지난 글은 시험지 만드는 법이었고, 오늘은 채점이다.
채점이 따로 한 편인 이유가 있다. 채점을 잘못 만들면 점수가 거짓말을 한다.
모른다. 어떤 5개인지가 빠져 있기 때문이다.
오타 섞인 문제 5개를 틀렸으면 내놔도 된다. 근데 그중 하나가 "취소해 주세요"를 새 주문으로 잡은 거라면? 나머지를 다 맞아도 못 내놓는다. 취소한 손님한테 물건이 또 가는 프로그램이니까.
그래서 채점을 개수로 하면 안 된다. 등급으로 해야 한다.
내 채점기의 등급은 4개다. 기준은 하나 — 되돌릴 수 있는가. 이 프로그램에서 되돌릴 수 없는 순간은 엉뚱한 물건이 트럭에 실리는 순간이다.
치명 엉뚱한 물건이 실린다. 되돌릴 수 없다
위험 애매한 걸 확인 없이 확정했다. 이번엔 맞았어도 다음엔 치명이 된다
누락 주문을 놓쳤다. 거래처가 전화한다. 고칠 수 있다
무해 "확인해 주세요"를 남발했다. 느려질 뿐이다
여기서 원칙이 하나 나온다.
틀린 확정이, 확정 못 한 것보다 나쁘다.
당연한 말 같은데 실전에서는 반대로 만들고 싶어진다. "확인 필요가 너무 많이 떠요"라는 불평을 듣고 확신 기준을 낮추는 것이다. 그러면 화면은 깔끔해진다. 그리고 사고는 화면 밖에서 나기 시작한다.
치명 0 · 누락 1 → 내놓는다. 놓친 건 사람이 잡는다
치명 1 · 나머지 만점 → 못 내놓는다. 그 1이 언제 또 나올지 모른다
점수는 같은데 운명이 갈린다.
채점기도 결국 내가 짠 코드다. 내 코드가 늘 그렇듯 버그가 있었다.
사고 하나 — 형식 때문에 빵점. AI 답안이 내용은 완벽한데, 답을 담는 데이터 형식(JSON)의 맨 끝이 잘려서 왔다. 채점기는 "형식 깨짐 = 치명"으로 처리했다. 내용 100점을 마지막 중괄호 하나 때문에 빵점 만든 것이다.
고친 방법은 단순하다. 열린 괄호 수를 세서 모자란 만큼 닫아준다. 따옴표 안의 괄호는 세지 않는다. 실제 코드는 저장소의 parse_json에 있다.
사고 둘 — 잘한 답에 벌점. "250박스 5개"라는 문제에 AI가 이렇게 답했다.
판정: 확인 필요
유력 후보: 택배박스 250
사유: '개'가 박스면 5박스, 낱장이면 0.1박스라 확정 불가
확인을 요청하면서 힌트까지 주는 친절한 답이다. 근데 채점기는 후보 칸이 채워진 것만 보고 "확정해버렸네?" 하고 오답 처리했다. 판정 칸을 먼저 읽도록 고쳤다.
교훈: 채점기가 틀리면 멀쩡한 AI를 고치게 된다. 그리고 고칠수록 나빠진다.
AI가 낸 답을 버리지 말고 파일로 저장해둔다. 이 프로젝트에서 바뀐 건 AI 답이 아니라 채점 쪽이었다 — 정답지를 세 번, 채점기를 두 번 고쳤다. 고칠 때마다 29문제를 다시 채점해야 하는데, 답을 저장해뒀으면 저장된 답으로 다시 채점만 하면 몇 초로 끝난다. 안 해뒀으면 채점 한 번 다시 하려고 AI를 29번 다시 불러야 한다. 보관해둔 답안지를 다시 채점하느냐, 학생들을 다시 불러 시험을 또 보게 하느냐의 차이다. 나는 이걸 --rescore(재채점) 옵션으로 만들었다.
결과는 한 건 끝날 때마다 바로 저장한다. 다른 실험에서 데이터 5,578건을 받으면서 마지막에 한 번에 저장하는 구조로 짰다가, 마지막 요청이 실패하면서 앞의 5,000건이 통째로 날아갔다. 유료 API라 날아간 5,000건이 전부 돈이었다. 그날 배웠다.
시험 결과를 받으면 물을 것은 "몇 개 맞았나"가 아니다. "틀린 것 중에 되돌릴 수 없는 게 있나"다.
그래서 이 채점기 결과에서 실제로 보는 줄은 하나다. 치명이 0이면 내놓는다. 치명이 1이면 나머지가 만점이어도 못 내놓는다.
덧. 다음 글 — 3배 비싼 모델이 이긴 건 딱 한 문제였다.
덧2. 새 실험이 끝날 때마다 메일로도 보냅니다 → AI 검증 노트