채점기가 모델보다 자주 틀렸다

자는 동안 800회 넘게 검증을 돌리고 아침에 실패 목록을 보니 8건 이상이 측정 도구 결함이었다. 도구를 고치고 나서 남은 진짜 결함으로 설정 실험 1,000회. 넘은 것 셋, 벽 넷

집에 둔 GPU 장비에 vLLM을 올려 로컬 모델을 직접 서빙하고 있다. 엔진과 모델을 고른 뒤라 이 서버의 실력을 처음으로 제대로 재는 자리였고, 시나리오와 합격선을 먼저 정해 둔 채 자는 동안 밤새 돌렸다. 아침에 열어 본 실패 목록이 정말 모델의 실패인지가 문제였다.

하려던 것

엔진과 모델을 확정했으니 이제 이 서버가 실제로 뭘 할 수 있는지 재야 했다. 도구 호출, 장문 이해, 도메인 지식, 구조화 출력, 검색. 8월 19일 밤에 시나리오 40개와 조건 4개를 짜고, 결과를 보기 전에 합격선을 문서에 못 박았다.

이제 나는 자러 갈 건데 내일 아침에 와서 확인할 거야. 토큰을 모두 쓸 정도로 완벽하게 테스트해줘.

어떻게 시켰나

밤새 800회를 넘게 돌았다. 그날 하루 합계로는 1,700여 회에 검색 실험 400여 회가 따로 붙었다. 아침에 실패 목록을 열었다.

어디서 막혔나

실패로 찍힌 것의 상당수가 모델이 아니라 채점기 쪽 문제였다.

모델의 답채점기가 찾던 것실제
“09:00 ~ 15:30”9시 패턴만 인정정답
“9조 2,000억”9.2조만 인정정답
“1조 2,340억원”숫자 추출 결과 “1”정답
“첫 번째 금요일”첫째 금요일정답

도메인 지식 항목이 84/93에서 93/93으로 바뀌었다. 하네스 자체가 망가진 것도 있었다. 장문 니들 테스트는 바늘을 개행 경계에 꽂도록 짰는데 공시 원문에 개행이 없었다. 깊이 20%부터 80%까지 전부 1,877자 같은 자리에 꽂혔다. 깊이 축이 통째로 가짜였다. 고치니 40/45가 실은 74/75였다. 계산 도구 픽스처는 입력과 무관하게 46.6을 돌려주고 있어서 모델이 옳게 위임해도 채점에서 떨어졌다. 빈 답변 5건은 오답이 아니라 max_tokens 부족이었다. 올리니 71%가 97%가 됐다.

거짓 실패가 8건을 넘었다. 한 번은 반대로 갔다. 채점을 느슨하게 고치다가 “영업이익 499조”를 통과시킬 뻔했는데, 원문을 다시 읽으니 실제 기사를 그대로 옮긴 것이었다. 환각이 아니라 헤지 실패였다. 환각 0/9와 헤지 실패 2/3으로 갈라서 다시 셌다. 이날 정한 규칙은 하나다. 실패로 찍힌 항목은 원문을 읽기 전까지 실패가 아니다.

어떻게 풀었나

도구를 고치고 남은 진짜 결함은 이랬다. 도구가 20개를 넘으면 원시 토큰이 답변으로 샌다. 경계는 18개와 20개 사이이고 기울기가 아니라 절벽이다. tool_choice는 템플릿이 참조하지 않아 완전히 무력하다. json_schema와 tools를 같이 쓰면 특정 프롬프트 문구와 조합될 때만 수치가 손상된다. 도구 루프에 빠지면 빈 답변이 나온다.

이걸 설정으로 넘을 수 있는지 실험 7종, 약 1,000회를 돌렸다.

넘은 것 셋. 내장 도구 28개를 15개로 줄이니 요청당 오버헤드가 4,251토큰에서 1,994토큰으로 줄고 누출이 사라졌다. 시스템 프롬프트 두 줄로 상식 이탈 지적이 0/5에서 4/5가 됐다. 숫자 필드를 string으로 받으니 수치 손상이 0/10이었다.

벽 넷. 검색은 8조건 전부 미달이었는데 원인이 설정이 아니었다. 금융 사이트가 봇을 막아 3바이트를 돌려준다. 400회를 돌리고 나서야 인정했다. 도구 루프는 페널티를 주자 6건이 8건으로 늘었다. 장문과 대화 격리는 3조건 전부 미달. tool_choice는 서버에서 할 게 없다. 샘플링은 무관했다. 온도와 top_p를 어떻게 흔들어도 안정 항목 120/120이었고, 반복 측정의 잡음 바닥은 ±8%p였다.

Claude Code의 결론이 정확했다. “벽 넷은 서버 설정이 아니라 호출하는 쪽 코드다.”

배운 점