본선에는 가지 못했다. 11월 4일에 온 결과 메일은 “아쉽게도 이번 본선에 모실 수 없게 되었습니다”로 시작했다. 개인 점수와 순위는 공개하지 않는다고 해서 몇 점이었는지도 모른다. 다만 심사 중에 봇이 남긴 대화와 API 호출 기록은 내 서버에 그대로 남아 있다. 그 기록을 다시 열어 보면서 무엇을 준비했고, 당일에 어디서 시간을 잃었고, 무엇이 점수를 깎았는지 정리해 둔다.
어떤 대회였나
AI_TOP_100은 카카오임팩트가 여는 AI 활용 대회다. 2026년 온라인 예선은 10월 31일(토) 10시부터 15시까지 진행됐다.
가상의 마을 쇼핑몰에 고객 문의가 쏟아지고, 참가자는 그 문의를 대신 처리하는 상담 에이전트를 카카오톡 봇으로 만들어 낸다. 필요한 지식은 문서로 주어지지 않는다. 쇼핑몰을 운영하는 마을 사람들과 카카오톡으로 인터뷰해서 운영 규정과 현장 사정을 알아내야 하고, 처음에는 한 사람에게만 연락할 수 있어서 다른 사람의 연락처도 인터뷰로 얻어야 한다.
봇은 답만 하는 게 아니라 일도 해야 한다. 주문 조회, 환불 접수, 담당자 이관 같은 처리를 하는 API가 수십 개 주어지고, 심사에서는 필요한 조회와 처리를 제대로 했는지까지 본다. 심사자가 카톡으로 직접 말을 거는데, 응답 속도(p95)와 말풍선 수, 말풍선당 글자 수도 점수에 들어간다. 말풍선 하나가 500자를 넘으면 채점에서 빠지고, 60초 동안 답이 없으면 그 케이스는 거기서 끝난다.
제출물은 카카오톡 봇의 App ID와 에이전트를 설명하는 디브리프였다. 제출은 한 번뿐이고, 제출한 뒤에는 심사가 끝날 때까지 봇을 고칠 수 없다.
일주일 동안 준비한 것
다섯 시간 안에 봇 엔진부터 만들 수는 없다고 보고, 대회 일주일 전부터 당일에는 설정만 바꿔 끼우면 되도록 준비했다.
먼저 봇 엔진(kbot)을 직접 만들었다. 카카오톡 봇 게이트웨이에 WebSocket으로 붙어 메시지를 받고, LLM의 함수 호출로 도구를 실행한 뒤 답장을 보낸다. 한 턴이 중간에 실패하면 그 턴에서 바뀐 상태를 전부 되돌리고, 같은 턴에서 같은 쓰기 요청이 두 번 나가지 않게 했다. 도구 결과나 내부 JSON이 답장에 섞이면 전송 직전에 막는 장치도 넣었는데, 과거 답장 5천여 개로 돌려 봤을 때 정상 답장을 잘못 막은 경우는 없었다.
그 위에 봇 공장(forge)을 얹었다. 같은 문제로 봇을 여러 버전 만들고, 미리 봉인해 둔 숨은 시나리오로 채점해서 가장 나은 버전을 고르는 파이프라인이다. 대회 형식을 흉내 낸 모의 문제도 일곱 개 만들어 처음부터 끝까지 리허설했고, 네 시간마다 점검 라운드를 돌려 대회 당일 아침까지 40번 돌렸다.
리허설에서 의외였던 건 자체 평가가 상위권을 전혀 가려내지 못했다는 점이다. 자체 평가 100점짜리 버전이 숨은 채점에서는 7/10이었고, 73점짜리가 10/10이었다. 그래서 판정 기준을 ‘도구를 어떤 순서로 불렀나’에서 ‘대화에 드러난 행동과 그 결과’로 바꿨다. 모델에 따라 숨은 채점 결과가 크게 갈린다는 것도 이때 알았다. 실전에는 비용과 용량을 따져 Gemini flash-lite 무료 키 여섯 개를 돌려 쓰기로 했고, 계산상으로는 하루 850건 정도를 처리할 수 있었다. 사소하지만 카톡 말풍선이 마크다운을 렌더링하지 않는다는 것도 리허설에서 처음 봤다. 모델이 습관처럼 붙이는 **강조**가 별표째 찍혀 나가서, 전송 직전에 서식을 지우게 했다.
대회 당일
| 시각 | 한 일 |
|---|---|
| 10:05 | 문제 공개, 가이드 확인 |
| 10:07–11:47 | 단계별로 잠긴 화면에서 진행이 멈춤 |
| 12:21 | 스토리 확인, 봇 설정과 도구 작업을 동시에 시작 |
| 12:30–13:00 | AI 에이전트가 카카오톡 앱으로 인터뷰할 수 있게 채널 추가·대화창 열기 스크립트 작성(30분 소요) |
| 13:04–13:55 | 인터뷰 에이전트 다섯 개가 마을 사람을 나눠 맡아 동시에 인터뷰 |
| 13:15 | API 문서를 받아 도구 40개를 자동 생성, 첫 배포 |
| 14:15–14:32 | 지식 병합, 응답 지연 해결, 재배포 |
| 14:34 | 제출 |
오전 10시 7분부터 11시 47분까지 거의 두 시간을 다음 단계가 열리기를 기다리며 보냈다. 하루 중 가장 크게 잃은 시간이다. 결국 다섯 시간 중 봇을 실제로 만들고 다듬은 시간은 두 시간 남짓이었다.
남은 시간에 범위를 넓힐 수 있었던 건 인터뷰를 AI 에이전트에게 나눠 맡긴 덕분이다. 에이전트 다섯 개가 각자 맡은 사람과 카카오톡 앱으로 대화했다. 대회 규정에 맞춰 질문은 한 번에 하나씩 보내고, 답이 온 뒤에만 다음 질문을 하게 했다. 질문 방향과 이미 확보한 문서는 미리 알려 주고, 에이전트들이 정리한 사실은 모아서 봇 지식에 합쳤다. 그렇게 한 시간 만에 열 명 중 일곱 명과 연결됐고, 확인한 사실 160여 개와 원문 문서 여덟 종을 모았다. 마을 사람들은 한 번에 한 주제만 답했다. 그래서 질문을 짧게 하나씩 던지고, 답에 나온 문서나 다른 사람 이름을 따라가며 넓혀 갔다. API는 공식 문서(OpenAPI)에서 도구 40개를 자동으로 만들었고, 엔진이 대화에 담겨 오는 테스트 케이스 ID를 읽어 모든 호출에 붙이게 했다.
마감이 다가오자 문제가 연달아 터졌다. 지식과 도구 설명을 다 넣고 나니 응답 하나에 36–65초가 걸렸다. 60초를 넘기면 케이스가 끝나니 그대로 낼 수는 없었다. 도구 설명을 이름과 한 줄 요약으로 줄이고, 같은 조회를 두 번 하지 말라는 규칙과 45초 턴 상한을 넣어 12–23초까지 내렸다. 그 과정에서 지식 파일을 셸 명령 head -c로 바이트 단위로 잘랐다가, 한글 글자 중간이 잘리면서 파일 전체가 깨져 봇이 2분 동안 멈추기도 했다. 글자 단위로 자르도록 고쳐 다시 배포했다. 마지막 확인에서는 봇이 고객 전화번호를 되읽어 주는 걸 발견했다. 저장된 개인정보를 먼저 불러 주지 말라는 규칙을 넣어 다시 배포했고, 그게 제출 2분 전이었다.
심사 기록으로 본 우리 봇
심사는 그날 17시 21분에 시작해 19분 만에 끝났다. 서른 개 케이스가 거의 쉬지 않고 들어왔다. 답장 133건은 하나도 빠짐없이 나갔고, 응답 시간은 중앙값 7.3초, p95 45.3초였다. p95가 턴 상한 45초에 거의 붙어 있다는 게 마음에 걸려 폴백 답장을 찾아보니 13번이었는데, 전부 처음 다섯 케이스에서 나왔다. 그 뒤 스물네 케이스에서는 한 번도 없었다. API는 140번 불러 18번 실패했다. 대상이 없다는 404가 7번, 테스트 케이스 ID가 빠졌다는 400이 6번이었고, 존재하지 않는 도구 이름을 부른 경우도 5번 있었다.
무엇이 점수를 깎았나
가장 아픈 건 테스트 케이스 ID였다. 공개 예시의 ID가 모두 L-11처럼 영문 한두 글자였고, 나는 정규식을 딱 그만큼만 받게 짰다. 심사에는 NEW-01이 나왔다. 엔진이 이 ID를 못 읽어 헤더를 붙이지 않았고, 그 케이스의 API 호출 여섯 번이 전부 400으로 돌아왔다. 예시만 보고 형식을 정하면 안 된다는 건 알고 있었는데, 마감에 쫓기니 확인하지 않았다.
초반 폴백 13번은 용량 계산을 하루 단위로만 한 탓이다. 무료 키는 키당 분당 15회 정도가 한도라, 심사 초반에 케이스가 겹치자 대기가 길어졌고 45초 상한에 걸렸다. 부하가 풀린 뒤로 폴백이 한 번도 없었던 걸 보면 다른 원인을 찾기 어렵다.
속도를 잡으려고 마지막에 넣은 변경도 문제를 만들었다. 한 턴의 도구 호출 단계를 10에서 6으로 줄였는데, 조회를 여러 번 하고 접수까지 마치면 단계가 바닥났다. 그러면 봇은 접수가 이미 끝났는데도 “아무것도 확정되지 않았다”는 폴백을 보냈다. 제출하고 나서 공개 테스트 케이스로 다시 돌려 보다가 알았고, 그때는 고칠 수 없었다.
인터뷰에서 얻은 내용도 끝까지 반영하지 못했다. 프롬프트에 ‘인터뷰로 채울 것’이라고 비워 둔 자리가 몇 군데 남았다. 규정집에는 재배송을 먼저 하고 그래도 안 되면 환불한다고 되어 있는데, 봇은 바로 환불을 제안했다. 담당자에게 넘기는 기준도 절차서보다 거칠었다.
다음에 바꿀 것
- 문제가 공개되면 제출물, 채점 기준, API 문서부터 챙긴다. 화면이 순서대로 열리는 구조라면 그 흐름을 미리 연습해 둔다.
- 입력 형식은 공개 예시가 아니라 나올 수 있는 범위 전체로 받는다.
- 턴 상한은 단계 수가 아니라 시간으로만 건다. 단계가 바닥나더라도 이미 성공한 접수는 고객에게 알린다.
- 용량은 하루 총량이 아니라 요청이 몰리는 순간을 기준으로 잡는다.
- 마감 30분 전부터는 검증한 변경만 넣는다.
일주일 동안 만든 엔진은 심사 내내 답장을 하나도 빠뜨리지 않았다. 점수가 새어 나간 곳은 마감 직전에 서둘러 내린 판단과, 확인하지 않고 넘어간 가정들이었다.
Comments
Loading comments...