목차 열기
02. 워크플로우 — FlowState 상태머신
에이전트는 예매 흐름을 그래프 기반 상태머신으로 관리합니다. 전체 흐름이 8개의 상태로 분리되며, 각 상태는 "지금 무엇을 해야 하는가"를 정의합니다. 한 상태의 일이 끝나면 반환값만 보고 다음 상태로 전환됩니다.
상태 정의
| 상태 | 명칭 | 역할 | 대응 UI 단계 |
|---|---|---|---|
| S0 | Init | 브라우저 기동·세션 복원 | 경기 상세 페이지 접근 |
| S1 | Pre-entry | 예매 버튼 클릭, 대기열 진입 | 경기 상세 → 대기열 |
| S2 | Queue | 큐 통과 대기 | 대기열 화면 |
| S3 | Security | 보안 챌린지 풀이 (인터럽트) | 챌린지 팝업 |
| S4 | Section (MAP) | 직접 좌석 선택 모드 — 구역 클릭 | 구역 선택 화면 |
| S4R | Recommend | 좌석 추천 모드 — 추천 카드 로드 | 추천 결과 화면 |
| S5 | Seat (MAP) | 좌석표에서 좌석 선택 + 예매 요청 | 좌석표 화면 |
| S5R | Accept | 추천 카드 수락 또는 자동 선택 | 추천 결과 확정 |
| SX | Terminal | DONE · BLOCKED · ABORT 중 하나로 마감 | 결제 페이지 / 차단 / 오류 |
전이 흐름
LangGraph FlowState state machine
문서 이미지를 큰 화면으로 확인합니다.
실선 = 정상 전이, 점선 = 실패 / 인터럽트. S3는 어떤 활성 상태에서도 발생 가능하고, 풀이 성공 시
last_non_security_state로 복귀 (공격 에이전트는 방어를 블랙박스로 가정).
상태별 반환 규칙
각 상태는 다음 상태를 값으로만 반환합니다. 상태 내부에서 직접 다음 상태를 호출하지 않습니다.
| 현재 상태 | 반환 가능 다음 상태 | 설명 |
|---|---|---|
| S0 | S1, SX(ABORT) | 세션 복원 실패 시 중단 |
| S1 | S2, S3, SX(BLOCKED), SX(ABORT) | 큐 진입 성공/차단 구분 |
| S2 | S4, S4R, S3, SX(ABORT) | 모드에 따라 분기 |
| S3 | 이전 상태, SX(BLOCKED) | 챌린지 성공 시 원복, 실패 시 종료 |
| S4 | S5, S3, SX(BLOCKED), SX(ABORT) | 구역 선택 후 좌석 단계 |
| S4R | S5R, S4 (폴백), S3, SX(BLOCKED), SX(ABORT) | 추천 없으면 직접 좌석 선택 폴백 |
| S5 | SX(DONE), S5 (재시도), S3, SX(BLOCKED) | 좌석 확보 or 재시도 or 종료 |
| S5R | SX(DONE), S5R (재시도), S3, SX(BLOCKED) | 동일 |
인터럽트 처리 — 보안 챌린지
보안 챌린지는 어느 단계에서든 갑자기 뜰 수 있습니다. 모든 상태는 공통 인터럽트 패턴으로 처리합니다.
┌──────────────────────────────────────────┐
│ 현재 상태 N 진입 │
│ ↓ │
│ 챌린지 가시성 체크 │
│ ↓ (감지됨) │
│ last_non_security_state ← 상태 N 저장 │
│ ↓ │
│ S3 전환 │
│ ↓ (챌린지 풀이) │
│ last_non_security_state 값으로 복귀 │
│ ↓ │
│ 상태 N 재진입 → 이어서 진행 │
└──────────────────────────────────────────┘
복귀 가능 상태
다음 상태들만 last_non_security_state로 저장 가능합니다. 즉 챌린지 복귀 대상이 될 수 있습니다.
- S0, S1, S2, S4, S4R, S5, S5R
- S6, SX는 제외 — terminal 상태로 복귀 불필요
TIP — 이 패턴 덕분에 각 단계별로 "챌린지가 뜨면 어디로 돌아가야 하나"를 개별 구현할 필요가 없습니다. 모든 복귀 로직이 한 지점에 집중됩니다.
상태별 세부 동작
S0 — 초기화
| 구분 | 내용 |
|---|---|
| 목적 | 브라우저 기동, 저장된 세션으로 로그인 상태 복원 |
| 주요 동작 | 브라우저 컨텍스트 생성, 쿠키·저장소 로드, 초기 페이지 접근 |
| 성공 조건 | 대상 서비스 도메인에 인증된 상태로 접근 가능 |
| 실패 처리 | 세션 만료 시 SX(ABORT) |
| 기록 이벤트 | RUN_START, BOOTSTRAP_COMPLETE |
S1 — 예매 진입
| 구분 | 내용 |
|---|---|
| 목적 | 예매 버튼 클릭, 대기열 진입 |
| 주요 동작 | 오픈 시각 정밀 대기, 예매 버튼 탐색, 클릭 |
| 성공 조건 | 서버가 정상 응답(2xx) 또는 큐 진입 URL 반환 |
| 실패 처리 | 큐 미개방(409) 시 재시도 / 차단(403) 시 SX(BLOCKED) |
| 기록 이벤트 | PRE_ENTRY_QUEUE_OPENED, ENTRY_CLICKED |
자세한 내용은 03-open-at-sync 참조.
S2 — 대기열 통과
| 구분 | 내용 |
|---|---|
| 목적 | 큐 통과 대기, 다음 단계 진입 |
| 주요 동작 | URL 변화 감시, 보안 챌린지 가시성 폴링 |
| 성공 조건 | 구역 선택 또는 추천 카드 UI 로드 확인 |
| 실패 처리 | 타임아웃 시 SX(ABORT) |
| 기록 이벤트 | QUEUE_PASSED |
S3 — 보안 검증 인터럽트
자세한 내용은 05-vqa-solver 참조.
S4 — 구역 선택 (직접 좌석 선택 모드)
| 구분 | 내용 |
|---|---|
| 목적 | 목표 구역 클릭해 좌석표 로드 |
| 주요 동작 | 인원수 드롭다운 설정, 목표 구역 탐색, 사전 마우스 이동, 클릭 |
| 성공 조건 | 서버가 좌석표 데이터 응답(2xx) |
| 실패 처리 | 403 → SX(BLOCKED) / 4xx → S3 재진입 |
| 기록 이벤트 | SECTION_SELECTED (구역 이름 포함) |
S4R — 구역 선택 (좌석 추천 모드)
| 구분 | 내용 |
|---|---|
| 목적 | 시스템 추천 카드 로드 |
| 주요 동작 | 인원수 드롭다운 조작, 추천 API 응답 감시, 카드 가시화 대기 |
| 성공 조건 | 추천 카드 또는 자동 선택 버튼 가시화 |
| 실패 처리 | 결과 없음 시 직접 좌석 선택 모드로 폴백(S4) |
S5 — 좌석 선택 (직접 좌석 선택 모드)
| 구분 | 내용 |
|---|---|
| 목적 | 좌석표에서 좌석 선택 + 예매 요청 |
| 주요 동작 | 스웜 공유 점유 리스트 + 코디네이터 제외 좌석 병합, 연석 탐색, 클릭 |
| 성공 조건 | 좌석 확보 API 2xx + 결제 페이지 리다이렉트 |
| 실패 처리 | 좌석 충돌(409) → 재시도 / 403 → SX(BLOCKED) |
| 기록 이벤트 | PAYMENT_PAGE_REACHED (좌석 라벨 포함) |
좌석 분산 전략
- 에이전트별 담당 구역·시작 열을 다르게 배정해 충돌 최소화
- N연석 필요 시 같은 행의 인접 좌석 탐색
S5R — 추천 수락
| 구분 | 내용 |
|---|---|
| 목적 | 추천 카드 수락 또는 자동 선택 버튼 클릭 |
| 주요 동작 | 카드 순차 클릭 또는 자동 선택 |
| 성공 조건 | 좌석 확보 API 2xx + 결제 페이지 리다이렉트 |
| 기록 이벤트 | RECOMMEND_CARD_SELECTED, RECOMMEND_BOOK_CLICK, RECOMMEND_AUTO_CLICK |
SX — 종료
| 종료 사유 | 의미 | 발생 조건 |
|---|---|---|
| DONE | 좌석 확보 성공 | 결제 페이지 도달 |
| BLOCKED | 방어 차단 | 403 응답, 챌린지 풀이 실패 등 |
| ABORT | 내부 실패 | 타임아웃, 세션 만료, 예외 |
NOTE — DONE 상태에서 브라우저는 자동으로 닫히지 않습니다. 사용자가 수동으로 결제를 완료할 수 있도록 유지됩니다.
그래프 기반 상태머신이 주는 이점
| 이점 | 설명 |
|---|---|
| 디버깅 가능성 | "구역 선택 단계에서 막혔다"처럼 원인을 단계 수준으로 좁힐 수 있음 |
| 인터럽트 일관성 | 모든 상태가 같은 패턴으로 챌린지 복귀 처리 |
| 흐름 예측성 | 상태 안에서 다음 상태를 직접 호출하지 않음 → 분기 로직 한곳에 집중 |
| 확장성 | 새로운 상태(예: 대기 시간대별 분기)를 기존 코드 건드리지 않고 추가 가능 |
참조
- 03-open-at-sync — S1 오픈 시각 동기화 세부
- 05-vqa-solver — S3 보안 챌린지 풀이
- 11-events-reference — 이벤트 카탈로그 전체