89등이라고 믿었는데 265등이었다
종료된 대회의 부검이다. 세 번 떨어진 기록을 순서대로 쓰는 연작의 1편.
삼성 SCPC 2026 AI 챌린지에 나갔다. 참가자 1,845명, 총상금 7,000만원, 과제는 AI 에이전트 하네스였다. 열흘 동안 점수를 0.1136에서 0.8530까지 올렸고, 마지막 이틀은 하루에 다섯 발씩 제출권을 다 썼다. 그리고 마감 두 시간 전에 내 순위가 89등이 아니라 265등이라는 걸 알았다.
두 개를 동시에 틀렸다. 하나는 과녁이 움직이는 걸 계산에 넣고도 못 따라간 것이고, 하나는 순위를 내 눈으로 세고 있었던 것이다. 후자가 더 부끄럽다.
첫날 밤에 컷이 0.54에서 0.84로 올라갔다
첫 제출은 캘리브레이션용이었다. 공식 노트북을 그대로 돌린 베이스라인의 로컬 점수가 0.0882였는데 서버에서 0.1136이 나왔다. 배율 1.29. 로컬이 보수적으로 채점한다는 걸 첫 발로 확인하고, 이후 개선은 로컬 델타로 추적하되 서버 확인은 아꼈다.
그날 저녁 리더보드를 처음 봤을 때 40위 컷은 0.5454였다. 내 점수는 0.5217. 스물네 점 차이니까 하루면 넘겠다고 생각했다.
40분 뒤에 다시 봤다.
| 시각 | 40위 컷 | 1위 | 등재 | 내 점수 / 순위 |
|---|---|---|---|---|
| 07-06 21:30 | 0.5454 | 0.8762 | 84명 | 0.5217 / 42위 |
| 07-06 22:10 | 0.8373 | 0.8932 | 87명 | 0.5217 / 88위 |
컷이 40분 만에 0.29 올라갔다. 점수는 하나도 안 움직였는데 순위가 42위에서 88위로 밀렸다. 세 명이 새로 등재된 사이에 벌어진 일이다. 대회 초반의 리더보드는 실력 분포가 아니라 아직 제출하지 않은 사람들의 대기열이다. 내 앞에 몇 명이 있는지가 아니라, 앞으로 몇 명이 올 것인지가 진짜 좌표다.
여기서 규칙 하나를 만들었다. 목표를 "현재 컷"이 아니라 "마감 시점의 컷"으로 쓴다. 로그 곡선으로 착지 컷을 0.89에서 0.91 사이로 추정하고, 내부 목표를 40위 방어선이 아니라 30위 안착선인 0.895에서 0.90으로 잡았다. 40위는 살얼음이었다. 컷 ±0.002 구간에 열 명이 들어차 있어서 0.001 차이로 다섯에서 열 계단이 흔들렸고, 최종 진출 판정은 내가 보고 있는 Public이 아니라 Private 점수였다.
이 판단 자체는 맞았다고 생각한다. 문제는 그 목표에 도달하지 못한 것이고, 도달 못한 이유가 실력만은 아니었다는 것이다.
궤적: 0.11 → 0.52 → 0.84 → 0.85
| 날짜 | 점수 | 무엇을 바꿨나 |
|---|---|---|
| 07-06 | 0.1136 | 공식 베이스라인 |
| 07-06 | 0.5217 | 하네스 v1 |
| 07-07 | 0.8433 | 응답 템플릿 25종 |
| 07-12 | 0.8530 | 정답 사례 차분 마이닝 |
두 번의 큰 점프와 한 번의 미세 조정이다. 0.11에서 0.52는 하네스 구조를 짜서 얻었고, 0.52에서 0.84는 응답 형식을 스물다섯 가지로 나눠 얻었다. 여기까지 이틀이 걸렸다.
그리고 남은 닷새 동안 0.0097을 올렸다.
정체는 뚜렷했다. 미세 A/B는 한 발에 0.004 정도를 줬는데 필요한 이득은 0.05였다. 열두 발을 쏴도 못 닿는 거리다. 그런데도 나는 하루 다섯 발의 제출권을 미세 A/B에 계속 썼다. 이동량이 큰 구조 가설을 하루에 하나씩 넣기로 규칙을 적어두고도, 실제로는 "지금 손에 있는 것"을 조금씩 비틀었다.
마감 두 시간 전에 진짜 승리 방법이 나왔다. 개발셋에서 내가 틀린 사례와 정답 사례를 전수 대조해 차이를 캐는 방식이었는데, 두 발로 0.0058을 얻었다. 이걸 하루만 일찍 찾았다면 0.009를 더 얻어 0.862였다. 그래도 컷 0.8787에는 못 닿는다. 완벽하게 플레이해서 얻을 수 있던 최대치가 0.877이었으니, 사실 이 대회는 진 게 맞다.
가설을 발명하지 말고 차분을 마이닝하라. 이게 이 대회에서 얻은 가장 값나가는 문장이다. 내가 뭘 잘못했는지 모르는 상태에서 아이디어를 짜내는 것보다, 맞은 것과 틀린 것을 나란히 놓고 차이를 세는 게 훨씬 빠르다. 나는 그 순서를 거꾸로 했고, 닷새를 지불했다.
그런데 순위는 내 눈으로 세고 있었다
여기서부터가 진짜 실패다.
나는 리더보드를 크롤링해서 컷과 내 순위를 자동으로 기록하는 스크립트를 만들어뒀다. 매 사이클 첫 액션이 그걸 돌리는 것이었고, 시계열을 쌓아 컷 상승 속도까지 추정했다. 도구는 잘 작동했다. 다만 순위를 계산하는 방식이 틀렸다.
스크립트가 목록에서 내 위 행의 개수를 셌다. 리더보드는 페이지네이션이 되어 있는데, 스크립트는 첫 페이지에 렌더된 등재자만 보고 있었다. 그래서 "89위 / 89명 등재"처럼 보이는 숫자가 나왔고, 나는 그걸 "등재자 89명 중 89위"로 읽었다. 실제로는 첫 페이지 안에서의 상대 위치였다.
07-12 오전, 마감 당일에 서버가 직접 계산해서 내려주는 내 고정행을 처음 읽었다.
rank 265 / score 0.853
rank 100 cut = 0.8787 (갭 -0.026)
rank 40 cut = 0.889
265등이었다. 그리고 그날 제출권 세 발은 이미 소진돼 있었다. 최종 확정 순위는 305위였다. 마감 뒤에도 제출이 들어오면서 뒤로 더 밀렸다.
더 나쁜 건 이 오독 위에 전략을 세웠다는 점이다. 나는 며칠 전부터 "top-100 입장권은 이미 확보했다"고 판단하고 있었다. 그 전제 위에서 제출권을 탐색용 프로브에 배분했다. 전제가 틀렸으니 그 배분 전체가 틀렸다. 결국 쓸 수 있던 제출 스물다섯 발 중 네 발, 16%를 운영 실수로 허공에 쐈다.
결과는 아마 안 바뀌었을 것이다. 완벽하게 플레이해도 컷에 못 닿았으니까. 그래도 이건 별개의 실패다. 결과에 영향이 없는 실수도 실수다. 다음 대회에서 실력이 컷 근처까지 올라갔을 때 같은 버그를 갖고 있으면, 그때는 결과가 바뀐다.
규칙으로 남긴 것
- 순위는 서버가 계산한 내 고정행만 신뢰한다. 목록에서 행을 세면 페이지네이션에 속는다. 내 위치를 알려주는 API나 화면 요소가 있으면 그것만 읽는다.
- "확보했다"는 전제는 원페이지 밖에서 검증한다. 한 화면에서 얻은 결론으로 예산을 배분하기 전에, 다른 경로로 같은 사실을 확인한다.
- 목표는 현재 컷이 아니라 마감 시점의 컷이다. 컷 상승 속도를 시계열로 재고 착지점을 추정한다. "컷까지 -0.02" 같은 정지 좌표를 쓰지 않는다.
- 필요 이득을 먼저 계산한 다음 수단을 고른다. 0.05가 필요한데 한 발에 0.004를 주는 수를 반복하는 건 산수를 안 한 것이다.
- 가설을 발명하기 전에 차분을 마이닝한다. 맞은 것과 틀린 것의 전수 대조가 아이디어보다 빠르다.
남은 질문
이 대회에서 도구는 잘 만들었다. 로그인 자동화, 제출 전 페이로드 검증, 일일 제출 카운터, 단계별 스크린샷, 리더보드 시계열까지 전부 돌아갔다. 그런데 그 도구가 만들어내는 숫자 하나의 정의를 검증하지 않았다.
자동화를 잘 짜면 오히려 그 출력을 의심하지 않게 된다. 손으로 확인하던 걸 기계에 넘기는 순간, 기계가 틀렸을 때 알아차릴 사람이 없어진다.
다음에 계측 도구를 만들 때 이걸 먼저 물어야 한다. 이 숫자가 틀렸다면 나는 어떻게 알게 되는가?