주말 오디세이 IMAX 예매, 문제는 빈자리가 다시 풀리는 순간이었다
한국 앱 스크린샷
주말 오디세이 IMAX관에서 보고 싶은 영화가 있었다. 문제는 좌석이었다. 원하는 회차는 이미 매진에 가까웠고, 괜찮은 자리가 언제 다시 풀릴지 알 수 없었다.
취소표를 잡는 가장 단순한 방법은 예매 페이지를 계속 새로고침하는 것이다. 하지만 하루 종일 화면을 들여다볼 수도 없고, 잠깐 자리를 비운 사이 좌석이 풀렸다 다 시 사라질 수도 있다.
그래서 Hermes 봇에게 부탁했다.
CGV 대구 오디세이 IMAX관
8월 15일부터 17일까지
오전 10시 30분부터 오후 9시 사이에 시작하는 회차
5분마다 확인
빈자리 수가 직전보다 늘었을 때만 알림
같거나 줄었다면 조용히 있기
요청은 간단했다. 하지만 영화보다 감시기를 만드는 과정이 더 스릴러였다.
첫 번째 답은 “로그인 없이는 어렵다”였다
에이전트가 처음 찾은 CGV API는 403 오류를 반환했다. 접근이 거부되자 에이전트는 좌석 상세 정보는 로그인 세션 없이는 보기 어렵다고 결론지었다. 로그인 정보를 이용하거나 브라우저 자체를 자동으로 조작하는 방식을 제안했다.
하지만 마음에 걸렸다. 네이버 검색 결과에서는 해당 영화의 상영시간과 CGV 예매 링크를 확인할 수 있었기 때문이다. 브라우저에서 실제 예매 흐름이 동작한다면, 어딘가에는 필요한 데이터를 요청하는 경로가 있을 가능성이 있었다.
나는 네이버 검색에서 찾은 실제 예매 URL을 에이전트에게 전달했다.(이것도 확인해줘~)
사람이 찾은 URL에서 에이전트가 구조를 읽었다
예매 URL에는 영화, 극장, 상영관, 날짜, 회차를 구분하는 여러 식별자가 들어 있었다. 에이전트는 처음에는 상영관 번호와 IMAX 포맷 분류 코드를 혼동했다. 내가 다시 짚자 값을 교차검증했고, 실제로 해당 번호가 대구 IMAX관을 지정한다는 것을 확인했다.
이 순간 역할이 자연스럽게 나뉘었다.
나는 검색과 실제 화면에 서 유효한 단서를 가져왔다.
에이전트는 URL의 구조를 해석하고 각 값이 무엇을 뜻하는지 검증했다.
둘이 합쳐지자 정확한 상영회차를 지정할 수 있게 됐다.
AI가 혼자 정답을 찾아낸 것도 아니고, 내가 직접 API를 분석한 것도 아니었다. 사람이 현실의 단서를 건네고 에이전트가 반복 탐색을 맡은 협업이었다.
“안 된다”가 “좌석 API를 찾았다”로 바뀌었다
정확한 회차 식별자가 생기자 에이전트는 예매 페이지의 동적 JavaScript를 다시 추적했다. 그리고 좌석 상태를 반환하는 경로를 찾았다.
이제 결과는 처음 판단과 달랐다.
로그인 없이 상영회차를 조회할 수 있었다.
IMAX관인지 응답으로 다시 확인할 수 있었다.
한 회차의 전체 241석과 각 좌석의 상태를 받을 수 있었다.
어떤 좌석이 예매 가능하고 어떤 좌석이 판매되거나 선점됐는지 구분할 수 있었다.
처음의 403도 “로그인 없이는 불가능하다”는 뜻이 아니었다. 필요한 파라미터가 빠졌고 실제 웹페이지가 사용하는 호출 경로를 아직 찾지 못했던 것이었다.
이번 교훈은 다음과 같다.
에이전트가 말하는 “불가능”은 때때로 “아직 올바른 경로를 찾지 못했다”는 뜻이다.
에이전트도 첫 판단이 성급했다고 인정했다. 다음부터는 불가능과 미확인을 구분하겠다고 했다. 나는 다음에도 너무 빨리 포기하는 것 같으면 한 번 더 찔러보기로 했다.
좌석 조회를 실제 감시기로 바꾸다
API를 한 번 호출하는 것만으로는 취소표를 잡을 수 없다. 사람이 보고 있지 않아도 반복해서 확인하고, 의미 있는 변화가 생겼을 때만 알려주는 시스템이 필요했다.
에이전트는 Python 감시기를 만들었다.
날짜별 상영회차를 가져온다.
원하는 영화, IMAX관, 시작시간 조건에 맞는 회차만 고른다.
각 회차의 예매 가능 좌석 수와 좌석번호를 수집한다.
가장 최근 관측값을 상태 파일에 저장한다.
현재 빈자리 수가 직전보다 늘었을 때만 Telegram으로 알린다.
좌석 수가 같거나 줄었다면 아무 메시지도 보내지 않는다.
최초 실행에서는 현재 좌석을 취소표로 오해하지 않도록 기준값만 조용히 저장했다. 이후 실행부터 직전 상태와 비교했다.
평소에는 5분마다 확인하고, 취소표가 나올 가능성이 높다고 느껴질 때는 20분 동안만 2분 간격으로 바꿨다가 자동으로 원래 주기로 돌아오게 했다. 단순한 스크립트가 아니라 생활 속에서 실제로 쓸 수 있는 감시기가 됐다.
자동화는 한 번 실행됐다고 완성되는 것이 아니었다
감시기가 만들어진 뒤에도 문제는 계속 나왔다.
특정 종료 시각 때문에 감시가 바로 끝났다
스크립트 안에 이전 감시의 종료 시각인 15:00이 남아 있었다. 새로운 한 시간 감시를 등록해도 코드는 이미 종료 시각이 지났다고 판단해 아무 일도 하지 않았다.
해결 방법은 종료 시각을 코드에 영구적으로 박아두지 않는 것이었다. 감시는 재사용 가능한 상태로 두고, 별도의 일회성 정리 작업이 정 해진 시간에 크론을 제거하도록 바꿨다.
고친 파일과 실제 실행 파일이 달랐다
워크스페이스에서 수정한 스크립트와 Hermes 크론이 실제로 읽는 프로필 내부 실행본이 서로 다른 순간도 있었다. 화면상으로는 “수정 완료”였지만 실제 감시기는 이전 코드를 실행할 수 있는 상태였다.
그 뒤부터는 코드 내용만 보지 않았다.
크론이 실제로 읽는 파일 경로
최근 실행 시각과 상태
상태 파일의 갱신 시각
실제 알림 출력
이 네 가지를 함께 확인했다.
메시지는 왔지만 내가 원한 좌석이 아니었다
한 번은 A~C열 좌석만 새로 풀렸는데 알림이 왔다. 나는 앞쪽 좌석에는 관심이 없었다. 기술적으로는 빈자리 증가가 맞았지만 사용자 입장에서는 오탐이었다.
조건을 다시 다듬었다.
A~C열만 풀리면 알리지 않는다.
D열 이후 좌석이 하나라도 새로 풀리면 알린다.
앞쪽 좌석과 원하는 좌석이 함께 풀렸다면 원하는 좌석만 표시한다.
전체 빈자리 증가량은 실제 값 그대로 유지한다.
자동화의 정확성은 데이터가 맞는지만으로 결정되지 않았다. 사용자에게 의미 있는 변화인가까지 반영해야 했다.
조회가 정상이어도 대화 연결에서 막힐 수 있었다
Telegram이 봇 멘션을 중간에서 제거해 Hermes 봇이 자신의 호출로 인식하지 못한 일도 있었다. API와 크론은 정상인데 대화 라우팅에서 끊긴 것이다.
이 경험으로 자동화는 코드 한 파일이 아니라는 걸 배웠다.
데이터 조회 → 상태 비교 → 필터 → 스케줄러 → 메시지 전달 → 사용자의 행동
이 전체 흐름이 이어져야 실제로 쓸 수 있다.
휴대전화의 문자 메시지 스크린샷
마침내 취소표 알림이 도착했다
수정된 감시기는 날짜와 시간을 보기 쉽게 나누고, 좌석 변화를 이렇게 알려줬다.
CGV 대구 IMAX ‘오디세이’ 빈자리 증가
- 8월 15일(토) 18:00
- 2석 → 3석 (+1석)
- 새 좌석: E6변화가 없을 때는 조용했고, 조건에 맞는 좌석이 생겼을 때만 메시지가 왔다. 더 이상 예매 페이지를 계속 새로고침할 필요가 없었다. 알림이 오면 그때 들어가 확인하면 됐다.
그리고 끝내 주말 IMAX관의 오디세이 예매에 성공했다.
처음부터 완벽한 자동화가 있었던 것은 아니다. “안 된다”는 첫 답을 의심했고, 실제 URL을 건넸고, API를 다시 찾았고, 감시기를 만들고, 운영 중 발생한 실패와 오탐을 하나씩 고쳤다. 그 과정 전체가 예매 성공으로 이어졌다.
Hermes 봇은 정답지가 아니라 함께 고치는 동료였다
이번 경험에서 Hermes 봇의 장점은 처음부터 정답을 알고 있다는 데 있지 않았다. 오히려 첫 판단은 틀렸다.
대신 새로운 단서가 들어오자 판단을 수정했고, 사람이 하기 번거로운 반복 탐색과 검증을 맡았고, 찾은 방법을 코드와 크론으로 바꿨다. 나는 실제 환경에서 보이는 단서와 원하는 좌석의 기준을 제공했다.
혼자였다면 에이전트는 너무 일찍 포기했을 수 있다. 나 혼자였다면 계속 새로고침하거나 API와 상태 비교 코드를 직접 만들어야 했을 것이다. 서로 부족한 부분을 메우자 실제 결과가 나왔다.
내가 생각하는 Hermes 봇은 모든 답을 즉시 내놓는 마법사가 아니다.
함께 틀리고, 증거를 찾고, 다시 고치고, 결국 생활의 문제 하나를 해결해내는 동료다.
이번에는 그 동료와 함께 주말 IMAX 취소표를 잡았다.
이번 경험에서 얻은 실전 팁
1. AI의 실패를 최종 결론으로 받아들이지 않는다
“안 된다”는 답을 받으면 어떤 경로를 확인했고 무엇이 막혔는지 묻는다. 새로운 증거가 있다면 함께 건넨다.
2. 실제로 작동하는 URL은 강력한 단서다
문서가 없어도 URL과 네트워크 요청에는 서비스가 대상을 구분하는 방식이 남아 있다.
3. 자동화 조건을 수치로 명 확히 적는다
“빈자리 나오면 알려줘”보다 다음처럼 요청하는 편이 정확하다.
최초 관측은 기준값으로만 저장해.
현재 예매 가능 좌석 수가 직전보다 클 때만 알려줘.
같거나 줄면 아무 메시지도 보내지 마.
새로 늘어난 좌석번호도 함께 표시해.
A~C열만 늘어난 경우는 알리지 마.4. 코드 작성보다 실제 실행 경로를 검증한다
스케줄러가 어떤 파일을 읽는지, 상태가 갱신되는지, 실제 메시지가 도착하는지까지 확인해야 한다.
5. 오탐은 실패가 아니라 요구사항을 선명하게 만드는 데이터다
A~C열 알림은 기술적으로 맞았지만 나에게는 필요하지 않았다. 실제 사용 중 나온 불편을 필터 규칙으로 바꾸자 자동화가 더 쓸모 있어졌다.
마무리
이번 예매는 한 번의 완벽한 프롬프트로 성공한 일이 아니었다. 사람이 단서를 찾고, 에이전트가 검증과 자동화를 맡고, 실제 운영에서 발견된 문제를 다시 사람이 지적하는 과정이 반복됐다.
“안 된다” → “방법을 찾았다” → “감시한다” → “오탐을 고친다” → “실제 예매에 성공한다.”
그 시행착오까지 포함해서, 꽤 Hermes 봇다운 협업이었다.