OpenOrchestrator 시리즈 6편 | 2026.04
>
이 글을 읽으면 세 가지를 알게 됩니다:
- 스마트폰에서 프로젝트를 기획하고, PC가 자동으로 개발을 시작하는 워크플로우
- 기존 인프라 자산(HTTPS, 프로세스 관리, 스케줄러)을 재사용해서 새 프로젝트를 빠르게 띄우는 방법
- 던전 탐험 AI Agent 시뮬레이터의 아키텍처와 핵심 코드
5편에서 이어지는 이야기
지난 5편에서 Circuit Breaker — AI Agent가 같은 실수를 반복하지 않도록 자동으로 멈추는 보호장치 — 를 다뤘습니다. 3회 연속 실패 시 차단, 쿨다운 후 자동 복구, 13개 Agent를 프로젝트 단위로 격리하는 구조였죠.
글 끝에 이렇게 예고했습니다.
"다음 편에서는 AWS AI League 대회 준비를 위해 새 프로젝트를 스마트폰 기획부터 자동 개발까지 OO 생태계로 띄운 이야기를 다룹니다."
Circuit Breaker는 "실패했을 때 어떻게 보호할 것인가"에 대한 답이었습니다. 이번 편은 그 반대 방향입니다. "새로운 것을 얼마나 빠르게 시작할 수 있는가."
보호장치가 갖춰진 생태계 위에서, 진짜로 새 프로젝트를 하나 띄워보겠습니다. 사이드 프로젝트가 아니라, AWS 공식 대회에 출전할 실서비스입니다.
"대회 나가볼까?" — 스마트폰에서 시작된 프로젝트
4월의 어느 날, AWS Summit Seoul 2026 AI League 소식을 봤습니다.
대회 내용은 이렇습니다: 그리드(격자) 던전을 탐험하는 AI Agent를 만들어라. 코인을 줍고, 함정을 피하고, 출구를 찾는 Agent를 설계하는 겁니다. 우승하면 re:Invent 2026(라스베이거스에서 열리는 AWS 연례 기술 행사) 전액 지원 — 꽤 매력적인 상금이죠.
문제는 시간입니다. 대회일은 5월 21일, 남은 시간은 약 5주. 그런데 이미 12개 프로젝트를 운영하고 있는 상황에서, 하나를 더 시작할 여유가 있을까요?
답은 "여유는 없지만, 인프라는 있다"였습니다.
이전 편들을 읽으셨다면 감이 오실 겁니다. Non-blocking HitL(1편), Autonomy Slider(3편), Wave Orchestration(4편), Circuit Breaker(5편) — 이 모든 것이 쌓여서, 새 프로젝트의 부트스트랩 비용이 급격히 줄어든 상태입니다.
Step 1: 스마트폰에서 기획 → 태스크 등록
출퇴근 지하철에서 claude.ai 모바일 앱을 열었습니다. 프로젝트 기획을 대화로 진행합니다.
나: AI League 대회에 나가려고 해. 던전 탐험 AI Agent를 만들어야 하는데,
어떤 구조로 시작하면 좋을까?
Claude: 두 가지 Phase를 제안합니다.
Phase 1 — 범용 던전 시뮬레이터: 대회 규칙이 아직 미확정이니까,
일반적인 그리드 탐험 환경을 먼저 만들고 Agent 설계 패턴을 연습합니다.
Phase 2 — 사전자료 수신 후 실제 규칙을 반영하고 Bedrock 특화 튜닝.
나: 좋아. 기술 스택은?
Claude: 서버 FastAPI + 프론트 React(CDN, 빌드 불필요) + AI Bedrock Claude.
기존 프로젝트의 Tailscale HTTPS 패턴을 재사용하면
서버 설정 시간을 크게 줄일 수 있습니다.
기획이 끝나면 OO 생태계의 MCP Gateway(원격 제어 게이트웨이)를 통해 태스크를 등록합니다. 스마트폰에서 보낸 요청이 집에 있는 PC의 OpenOrchestrator(이하 OO)에 도착합니다.
{
"type": "capture_request",
"target": "ai-league",
"summary": "던전 Agent 시뮬레이터 프로젝트 부트스트랩",
"priority": "high",
"dispatch_reason": "AWS AI League 대회 준비"
}
OO는 이 요청을 받아서 Work Packet(작업 문서)으로 변환하고, Claude Code CLI(로컬 PC에서 터미널로 동작하는 AI 개발 도구)가 자동으로 작업을 시작합니다.
지하철에서 기획하고, 집에 도착하면 코드가 이미 돌아가고 있습니다.
Step 2: "이미 있나?" — 기존 자산 재사용
새 프로젝트를 시작할 때 가장 중요한 질문은 "이미 있나?"입니다. 처음부터 다 만들 필요 없이, 기존에 만들어둔 것을 가져다 쓰면 됩니다.
ai-league에서 재사용한 기존 자산을 정리하면:
| 필요한 것 | 이미 있는 자산 | 출처 |
|---|---|---|
| HTTPS 인증서 | Tailscale MagicDNS 인증서 | 기존 프로젝트 |
| 프로세스 관리 (시작/종료/PID) | DETACHED_PROCESS 런처 패턴 | 기존 프로젝트의 run.py |
| PC 재부팅 후 자동 시작 | Windows Task Scheduler 등록 스크립트 | OO 생태계 공통 패턴 |
| 프로젝트 뼈대 (문서, 규칙) | CLAUDE.md + WBS 템플릿 | OO vibe-coding 템플릿 |
| 원격 접속 (VPN) | Tailscale 네트워크 | 이미 설정됨 |
이전에 만든 프로젝트에서 이미 "FastAPI + Tailscale HTTPS + 프로세스 관리" 패턴을 완성해뒀습니다. ai-league는 이 패턴을 그대로 복사해서 씁니다.
실제 코드를 보면 얼마나 비슷한지 알 수 있습니다:
# ai-league/run.py — 서버 실행 스크립트 (61줄)
PROJECT_DIR = Path(__file__).parent
CERT_FILE = PROJECT_DIR / "desktop-xxxxx.tail-xxxx.ts.net.crt"
KEY_FILE = PROJECT_DIR / "desktop-xxxxx.tail-xxxx.ts.net.key"
PID_FILE = PROJECT_DIR / "server.pid"
PORT = 8077
def main():
# 인증서 존재 확인
if not CERT_FILE.exists():
print("ERROR: TLS certs not found.")
sys.exit(1)
# 가상환경의 Python으로 서버 실행
venv_python = PROJECT_DIR / ".venv" / "Scripts" / "python.exe"
cmd = [
str(venv_python), "-m", "uvicorn",
"src.server:app",
"--host", "0.0.0.0",
"--port", str(PORT),
"--ssl-certfile", str(CERT_FILE),
"--ssl-keyfile", str(KEY_FILE),
]
# 백그라운드 프로세스로 실행 + PID 파일 기록
proc = subprocess.Popen(
cmd,
creationflags=0x00000008, # DETACHED_PROCESS
)
PID_FILE.write_text(str(proc.pid))
이 패턴의 핵심은 세 가지입니다:
- Tailscale HTTPS: 별도의 도메인/인증서 구매 없이
desktop-xxxxx.tail-xxxx.ts.net도메인과 자동 발급 인증서로 HTTPS 서빙 - DETACHED_PROCESS: 터미널을 닫아도 서버가 계속 실행됨
- PID 파일: 프로세스 ID를 기록해서 나중에 깔끔하게 종료 가능
기존 프로젝트에서 이 패턴을 이미 디버깅하고 안정화해뒀기 때문에, ai-league에서는 포트 번호만 바꾸면 됩니다.
Step 3: 핵심 개발 — 게임 엔진 + Agent + UI
기존 자산 위에 새로 개발한 코드는 크게 세 부분입니다.
3-1. 던전 게임 엔진 (engine.py, 291줄)
게임 엔진의 핵심은 그리드 생성과 이동 처리입니다.
# src/engine.py — 던전 생성 핵심 로직
class DungeonEngine:
CELL_VALUES = {
CellType.COIN: 10, # 코인: +10점
CellType.TREASURE: 50, # 보물: +50점
CellType.TRAP: -20, # 함정: -20점 + HP 데미지
}
def new_game(self, seed=None):
# seed를 고정하면 매번 같은 던전이 생성됨
# → A/B 테스트에서 두 Agent를 동일 조건으로 비교 가능
actual_seed = seed if seed is not None else random.randint(0, 2**31)
rng = random.Random(actual_seed)
# 그리드 생성: 빈 칸 → 벽 배치 → 코인 배치 → 보물 배치 → 함정 배치
grid = [[Cell() for _ in range(w)] for _ in range(h)]
wall_count = int(w * h * self.config.wall_density)
# 시작점(0,0)과 출구(w-1,h-1)는 벽 배치 대상에서 제외
empties = [
(x, y) for y in range(h) for x in range(w)
if not (x == 0 and y == 0)
and not (x == w - 1 and y == h - 1)
]
rng.shuffle(empties)
seed 매개변수가 핵심 설계입니다. 같은 seed를 넣으면 벽, 코인, 함정의 위치가 완전히 동일한 던전이 생성됩니다. 이것 덕분에 A/B 테스트 — 두 Agent를 동일한 맵에서 실행해서 성적을 비교하는 — 가 가능합니다.
3-2. Agent 시스템 (agent.py, 256줄)
Agent는 규칙 기반(RuleBasedAgent)과 LLM 기반(LLMAgent) 두 종류입니다.
# src/agent.py — Agent 인터페이스
class BaseAgent(ABC):
def __init__(self, name: str, prompt: str = ""):
self.name = name
self.prompt = prompt
self.decision_log: list[dict] = [] # 매 턴 판단 이유 기록
@abstractmethod
def decide(self, observation: dict) -> Direction:
"""관찰 결과를 받아서 다음 이동 방향을 결정"""
class RuleBasedAgent(BaseAgent):
STRATEGIES = {
"explorer": "미방문 셀 우선, 함정 회피, 근처 아이템 수집",
"greedy": "가장 가까운 코인/보물로 돌진, 위험 감수",
"cautious": "함정 철저 회피, 안전한 경로만 선택",
"speedrun": "아이템 무시, 출구로 최단 경로",
}
4가지 전략은 Agent 설계의 기초 벤치마크 역할을 합니다. LLM Agent를 만들기 전에, 단순한 규칙만으로 어느 정도 점수가 나오는지 기준선을 잡는 거죠.
Agent가 받는 관찰 데이터(observation)는 이런 형태입니다:
{
"position": {"x": 3, "y": 5},
"score": 60,
"hp": 80,
"turns_used": 12,
"turns_remaining": 88,
"visible_cells": [
{"x": 2, "y": 5, "type": "coin", "visited": false},
{"x": 4, "y": 5, "type": "wall", "visited": false},
{"x": 3, "y": 4, "type": "trap", "visited": false}
],
"grid_size": {"width": 10, "height": 10}
}
Agent는 전체 맵을 볼 수 없습니다. 안개(Fog of War)가 있어서, 현재 위치 근처의 셀만 보입니다. 이 안개 반경은 맨해튼 거리(Manhattan Distance — 상하좌우 이동 횟수로 계산하는 거리)로 결정됩니다.
# 안개 업데이트 — 맨해튼 거리 기반 가시 범위
def _update_visibility(self):
px, py = self.state.player.position
for dy in range(-fog_radius, fog_radius + 1):
for dx in range(-fog_radius, fog_radius + 1):
nx, ny = px + dx, py + dy
if abs(dx) + abs(dy) <= fog_radius: # 맨해튼 거리
self.state.grid[ny][nx].visible = True
3-3. React UI (index.html, 411줄)
UI는 React 18을 CDN으로 불러와서 빌드 과정 없이 바로 실행됩니다. Node.js 설치도, npm install도 필요 없습니다.
┌──────────────────────────────────────┐
│ AI League Dungeon Simulator │
│ │
│ Score: 60 HP: 80 Turn: 12/100 │
│ │
│ ## ## ## ## ## ## ## │
│ ## . $ . . ## ## │
│ ## . @ ! . . ## │
│ ## . . * ## . ## │
│ ## ## . . . E ## │
│ ## ## ## ## ## ## ## │
│ │
│ [W] Decision Log: │
│ [A][S][D] Turn 12: 함정 회피 → │
│ 왼쪽 코인으로 이동 │
│ │
│ [Play] [Agent] [A/B Test] │
└──────────────────────────────────────┘
@ = 플레이어 $ = 코인 * = 보물
! = 함정 E = 출구 # = 벽
UI는 세 가지 모드를 지원합니다:
- Play: 직접 키보드(WASD)로 조작하며 던전 탐험
- Agent: 4가지 전략 중 하나를 골라 AI가 자동 플레이
- A/B Test: 두 전략을 같은 맵에서 실행하고 결과 비교
Step 4: 서버 기동 → 스마트폰 접속
개발이 끝나면 서버를 띄우고, Tailscale 네트워크를 통해 스마트폰에서 바로 접속합니다.
# 서버 실행
python run.py
# → Starting AI League server on
# https://desktop-xxxxx.tail-xxxx.ts.net:8077/
# → Server started PID=39656
Tailscale은 개인 VPN(가상 사설 네트워크)입니다. 같은 Tailscale 계정에 연결된 기기들은 인터넷 어디서든 서로 접속할 수 있습니다. 포트 포워딩이나 공유기 설정이 필요 없습니다.
스마트폰에서 https://desktop-xxxxx.tail-xxxx.ts.net:8077/을 열면, 집 PC에서 돌아가는 던전 시뮬레이터가 바로 뜹니다. 터치로 Agent를 실행하고, A/B 테스트 결과를 확인하고, Decision Log(Agent가 매 턴 왜 그 방향으로 갔는지 기록)를 보면서 전략을 개선할 수 있습니다.
Windows Task Scheduler(윈도우 예약 작업)에 등록해두면 PC를 재부팅해도 자동으로 서버가 시작됩니다:
# register-task.ps1 — 시스템 로그온 시 자동 시작
New-ScheduledTask -Name "OO-AILeague" `
-Trigger (New-ScheduledTaskTrigger -AtLogon) `
-Action (New-ScheduledTaskAction `
-Program "python" `
-Arguments "run.py" `
-WorkingDirectory "C:\Dev\ai-league")
전체 아키텍처
완성된 시스템의 전체 구조를 정리하면:
스마트폰 (claude.ai 앱)
│
│ 1. 기획 + 태스크 등록
↓
OpenOrchestrator (PC)
│
│ 2. Work Packet 생성 → Claude Code CLI 자동 개발
↓
ai-league 프로젝트 (PC)
├── src/engine.py ← 던전 게임 엔진
├── src/agent.py ← 규칙/LLM Agent
├── src/server.py ← FastAPI 9개 엔드포인트
├── src/db.py ← SQLite 게임 기록
├── static/index.html ← React UI
└── run.py ← HTTPS 서버 런처
│
│ 3. Tailscale HTTPS
↓
스마트폰 (브라우저)
└── 던전 시뮬레이터 접속 → Agent 훈련
숫자로 보는 결과 (Phase 1 완료 시점, 2026-04-17)
| 항목 | 수치 |
|---|---|
| 총 코드량 | 1,326줄 (Python 944 + HTML/JSX 382) |
| Python 모듈 | 6개 (engine, agent, server, db, models, main) |
| API 엔드포인트 | 9개 |
| Agent 전략 | 4개 규칙 기반 + 1개 LLM |
| DB 테이블 | 2개 (games, ab_tests) |
| React 컴포넌트 | CDN 직접 로드 (빌드 도구 없이) |
| Git 커밋 | 4개 (scaffold → full-stack → UI → infra) |
| 재사용한 기존 패턴 | 5개 (HTTPS, PID, Scheduler, 템플릿, VPN) |
핵심 교훈: 인프라가 쌓이면 속도가 바뀐다
이 프로젝트에서 가장 인상적인 부분은 새로 만든 게 생각보다 적다는 점입니다.
HTTPS? 이미 있습니다. 프로세스 관리? 이미 있습니다. 프로젝트 뼈대? 이미 있습니다. 원격 접속? 이미 있습니다.
새로 만든 것은 도메인 로직(게임 엔진, Agent, API, UI)뿐입니다. 그리고 이 도메인 로직도 Claude Code CLI가 WBS(작업 목록)를 보고 자동으로 구현했습니다.
| 작업 | 사람이 한 것 | 시스템이 한 것 |
|---|---|---|
| 기획/요구사항 | claude.ai 대화 (~15분) | 요구사항 구조화 |
| 태스크 등록 | MCP 요청 1건 (~1분) | WP 생성 + dispatch |
| 코드 개발 | 없음 | 7개 모듈 1,478줄 자동 생성 |
| 서버 기동 | 없음 | HTTPS + PID + Scheduler 자동 |
| 테스트/검증 | 스마트폰 접속 확인 (~5분) | health check |
프로젝트를 12개, 13개, 14개... 이렇게 늘려가면서 느낀 건, 처음 3~4개 프로젝트는 느립니다. HTTPS 패턴, 프로세스 관리, CI/CD 등 인프라를 하나씩 만들어야 하니까요.
하지만 5번째부터는 속도가 확 바뀝니다. "이미 있는" 자산이 쌓이면서, 새 프로젝트의 부트스트랩 비용이 급격히 줄어듭니다. 10번째쯤 되면 사람이 할 일은 "무엇을 만들지" 결정하는 것뿐이 됩니다. "어떻게 만들지"는 시스템이 알아서 합니다.
이 사례가 시사하는 것: 실험 도구가 아니라 서비스 부트스트랩 엔진
AI League 준비기를 단순히 "대회 준비 이야기"로만 보면 핵심을 놓칩니다.
이 사례가 증명하는 건 하나입니다: OO 생태계 위에서는 "아이디어 → 동작하는 서비스"까지의 거리가 극적으로 짧아진다.
생각해보세요. 이 프로젝트는:
- 지하철에서 15분 기획
- 태스크 등록 1분
- 코드 작성 0분 (시스템이 자동 생성)
- 검증 5분
합산 약 20분의 사람 시간으로, 1,478줄짜리 풀스택 서비스가 HTTPS까지 달고 돌아가기 시작했습니다. 이건 사이드 프로젝트의 속도가 아닙니다. 실서비스 부트스트랩의 속도입니다.
이 속도가 가능한 이유는 명확합니다:
- 재사용 가능한 인프라 패턴이 쌓여 있다 — HTTPS, 프로세스 관리, 스케줄러, 프로젝트 뼈대가 검증 완료 상태
- 자동화된 태스크 파이프라인이 있다 — 스마트폰에서 등록하면 PC의 Agent가 자동으로 개발 시작
- 보호장치가 이미 작동 중이다 — Circuit Breaker, Wave 게이트가 실패를 격리하므로, 새 프로젝트를 추가해도 기존 프로젝트에 영향 없음
Phase 1 이후: 계속 자라는 생태계
위 숫자는 Phase 1 완료 시점(2026-04-17) 기준입니다. 그 이후 Phase 2에서 Bedrock AgentCore Gateway 연동, 가드레일 모듈, 프롬프트 프로필 시스템 등이 추가되면서 현재는 13개 Python 모듈·2,700여 줄 규모로 확장됐습니다. 핵심 사실은 변하지 않습니다: 처음 부트스트랩은 20분 남짓의 사람 시간으로 끝났고, 이후 확장은 같은 파이프라인 위에서 계속 돌고 있습니다.
앞으로의 방향
현재 OO는 개인 개발 환경에서 운영되고 있습니다. 하지만 이 패턴 — "인프라 자산 축적 → 재사용 → 빠른 부트스트랩" — 은 개인에 국한될 이유가 없습니다.
구상 중인 방향은 이렇습니다:
- oo-starter 패키지화: 프로젝트 뼈대(CLAUDE.md, WBS 템플릿, 태스크 파이프라인)를 누구나 쓸 수 있는 스타터킷으로 정리. 현재는 내부 파일럿 단계이고, 준비가 되면 별도 채널로 안내할 예정입니다.
- 정식 배포: npm 패키지 또는 VS Code Extension 형태로, 외부 개발자도 설치 한 번으로 시작할 수 있는 도구를 지향합니다.
[oo-starter 레포 — 준비 중, 별도 안내 예정]
구체적인 일정을 말하기엔 이르지만, 방향은 분명합니다: OO가 증명한 "인프라가 쌓이면 속도가 바뀐다"는 원리를 더 많은 개발자가 경험할 수 있게 하는 것.
정리
핵심 세 줄입니다.
- "이미 있나?"가 가장 중요한 질문이다. 새 프로젝트를 시작할 때, 처음부터 만드는 것이 아니라 기존 자산을 먼저 찾아보세요. ai-league의 인프라 코드 중 80%는 기존 프로젝트에서 가져온 것입니다.
- 인프라가 쌓이면 속도가 바뀐다. 5번째 프로젝트부터는 부트스트랩 비용이 급격히 줄어듭니다. 10번째쯤 되면 사람이 할 일은 "무엇을 만들지" 결정하는 것뿐입니다.
- 이건 사이드 프로젝트가 아니라 진짜 서비스 부트스트랩의 증거다. 20분의 사람 시간으로 풀스택 서비스를 띄울 수 있다면, OO는 실험 인프라가 아니라 서비스를 빠르게 만드는 엔진입니다.
이 글은 OpenOrchestrator 생태계의 auto-shorts01 파이프라인과 Claude를 활용하여 작성되었습니다.
'AI > Vibe Coding' 카테고리의 다른 글
| 블로그 대표이미지 만드는 일을 Codex CLI에 맡긴 이야기 — fallback 사다리는 그대로 두고 (0) | 2026.05.11 |
|---|---|
| Tistory 글을 검색엔진에 자동으로 발견시키는 법 — GitHub Pages mirror와 IndexNow (0) | 2026.05.04 |
| Circuit Breaker: AI Agent가 실패를 감지하고 스스로 멈추는 방법 (0) | 2026.04.20 |
| Wave Orchestration: 퇴근 후 2시간에 53개 작업을 자동 처리한 방법 (1) | 2026.04.16 |
| Per-domain Autonomy Slider: Karpathy의 슬라이더를 실제로 구현하면 (2) | 2026.04.14 |