본문으로 건너뛰기

© 2026 Molayo

GitHub요약2026. 05. 29. 05:58

GoogleCloudPlatform/race-condition

요약

Google Cloud Next '26 키노트에서 선보인 멀티 에이전트 마라톤 시뮬레이션의 오픈 소스 참조 아키텍처입니다. Gemini와 Google ADK를 활용하여 에이전트 간 통신, 결정론적 러너, 백엔드 주도 UI(A2UI) 등 복잡한 멀티 에이전트 시스템 구현 패턴을 제공합니다.

핵심 포인트

  • A2A 프로토콜 기반의 멀티 에이전트 통신 구조
  • 비용 절감 및 테스트를 위한 캐시된 재생(Cached Replay) 패턴
  • LLM 호출 없이 부하를 측정하는 결정론적 러너 구현
  • 에이전트가 UI 요소를 직접 전송하는 Backend-driven UI 방식

Google ADK와 Gemini로 구축된 멀티 에이전트 (multi-agent) 마라톤 시뮬레이션입니다. AI 에이전트들은 라스베이거스를 통과하는 마라톤 경로를 계획하고, 주변 환경(날씨, 교통, 인파)을 시뮬레이션하며, 자율적으로 경주를 수행합니다. 모든 통신은 A2A 프로토콜을 통해 이루어집니다.

본래 Google Cloud Next '26 개발자 키노트(Developer Keynote)에서 데모되었습니다.

이 프로젝트는 Google Cloud Next '26 개발자 키노트에서 실행했던 멀티 에이전트 시뮬레이션의 오픈 소스 버전입니다. 또한, 개별적으로 연구하기 어려운 몇 가지 패턴에 대한 작동 가능한 참조 아키텍처 (reference architecture)이기도 합니다:

캐시된 재생 vs 라이브 재생 (Cached vs live replay). 프론트엔드는 실제 에이전트 실행에서 기록된 NDJSON 스트림을 재생할 수 있으며, 이는 라이브 세션과 구별할 수 없습니다. 저희는 키노트의 안정성을 위해 이를 사용했습니다. 여러분은 이를 데모, UI 변경 사항 테스트, 또는 LLM 호출 비용을 지불하지 않고 교육하는 용도로 사용할 수 있습니다.

결정론적 러너 변체 (A deterministic runner variant). runner_autopilot은 실제 LLM 기반 러너와 동일한 형태의 결정을 내리지만, API 호출은 전혀 발생하지 않습니다. 실험 비용이 과도하게 발생하는 것을 방지하면서 부하 상황에서의 시뮬레이터를 측정하고자 할 때 적합한 베이스라인입니다.

플래너 사다리 (A planner ladder). 세 가지 플래너 변체(planner, planner_with_eval, planner_with_memory)는 각 계층이 실제로 무엇을 추가하는지(평가 게이팅 (eval gating), AlloyDB의 지속성 메모리 (persistent memory))를 기능 플래그 (feature flags)가 아닌 별개의 에이전트로 보여줍니다.

허브 세션 패턴 (The Hub session pattern). Go 게이트웨이가 WebSocket 트래픽을 A2A를 통해 Python ADK 에이전트와 주고받도록 라우팅하며, 수백 명의 러너가 동일한 틱 (tick)에 방송할 때 시스템이 자기 자신에게 천둥 치는 말 떼 현상 (thundering-herding)을 일으키지 않도록 배치 (batching) 처리를 수행합니다.

A2UI를 통한 백엔드 주도 UI (Backend-driven UI via A2UI). 프론트엔드가 응답 형태별로 레이아웃을 하드코딩하는 대신, 에이전트가 UI 프리미티브 (UI primitives: 카드, 경로 목록, 액션 버튼 등)를 네트워크를 통해 전송합니다.

README와 저장소 내의 에이전트 기술 (agent skills)은 전체를 실행하지 않고도 이 중 어떤 스레드라도 개별적으로 가져와 사용할 수 있도록 구성되어 있습니다.

무대에서 보셨던 몇 가지 사항은 이 저장소에 포함되어 있지 않으며, 이는 의도된 사항입니다:

  • 일부 데모는 아직 프라이빗 프리뷰 (private preview) 상태인 제품을 사용했습니다. 프리뷰 리스트에서만 실행 가능한 코드를 배포하는 대신, 해당 경로를 제외했습니다.
  • 일부 리소스(프로덕션 규모의 상시 가동 Memorystore, GKE 오토스케일링 (autoscaling))는 데모용으로 사용하기에 비용이 과도하게 발생합니다. 기본 배포 설정은 실행 사이에 컴퓨팅 자원을 0으로 스케일링 (scale to zero)합니다.
  • 코드 내의 일부 선택 사항은 키노트 일정(keynote schedule)을 반영합니다. 즉, 보통 몇 주가 걸릴 작업에 대해 며칠 단위의 마감 기한이 설정된 상황입니다. 이러한 한계는 실재합니다. 다른 선택 사항들은 이상해 보일 수 있으나 의도된 것입니다. 캐시 재생 (cached-replay) 모드가 가장 대표적인 예입니다. 어떤 것이 의도된 것인지 확실하지 않다면, 에이전트 스킬 (exploring-thecodebase)이 설계 결정 사항을 설명해 줍니다.

해당 제품들이 퍼블릭 프리뷰 (public preview)로 전환됨에 따라 프리뷰 제한 기능들을 다시 포함할 예정입니다.

마라톤의 형식을 빌린 Google Cloud 기반의 멀티 에이전트 시스템 (multi-agent system)입니다. 에이전트들은 다음과 같이 업무를 분담합니다:

  • 플래너 (Planner): Google Maps 데이터, GIS 도구, 그리고 약간의 금융 모델링을 사용하여 경주 코스를 설계합니다.
  • 시뮬레이터 (Simulator): 날씨, 교통, 인파, 경주 진행 상황 등 환경을 틱 단위 (tick by tick)로 실행합니다.
  • 러너 에이전트 (Runner agents, NPC): 경주가 진행됨에 따라 각자 페이스 조절, 수분 보충, 전략을 결정합니다.

이들은 에이전트 간 (Agent-to-Agent, A2A) 프로토콜을 통해 협업합니다. 중앙에는 Go 게이트웨이가 위치하여 3D Angular/Three.js 프론트엔드와 Python 에이전트 사이의 웹소켓 (WebSocket) 트래픽을 라우팅합니다.

로컬 환경에서는 Docker Compose (Redis, Pub/Sub 에뮬레이터, PostgreSQL)로 실행됩니다. 클라우드 환경에서는 Cloud Run 및 Vertex AI Agent Engine에 배포됩니다.

Race Condition을 실행하는 가장 빠른 방법은 AI 코딩 어시스턴트에게 요청하는 것입니다. 저장소 루트에는 최신 AI 개발 도구가 진입 시 읽을 수 있는 AGENTS.md 파일이 포함되어 있으며, .claude/skills/ 아래에 4개의 상세 스킬 파일이 있습니다.

스킬은 자동으로 탐색됩니다. 저장소를 열고 다음과 같이 질문하세요:

cd race-condition
claude
> Set up this project and get the simulation running

Claude는 스스로 getting-started 스킬을 로드할 것입니다.

이 도구들은 AGENTS.md를 읽습니다.

자동으로 로드하지만 스킬 파일들을 자동으로 탐색(auto-discover)하지는 않습니다. 어시스턴트에게 관련 스킬을 명시적으로 지정해 주세요:

cd race-condition
gemini # 또는 opencode, 또는 Cursor / VS Code에서 폴더 열기
> Read .claude/skills/getting-started/SKILL.md and walk me through it

다른 작업에 대해서도 동일한 패턴을 사용합니다. 상황에 맞는 스킬로 교체하세요:

작업지정할 스킬
최초 로컬 설정.claude/skills/getting-started/SKILL.md
...

스킬 파일은 YAML 프론트매터 (YAML frontmatter)가 포함된 일반 마크다운 (Markdown) 형식입니다. 어시스턴트가 GCP 인증, API 활성화, 종속성 설치(dependency installation), 그리고 시뮬레이션 시작 과정을 안내할 것입니다. 일부 단계(예: gcloud auth login)는 브라우저에서 직접 수행해야 하며, 어시스턴트가 해당 시점을 알려줄 것입니다.

수동으로 설정할 수도 있습니다. 아래의 Quickstart 섹션을 참조하세요.

graph TD
Frontend["Frontend<br/>Angular + Three.js"]
Gateway["Gateway<br/>Go · WebSocket · Gin"]
...
컴포넌트역할
Gateway중앙 WebSocket 허브 (Go/Gin). 요청을 라우팅하고, 세션을 관리하며, A2A를 통해 프론트엔드와 에이전트(agents)를 연결합니다.
...

이 내용에 대한 심층적인 버전은 docs/를 참조하세요. — architecture 서브트리(subtree)에서 토폴로지(topology), 프로토콜(protocols), 그리고 설계 결정(design decisions)에 대해 자세히 설명합니다.

시작하기 전에 다음 도구들을 설치하세요. make check-prereqs를 실행하면 이를 검증해 줍니다.

도구버전용도설치
Go1.25+Gateway, admin, 그리고 프론트엔드 BFF 서버go.dev/dl
...cloud.google.com/sdk

컴퓨팅은 기본적으로 제로 스케일링(scales to zero)이 적용되므로 (min_instances=0, max_instances=1), 무언가가 실행 중일 때만 비용이 발생합니다. 피할 수 없는 고정 비용은 Memorystore Redis, Cloud SQL, 그리고 Cloud NAT를 위해 월 약 $91 정도입니다. 각 시뮬레이션 실행 시 Gemini API 호출 비용은 대략 $3-4 정도입니다. API 크레딧을 소모하지 않고 개발하고 싶다면 runner_autopilot 변형을 사용하세요. 이는 결정론적(deterministic)이며 LLM 호출을 전혀 하지 않습니다.

배포 진입점 (scripts/deploy.shmake deploy

)는 동일한 분석 내용을 출력하며, 무언가를 프로비저닝(provision)하기 전에 확인을 기다립니다. 확인을 완료하면, 프로젝트의 사전 점검(pre-flight)을 수행하며(Cloud Build에 필요한 API를 활성화하고 Cloud Build 기본 서비스 계정(SA)에 Terraform을 실행할 수 있는 IAM 역할(roles)을 부여합니다. 이 과정은 다시 실행해도 안전합니다), 그 다음 빌드를 제출합니다.

cd infra && terraform destroy 명령어로 정리(Tear down)할 수 있습니다. 서비스의 상태를 따뜻하게(warm) 유지하고 콜드 스타트(cold start)를 건너뛰고 싶다면, infra/terraform.tfvars 파일 내의 service_sizing 맵(map)에서 원하는 서비스의 min_instances 값을 높인 후 다시 적용(re-apply)하세요.

결제(billing)가 활성화되어 있고 사용자가 소유자(Owner)이거나 최소한 roles/aiplatform.user 권한을 가진 GCP 프로젝트가 필요합니다. 프로젝트를 방금 생성했다면 이미 소유자(Owner) 상태일 것입니다.

# 로그인 및 애플리케이션 기본 자격 증명(Application Default Credentials)을 한 번에 작성
gcloud auth login --update-adc
# 프로젝트 설정 (아래 모든 곳의 MY_PROJECT_ID를 교체하세요)
...

참고: API 활성화가 전파되는 데 1~2분 정도 걸릴 수 있습니다. 처음 시작할 때 403 에러가 발생하면, 1분 정도 기다린 후 make restart를 실행하세요.

git clone https://github.com/GoogleCloudPlatform/race-condition.git
cd race-condition
# 모든 항목 설치 및 빌드 (선행 요구 사항 확인, .env 생성, 의존성 설치)
...

sed 명령어가 .env 파일 내의 GOOGLE_CLOUD_PROJECTPROJECT_ID를 설정합니다. 에이전트(agents)들은 gcloud config가 아닌 이 파일로부터 프로젝트 정보를 읽어옵니다.

make start 명령어를 실행하면 프론트엔드는 http://localhost:9119에서 열립니다. 관리자 대시보드는 http://localhost:9100에서 서비스 상태를 보여줍니다.

  • Go, Python, uv, Node.js, Docker가 설치되어 있는지 확인합니다.

  • .env.example.env로 복사합니다 (.env 파일이 존재하지 않는 경우).

  • uv sync로 Python 의존성을 설치합니다.

  • 프론트엔드 및 웹 UI를 설치하고 빌드합니다.

  • Docker 인프라(Redis, Pub/Sub 에뮬레이터, PostgreSQL)를 시작합니다.

  • Go 서비스들을 빌드합니다.

  • .env 파일이 존재하는지, 이미 실행 중인 서비스가 없는지 확인합니다.

  • Docker 인프라를 시작합니다.

  • 필요한 모든 포트가 비어 있는지 확인합니다.

  • Honcho를 통해 모든 서비스(13개 프로세스)를 실행합니다.

  • 출력을 logs/simulation.log에 기록합니다.

모든 것을 종료하려면 make stop을 사용하거나, 재시작하려면 make restart를 사용하세요.

프론트엔드는 Cached (캐시됨) 모드로 부팅됩니다. 이는 의도된 설계입니다. 수천 명의 관중 앞에서 발표할 때 네트워크가 한 번 끊긴다고 가정해 보십시오. 라이브 LLM (Large Language Model) 호출이 깔끔한 데모와 길고 어색한 침묵 사이의 차이를 만드는 상황은 피하고 싶을 것입니다. Cached 모드는 실제 실행에서 기록된 NDJSON 스트림을 재생하므로, 타이밍과 에이전트(Agent) 출력은 실제와 동일하지만 네트워크에 의존하지 않습니다.

Live (라이브) 모드는 WebSockets를 통해 에이전트와 통신하며 실제로 에이전트를 실행합니다.

Ctrl+L로 두 모드 사이를 전환하거나, 채팅 패널의 Settings (설정) 드롭다운에 있는 세그먼트 컨트롤을 사용하세요. 모드가 변경되면 모서리에 작은 표시기가 깜빡입니다.

시뮬레이션에는 9개의 데모가 포함되어 있습니다. 각 데모는 활성 에이전트, 캐시된 녹화본, 그리고 몇 가지 UI 기본 설정을 구성합니다. Ctrl+<key>를 사용하여 데모를 전환하세요:

단축키데모내용
Ctrl+0Sandbox (샌드박스)고정된 인트로 샷과 미리 로드된 마라톤 계획. Ctrl+I를 눌러 카메라를 해제하세요.
Ctrl+1Agent Platform으로 에이전트 구축스스로 작동하는 기본 플래너 (Planner).
Ctrl+2멀티 에이전트 시스템 생성eval (LLM-as-Judge) 기능이 포함된 플래너.
Ctrl+3메모리로 에이전트 강화AlloyDB 경로 메모리(route memory)를 지원하는 플래너.
Ctrl+4대규모 디버깅의도적인 결함 주입(fault injection)이 포함된 시뮬레이터.
Ctrl+5 / Ctrl+Shift+5Cloud Assist를 통한 의도에서 인프라로의 전환기본 버전 및 업그레이드된 변형 버전.
Ctrl+7 / Ctrl+Shift+7에이전트 보안보안되지 않은 버전 및 보안된 변형 버전.

Ctrl+R은 현재 데모를 초기화합니다. 동일한 데모의 단축키를 두 번 눌러도 동일한 동작을 수행합니다.

Ctrl+A, Ctrl+S, Ctrl+D는 카메라 A, B, C 사이를 전환합니다. 주의사항: Ctrl+D는 단축키 충돌로 인해 분리하지 못한 대체 사이드 패널(side panels)도 함께 전환합니다. 패치(Patches)는 언제나 환영합니다.

Ctrl+I는 고정된 카메라 인트로를 재생합니다 (Sandbox에서 사용됨). Ctrl+Shift+I는 이를 건너뜁니다.

Sandbox는 놀이터입니다. planner_with_memory를 로드합니다.

그리고 페이지가 준비되는 즉시 Organizer의 "top 3 routes" 패널을 보여줍니다. 캐시 모드(cached mode)에서는 Show Route를 클릭하여 미리 볼 수 있는 세 개의 사전 기록된 경로를 제공합니다. Live 모드로 전환하면 동일한 패널이 새로운 planner_with_memory 에이전트에게 list the top 3 best routes 명령을 전송하며 — 해당 에이전트가 무엇을 반환하기로 결정하든 그것이 화면에 표시됩니다.

전체 시뮬레이션을 실행하지 않고 메모리 에이전트(memory agent)를 즉석에서 테스트해 보고 싶다면, 이곳이 바로 그 작업을 수행할 장소입니다.

Planner 에이전트는 Google Maps MCP 도구들(search_places, compute_routes, lookup_weather)을 사용하여 지리적으로 정확한 마라톤 경로를 설계할 수 있습니다. 이를 위해서는 Google Maps API 키가 필요합니다. 키가 없어도 Planner는 작동하지만, 실시간 지도 데이터 없이 경로를 계획합니다.

키를 생성하기 전에 다음 API들을 활성화하십시오. 콘솔의 키 제한(key restriction) 드롭다운 메뉴에는 이미 활성화된 API만 표시됩니다.

gcloud services enable apikeys.googleapis.com # API 키 관리
gcloud services enable agentregistry.googleapis.com # ADK가 여기서 Maps MCP 서버를 발견합니다
gcloud services enable mapstools.googleapis.com # Maps MCP 서버
...

참고: API 활성화가 전파되는 데 1~2분 정도 걸릴 수 있습니다. 키를 생성하기 전에 몇 분간 기다려 주십시오.

  • Google Cloud Console에서 Credentials(자격 증명) 페이지를 엽니다.

  • Create credentials(자격 증명 만들기) > API key(API 키)를 클릭합니다. - 키 값을 복사합니다 (3단계에서 필요합니다).

  • Edit API key(API 키 편집)를 클릭합니다 (또는 목록에서 키 이름을 클릭합니다). - API restrictions(API 제한사항) 항목 아래에서 Restrict key(키 제한)를 선택합니다. - 드롭다운에서 다음 API들을 선택합니다 (필터 상자를 사용하여 찾으십시오):

    • Cloud API Registry API
    • Maps Grounding Lite API
    • Places API (New)
    • Weather API
  • Save(저장)를 클릭합니다.

GOOGLE_MAPS_API_KEY=AIza...your-key-here

그런 다음 시뮬레이션을 재시작합니다 (make restart).

Planner는 다음 순서로 키를 확인합니다:

  1. GOOGLE_MAPS_API_KEY 환경 변수 (설정되어 있고 비어 있지 않은 경우)
  2. Google Cloud Secret Manager: gcloud secrets versions access latest --secret=maps-api-key --project=$GOOGLE_CLOUD_PROJECT

. 둘 다 사용할 수 없는 경우, Maps 도구는 비활성화되며 플래너 (planner)는 경고를 로그에 기록합니다.

race-condition/
├── agents/ # Python AI 에이전트 (Google ADK)
│ ├── planner/ # GIS + Maps MCP를 사용한 경로 계획 (Route planning)
...

에이전트들은 /.well-known/agent-card.json에서 제공되는 에이전트 카드 (agent cards)를 통해 서로를 발견합니다.

게이트웨이 (gateway)는 시작 시 이 카드들을 가져오며, 선언된 기술 (skills)을 기반으로 메시지를 적절한 에이전트에게 라우팅 (routing)합니다.

시뮬레이터는 SequentialAgent 파이프라인을 실행합니다:

graph LR
PreRace["Pre-race<br/>계획 파싱, 러너 생성"] --> RaceEngine["Race engine<br/>LoopAgent, 최대 200 틱 (ticks)"]
RaceEngine --> PostRace["Post-race<br/>결과 컴파일"]

AI 자동 생성 콘텐츠

본 콘텐츠는 GitHub AI Tools의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0