Playball Logo

Command Palette

Search for a command to run...

목차 열기

06. 스웜 인프라

에이전트 여러 개를 동시에 돌리는 것 자체는 어렵지 않습니다. 하지만 서로 덜 충돌하면서도 서로의 성공을 활용하려면 단순 병렬 실행 이상의 구조가 필요합니다. 이를 위해 관측 · 결정 · 반영 세 가지 역할을 명시적으로 분리했습니다.

3단 역할 분리 (발행–구독 패턴)

역할담당특징
관측이벤트 버스구독자별 큐 분리, 가득 차면 오래된 이벤트부터 버림, 블로킹 없는 발행
결정LLM 코디네이터이벤트를 버퍼에 모으고 조건 맞을 때만 LLM 호출
반영공유 전략 저장소읽기는 잠금 없이, 쓰기는 잠금 사용

핵심 이점

에이전트는 LLM 응답을 기다리지 않습니다. 이벤트 발행 후 즉시 다음 동작을 계속하고, LLM은 백그라운드에서 처리됩니다. 에이전트가 결정이 필요한 순간에는 최신 전략을 그냥 읽기만 하면 됩니다.

이벤트 버스

구조

[에이전트 1~N]
    ↓ publish(event)
[이벤트 버스]
    ├─→ [구독자 A 큐]  → 코디네이터
    ├─→ [구독자 B 큐]  → 모니터
    └─→ [구독자 C 큐]  → 감사 로거

특성

특성내용
패턴발행-구독 (Pub/Sub)
구독자 큐각 구독자별로 독립된 큐 보유
드롭 정책큐 가득 참 시 가장 오래된 이벤트부터 제거
발행 특성블로킹 없음 — 에이전트는 발행 후 즉시 다음 동작 계속
상관관계 방지한 구독자의 느린 처리가 다른 구독자에 영향 없음

이벤트 구조

필드타입설명
ts_msinteger이벤트 발생 시각 (Unix ms)
eventstring이벤트 종류
flow_statestring당시 FlowState
agent_idinteger발행 에이전트 순번
session_idstring세션 식별자
그 외object이벤트별 추가 정보

감사 로그 동시 기록

이벤트 버스로 발행되는 순간 구조화된 로그 파일에도 동시에 기록됩니다. 발표-구독 오버헤드와 영구 기록을 분리된 경로로 처리합니다.

공유 전략 저장소

에이전트가 결정 지점에서 최신 전략을 읽는 in-memory 저장소.

비대칭 동기화 — 잠금 없는 읽기 / 잠금 쓰기

연산빈도동기화 방식지연
전략 읽기매우 잦음 (매 결정 지점)잠금 없음마이크로초
전략 쓰기드뭄 (LLM 응답 수신 시)잠금 사용수 ms

왜 비대칭인가

이유설명
읽기 잠금의 비용매 결정 지점마다 잠금 경합 시 ms 단위 지연 누적 → 결정 지점이 느려짐
쓰기 원자성의 필요LLM 응답 처리 시 여러 필드를 한 번에 원자적으로 업데이트해야 함
메모리 일관성 완화약간 오래된 전략을 잠깐 읽어도 무방 (LLM 응답 주기가 어차피 수초)

설계 원칙: "완벽한 동기화보다 빠른 반응 속도"

저장 항목

필드의미변경 주체
zone에이전트별 목표 구역코디네이터
party_size에이전트별 예매 인원코디네이터
seat_order좌석 선택 순서 (앞열·좌/우 우선 등)코디네이터
zone_blacklist차단된 구역 목록코디네이터
excluded_seats다른 에이전트가 이미 확보한 좌석좌석 확보 이벤트 (결정론)
vqa_gate동시 챌린지 풀이 제한 세마포어런처 초기화

에이전트의 "결정 지점"

에이전트는 다음 시점에 공유 전략 저장소를 읽습니다.

지점읽는 값
S1 Pre-entryparty_size (드롭다운 사전 설정)
S4 Section 진입zone, party_size
S4R Recommend 진입party_size
S5 Seat 선택excluded_seats, seat_order, party_size
S5R Acceptparty_size

런처

스웜 전체의 생명주기를 관리합니다.

주요 책임

책임내용
스웜 초기화구성 파일 로드, 에이전트·코디네이터·모니터 객체 생성
이벤트 버스·전략 저장소 생성스웜 공유 자원 준비
에이전트 병렬 시작에이전트 N개를 비동기로 동시 실행
시간차 투입에이전트 순번별 start_delay_ms 주입
백그라운드 태스크 관리코디네이터·모니터 수명 관리
종료 처리모든 에이전트 terminal 진입 후 요약 파일 생성

스웜 실행 순서

1. 구성 파일 로드
2. 이벤트 버스 생성
3. 공유 전략 저장소 생성
4. 코디네이터 생성 (비활성 플래그 없을 때)
5. 모니터 생성 (비활성 플래그 없을 때)
6. 감사 로거 구독자 연결
7. 코디네이터·모니터 백그라운드 태스크 시작
8. 에이전트 N개 비동기 병렬 시작
    ├─ agent 0: 즉시
    ├─ agent 1: start_delay_ms × 1 뒤
    ├─ ...
    └─ agent N-1: start_delay_ms × (N-1) 뒤
9. 모든 에이전트 terminal 대기
10. 자동 평가 → 요약 파일 저장
11. 종료

좌석 확보 성공 이벤트의 특수 처리

좌석 확보는 LLM 판단 없이 결정론 사이드 이펙트가 즉시 실행되는 유일한 경우입니다.

[에이전트 A] 좌석 확보 성공 (PAYMENT_PAGE_REACHED)
    ↓ 이벤트 버스로 발행
[코디네이터 수신]
    ↓
[1] 결정론 사이드 이펙트 즉시 실행 (LLM 호출 전)
    → 확보된 좌석 라벨을 다른 모든 에이전트의 excluded_seats에 추가
    ↓
[2] LLM 호출 (구역 블랙리스트 갱신 등 넓은 판단)

왜 LLM 전에 먼저 처리하나

  • LLM 응답을 기다리는 1~수 초 동안 다른 에이전트가 같은 좌석을 시도하면 충돌(409) 발생
  • "LLM이 판단할 만한 것"과 "결정론으로 즉시 처리할 것"을 분리
  • 지연을 최소화해 이선좌 사고 방지

스웜 내 동시 챌린지 풀이 제한

문제

상황위험
한 스웜 안의 여러 에이전트가 같은 시간대에 챌린지를 풀면"비정상적으로 동기화된 풀이 패턴"으로 보일 수 있음

해결 — 세마포어 기반 직렬화

매개변수기본값의미
vqa-concurrency1스웜 내 동시 챌린지 풀이 가능 에이전트 수
vqa-start-jitter-ms0에이전트별 시작 시각 결정론적 jitter

동시 풀이 수가 에이전트 수를 초과하지 않도록 런타임에서 자동 보정됩니다.

참조