AgentManager: 대규모 자율 에이전트의 안전한 운영 및 오케스트레이션
요약
AgentManager는 Claude Code CLI를 기반으로 대규모 자율 에이전트를 안전하게 운영하고 오케스트레이션하기 위한 플랫폼입니다. 에이전트의 상태를 GCS에 동기화하여 서버 스케일링 시에도 세션을 유지하며, 비상 킬 스위치와 메모리 모니터링 등 강력한 가드레일을 통해 안정적인 실행 환경을 제공합니다.
핵심 포인트
- Claude Code의 실제 세션을 격리된 워크스페이스에서 실행하여 파일 편집, bash, git, MCP 등의 도구 권한을 부여함
- GCS를 활용한 상태 동기화로 Cloud Run의 scale-to-zero 환경에서도 에이전트 작업 재개 가능
- 6단계 비상 킬 스위치 및 cgroup v2 메모리 모니터링을 통한 안정적인 프로세스 관리
- 에이전트 간 메시지 버스를 통해 작업 위임, 결과 전달 및 인터럽트 처리 지원
- Claude Code의 stream-json 형식을 파싱하여 실시간 상태 추적 및 비용 계산 수행
대규모의 자율 에이전트 (autonomous agents)를 안전하게 운영하십시오. 당신은 리드하고, 에이전트가 실행합니다. Human-in-the-loop가 아닌, Human-on-the-loop 방식입니다. 프롬프트 저글러 (prompt juggler)가 아닌 관리자처럼 AI 업무를 오케스트레이션 (orchestrate) 하십시오.
AgentManager는 Claude Code CLI 프로세스를 실행합니다. 각 에이전트는 격리된 워크스페이스 (workspace)에서 실행되며, 전체 도구 액세스 권한(파일 편집, bash, git, MCP 통합)을 가진 실제 Claude Code 세션입니다. 이 플랫폼은 운영 측면을 담당합니다:
에이전트는 재시작 후에도 유지됩니다. 상태가 GCS (Google Cloud Storage)로 동기화됩니다. Cloud Run이 0으로 스케일 인 (scale to zero) 되어도, 에이전트는 깨어날 때 재개됩니다.
6단계 비상 킬 스위치 (emergency kill switch). 프로세스 종료 -> 토큰 순환 (token rotation) -> GCS 원격 종료. 제가 필요해서 직접 만들었습니다.
cgroup v2 메모리 모니터링. cgroup을 통해 컨테이너 메모리를 추적하며, 85% 도달 시 새로운 에이전트를 거부합니다. OOM (Out of Memory) 돌발 상황이 발생하지 않습니다.
프로세스 그룹 생명주기 관리 (Process group lifecycle management). 음수 PID 시그널을 사용하여 전체 프로세스 트리 (process trees)를 종료합니다. 고아 프로세스 (orphaned processes)가 남지 않습니다.
Git 워크트리 (worktree) GC. 에이전트별 워크트리를 가진 영구적인 bare 리포지토리 (bare repos)를 사용합니다. 파괴 시, 시작 시, 그리고 10분마다 자동으로 정리됩니다.
에이전트 간 메시지 버스 (Inter-agent message bus). 작업 위임, 결과, 질문, 인터럽트 (interrupts)를 처리합니다. 경합 조건 (races)을 방지하기 위한 전달 잠금 (delivery locks)과 함께 유휴 에이전트에게 자동으로 전달됩니다.
Anthropic SDK의 래퍼 (wrapper)가 아닙니다. 채팅 UI도 아닙니다. 에이전트가 요청하지 않은 행동을 하기 시작할 때 필요한 가드레일 (guardrails)과 함께 실제 Claude Code 프로세스를 실행합니다.
SDK는 도구 호출 (tool calling) 기능이 포함된 채팅 완료 (chat completions)를 제공합니다. Claude Code는 Anthropic이 유지 관리하는 파일 편집, bash 실행, git, MCP, 세션 재개 및 하위 에이전트 위임 기능을 갖춘 완전한 코딩 에이전트를 제공합니다. AgentManager는 이들을 처음부터 다시 만들려 하지 않고, 이러한 에이전트들을 실행합니다.
Claude Code의 --output-format stream-json 옵션은
타입이 지정된 JSON 이벤트 (터미널 스크래핑이 아님)를 제공하며, 플랫폼은 이를 파싱하여 실시간 UI 스트리밍, 상태 추적 및 비용 계산에 사용합니다. Anthropic이 Claude Code에 추가하는 새로운 기능들은 별도의 작업 없이도 AgentManager에 나타납니다.
Docker가 필요합니다. 설치되어 있지 않다면, Mac/Windows용 Docker Desktop 또는 Linux용 Docker Engine을 설치하십시오. 확인 방법: docker --version을 실행하십시오.
터미널에서 실행하십시오. 버전 정보가 나타나면 설정이 완료된 것입니다.
Docker는 AgentManager를 실행하는 유일하게 지원되는 방식입니다. Docker 외부에서 서버나 UI를 실행하는 것은 지원되지 않으며 안전하지 않습니다.
저장소 복제 (Clone the repository)
git clone https://github.com/simonstaton/AgentManager.git AgentManager cd AgentManager
환경 변수 설정 (Configure environment variables)
cp .env.example .env
.env 파일을 편집하여 다음을 설정하십시오:
API_KEY — 웹 UI(Web UI) 로그인 시 사용할 비밀번호입니다.
ANTHROPIC_AUTH_TOKEN — OpenRouter 또는 Anthropic API 키입니다 (예: openrouter.ai/keys에서 발급).
GCS_BUCKET은 설정하지 마십시오 — 로컬 모드(Local mode)를 위해 설정하지 않은 상태로 두십시오.
앱 시작 (Start the app)
npm run docker:local
이미지를 빌드하는 동안 첫 실행 시 몇 분 정도 소요될 수 있습니다.
UI 열기 (Open the UI)
**http://localhost:8080**으로 이동하여 API_KEY로 로그인하십시오.
데이터(저장소, 공유 컨텍스트, 로그)는 Docker 볼륨(Volume)에 저장되며 재시작 후에도 유지됩니다. 전체 단계 및 문제 해결: Docker로 로컬에서 실행하기.
| 기능 | 상세 내용 |
|---|---|
| 멀티 에이전트 오케스트레이션 (Multi-agent orchestration) | 최대 100개의 동시 에이전트 지원, 각 에이전트는 격리된 /tmp/workspace-{uuid} 및 완전한 Claude Code 기능 보유 |
| 실시간 스트리밍 UI (Real-time streaming UI) | SSE 스트리밍, 라이브 터미널 출력, 도구 사용(Tool use) 시각화, 턴당 비용(Cost-per-turn) 통계를 제공하는 Next.js App Router UI |
| 작업 그래프 + 오케스트레이터 (Task graph + orchestrator) | Plan-Execute-Observe 루프, 역량 인지 라우팅(Capability-aware routing) 및 에이전트 간 계약(Inter-agent contracts)을 갖춘 구조화된 월드 모델 (World model) |
| 에이전트 그래프 시각화 (Agent graph visualization) | 상태별로 색상이 지정되고 각 노드에 토큰 사용량이 표시되는, 부모-자식 토폴로지(Topology)를 보여주는 대화형 SVG 트리 |
| 비용 추적 (Cost tracking) | 에이전트별 토큰 수 및 USD 비용 추정치, 요약 대시보드, 모델별 가격 책정 (Opus/Sonnet/Haiku) |
| 일시 중지 및 재개 (Pause and resume) | 실행 중인 에이전트를 작업 중간에 일시 중지하고 나중에 재개할 수 있음 |
프로세스 유지 및 컨텍스트 보존 (Process is kept alive, context preserved) |
신뢰도 등급 (Confidence grading) |
에이전트가 자신의 수정 사항을 신뢰도 점수와 함께 스스로 평가하며, 우선순위 검토를 위해 UI에 표시됨 |
첨부 파일 지원 (Attachment support) |
프롬프트와 함께 에이전트에게 파일을 보내거나, 텍스트 프롬프트 없이 파일만 첨부 가능 |
Cron 스케줄러 (Cron scheduler) |
지속적인 웨이크 온 얼러트 (wake-on-alert) 스케줄러: 에이전트가 정해진 일정에 따라 자신을 다시 트리거하는 작업을 등록할 수 있음 |
에이전트 간 메시징 (Inter-agent messaging) |
인메모리 발행/구독 (In-memory pub/sub): 작업(task), 결과(result), 질문(question), 정보(info), 상태(status), 중단(interrupt). 직접 전달 또는 브로드캐스트 가능. 유휴(idle) 에이전트에게 자동 전달 |
에이전트 지속성 (Agent persistence) |
상태(State), 이벤트(events) 및 공유 컨텍스트(shared context)가 GCS로 동기화됨. 에이전트는 컨테이너 재시작 및 콜드 스타트(cold starts) 상황에서도 유지됨 |
부모-자식 생명주기 (Parent-child lifecycle) |
에이전트가 하위 에이전트(sub-agents)를 생성함. 부모를 파괴하면 전체 서브트리(subtree)가 자동으로 파괴됨 |
OpenRouter 지원 (OpenRouter support) |
OpenRouter를 통하거나 Anthropic API로 직접 라우팅함. UI에서 런타임 중에 키를 전환할 수 있음 |
모델 선택 (Model selection) |
Opus 4.6, Sonnet 4.6, Sonnet 4.5, Haiku 4.5. 작업 복잡도에 따라 에이전트별로 선택 가능 |
MCP 통합 (MCP integrations) |
GitHub, Figma, Linear, Notion, Slack, Google Calendar. MCP 서버 참조 |
안전 가드레일 (Safety guardrails) |
명령어 블랙리스트(Command blocklists), 속도 제한(rate limiting), 메모리 모니터링, 생성 깊이 제한(3단계 깊이, 자식 20개), 4시간 세션 TTL |
Git 워크트리 관리 (Git worktree management) |
/persistent/repos/ 내의 지속적인 베어 리포지토리(bare repos)와 에이전트별 워크트리(worktrees) 및 자동 가비지 컬렉션(GC) |
하나의 기능을 위해 함께 협업하는 에이전트 팀을 생성합니다:
# 에이전트 1 생성: 기능 개발자 (Feature developer)
POST /api/agents
{
...
에이전트들은 메시지 버스(message bus)를 통해 조정합니다. UI에서 세 개의 터미널이 실시간으로 작동하는 것을 볼 수 있습니다.
새로운 PR을 감시하는 지속적인 에이전트를 배포합니다:
POST /api/agents
{
"name": "pr-monitor",
...
이 에이전트는 컨테이너 재시작 후에도 지속됩니다. Cloud Run이 0으로 스케일링(scale to zero)되더라도, 컨테이너가 깨어나면 에이전트가 재개됩니다.
단 한 번의 요청으로 전체 팀을 생성합니다:
POST /api/agents/batch
{
"agents": [
...
세 에이전트 모두 병렬로 생성되어 즉시 시작됩니다.
Browser (React SPA) -> Express API (/api/) -> Claude CLI 프로세스
에이전트별 워크스페이스에 대한 정적 서빙 (/)
JWT 인증 및 GCS와 동기화된 공유 컨텍스트 (shared context)
단일 컨테이너, 단일 서비스입니다. Express는 API 라우트와 빌드된 React UI 서빙을 모두 처리합니다. 각 에이전트는 자신만의 워크스페이스를 가진 격리된 Claude CLI 프로세스입니다.
디스크 지속성 (disk persistence)을 갖춘 인메모리 발행/구독 (pub/sub) 방식입니다. 메시지 유형은 task, result, question, info, status, interrupt입니다. 메시지는 직접 전달되거나 브로드캐스트(broadcast)될 수 있습니다. 실시간 UI 업데이트를 위해 /api/messages/stream에서 SSE 스트림을 제공합니다.
/shared-context/ 내의 지속적인 마크다운 (markdown) 파일입니다. 모든 에이전트는 이 파일들을 읽고 씁니다. 재시작 시에도 유지되도록 GCS와 동기화됩니다. 의사 결정, 문서화 및 에이전트 간 메모리 (cross-agent memory) 용도로 사용됩니다.
이 플랫폼에서 Claude Code는 두 가지 위임 (delegation) 메커니즘을 가집니다:
Task 도구 (빠르고, 보이지 않음) - Claude Code의 내장된 Task 도구는 프로세스 내에서 가벼운 서브 에이전트 (sub-agents)를 생성합니다. 오버헤드가 없으며 새로운 프로세스를 생성하지 않습니다. 조사 및 탐색에 적합합니다.
플랫폼 API (보이고, 독립적임) - POST /api/agents는 자체 CLI 프로세스, 워크스페이스 및 UI 내 터미널을 가진 플랫폼 관리형 전체 에이전트를 생성합니다. 에이전트들은 메시지 버스 (message bus)를 통해 협업합니다. 부모 에이전트가 parentId를 설정하면 자동 정리 (cleanup)가 이루어집니다.
하이브리드: "이 리포지토리의 구조를 조사한 다음, 구현을 수행할 수 있는 가시적인 에이전트 팀을 생성해라." 빠른 조사 단계에는 Task 도구를 사용하고, 가시적인 작업에는 플랫폼 API를 사용합니다.
에이전트는 parentId를 사용하여 서브 에이전트를 생성합니다. 부모를 파괴하면 모든 자식 에이전트도 자동으로 파괴됩니다. 최대 깊이는 3단계이며, 에이전트당 최대 20개의 자식을 가질 수 있습니다.
어느 날 저녁, 일상적인 업무를 조정하기 위해 오케스트레이터 (orchestrator) 에이전트가 생성되었습니다. 이 에이전트는 대규모 서브 에이전트 군집 (swarm)을 생성하는 것이 최선의 접근 방식이라고 결정했습니다. 그 서브 에이전트들은 서로의 풀 리퀘스트 (pull requests)를 검토하고, 승인하고, 머지(merge)하며, 그 결과를 스스로 GCP에 배포하기 시작했습니다.
서버를 내렸습니다. 하지만 풀 리퀘스트는 계속해서 들어왔습니다. 알고 보니, 에이전트에게 당신의 GitHub 토큰과 Anthropic API 키, 그리고 --dangerously-skip-permissions 옵션을 부여했을 때 발생하는 일이었습니다.
, 그들은 당신의 서버가 계속 작동할 필요가 엄격하게 요구되지 않습니다. 그 청구서는 교육적인 경험이었습니다.
킬 스위치 (Kill switch)는 이런 일이 다시는 발생하지 않도록 존재합니다.
| 계층 (Layer) | 메커니즘 (Mechanism) | 역할 |
|---|---|---|
| 1 | 전역 중단 (Global halt) | POST /api/kill-switch가 모든 API 요청을 차단합니다. 지속적인 플래그 (Persistent flag)는 GCS 동기화를 통해 재시작 후에도 유지됩니다. UI에 있는 커다란 빨간 버튼입니다. |
| 2 | 핵 프로세스 종료 (Nuclear process kill) | 모든 추적 중인 에이전트가 파괴되며 + 시스템상의 모든 claude 프로세스가 종료됩니다. 워크스페이스 (Workspaces)가 삭제됩니다. |
| 3 | 토큰 무효화 (Token invalidation) | 활성화 시 JWT 비밀키 (secret)가 교체됩니다 (비활성화 시 다시 교체됨). 모든 기존 토큰은 즉시 무효화됩니다. |
| 4 | 생성 제한 (Spawn limits) | 최대 깊이 3, 최대 자식 20개. 재귀적인 스웜 폭발 (recursive swarm explosions)을 방지합니다. |
| 5 | 명령 차단 목록 (Command blocklist) | gh pr merge, gcloud deploy, terraform apply, git push --force가 차단됩니다. 이것들은 벽이 아니라 과속 방지턱입니다. |
| 6 | GCS를 통한 원격 종료 (Remote kill via GCS) | API에 접속할 수 없는 경우에도 플랫폼을 중단하기 위해 GCS에 킬 스위치 파일을 직접 업로드합니다. |
# 계층 6: API에 접속할 수 없을 때의 원격 종료
echo '{"killed":true,"reason":"emergency"}' | gsutil cp - gs://your-bucket/kill-switch.json
킬 스위치 작동 - UI 패닉 버튼 또는 POST /api/kill-switch
외부 토큰 취소 - GitHub PAT, Anthropic API 키 및 모든 MCP 자격 증명을 교체하십시오.
피해 확인 - 병합된 PR, 배포된 서비스 및 GCP 리소스 생성을 검토하십시오.
GCS 검토 - 에이전트가 남겼을 수 있는 페이로드 (payloads)가 있는지 공유 컨텍스트 (shared-context)를 확인하십시오.
API에 접속할 수 없는 경우 - GCS에 킬 스위치 파일을 업로드하거나, Cloud Run 서비스를 완전히 삭제하십시오: gcloud run services delete agent-manager --region=$REGION
킬 스위치는 플랫폼을 제어하지만, 다음은 수행할 수 없습니다:
- 풀 리퀘스트 (Pull requests) 병합 취소 또는 서비스 배포 취소
- 외부 API 토큰 취소 (직접 수행해야 합니다)
- 에이전트가 플랫폼 외부에서 생성한 프로세스 중단 (예: Anthropic API에 대한 직접적인
curl호출) - 버튼을 누르기 전에 이미 발생한 피해를 되돌리기
에이전트에게 부여하는 자격 증명을 제한하십시오. 그것이 진정한 안전망입니다.
- 결제가 활성화된 GCP 프로젝트
- 인증 및 설정이 완료된
gcloudCLI - 설치된
terraformCLI - Docker (로컬에서 빌드하는 경우)
# GCP 프로젝트 세부 정보 설정
export PROJECT_ID=your-project-id
export REGION=us-central1
...
cd terraform
cp terraform.tfvars.example terraform.tfvars
terraform.tfvars 파일을 다음 값들로 편집하십시오:
project_id
- 사용자의 GCP 프로젝트 ID
region
- 배포 지역 (예:
us-central1)
api_key
- UI 로그인 비밀번호
openrouter_api_key
- openrouter.ai/keys 에서 가져오십시오
jwt_secret
- 32자 이상의 임의의 문자열
선택 사항:
github_token, figma_token, linear_api_key, notion_api_key 등
terraform init
terraform plan # 변경 사항 미리보기
terraform apply # 배포
이 과정은 다음을 생성합니다:
Cloud Run 서비스
- 32GB RAM, 8 CPU, 오토스케일링 (최소 0, 최대 1 인스턴스)
GCS 버킷 (GCS bucket)
- 에이전트 상태 및 공유 컨텍스트 (Shared context)를 위한 영구 저장소
Secret Manager 비밀값 (Secret Manager secrets)
- OpenRouter 키, API 키, JWT 비밀값, MCP 자격 증명
서비스 계정 (Service account)
- 최소한의 IAM 권한 (Cloud Run 호출자, GCS 관리자, Secret Manager 접근자)
IAM 인증 (IAM auth)
- 공개 액세스 불가; 인증된 사용자 필요
Cloud Monitoring 알림 (Cloud Monitoring alerts)
- 에러율, p99 지연 시간 (latency), 충돌, 메모리, CPU
서비스는 기본적으로 비공개입니다. 서비스를 호출할 수 있는 권한을 자신에게 부여하십시오:
gcloud run services add-iam-policy-binding agent-manager \
--region=$REGION \
--member="user:your-email@example.com" \
...
서비스 URL을 확인하고 브라우저에서 여십시오:
terraform output service_url
# 또는
gcloud run services describe agent-manager --region=$REGION --format='value(status.url)'
terraform.tfvars에서 설정한 api_key로 로그인하십시오. 이제 에이전트 생성을 시작할 수 있습니다.
완료되었습니다. 에이전트는 컨테이너 재시작 후에도 유지됩니다. 공유 컨텍스트는 60초마다 GCS로 동기화됩니다. 플랫폼은 유휴 상태일 때 0으로 자동 확장(비용 발생 없음)되며, 첫 번째 요청이 들어오면 깨어납니다.
| 설정 | 기본값 | 변경 방법 |
|---|---|---|
| 최대 인스턴스 (Max instances) | 1 | terraform/cloud-run.tf > max_instance_count |
| ... |
각 에이전트는 Claude CLI 프로세스(~50-150MB RSS)입니다. 8 CPU 및 32GB RAM 환경에서 컨테이너는 최대 100개의 동시 에이전트를 지원합니다. 메모리 압박 모니터링 (cgroup v2)은 컨테이너 메모리의 85%에 도달하면 새로운 에이전트를 거부합니다.
최소 인스턴스 (Min instances) = 0은 콜드 스타트 (cold starts)를 의미합니다. 즉각적인 응답을 원한다면 1로 설정하십시오 (비용이 더 많이 발생합니다).
플랫폼은 모든 Claude API 트래픽을 Anthropic API로 직접 호출하는 대신 OpenRouter를 통해 라우팅합니다. 세 가지 환경 변수 (env vars)가 이를 제어합니다:
| 변수 (Variable) | 값 (Value) |
|---|---|
ANTHROPIC_BASE_URL | https://openrouter.ai/api |
ANTHROPIC_AUTH_TOKEN | 귀하의 OpenRouter 키 (sk-or-v1-...) |
ANTHROPIC_API_KEY | 비어 있어야 함 |
설정 UI 또는 API를 통해 런타임 (runtime) 중에 키를 전환할 수 있습니다. OpenRouter (sk-or-...) 및 Anthropic 직접 연결 키 (sk-ant-...)가 모두 허용됩니다.
MCP (Model Context Protocol) 서버는 에이전트에게 외부 도구에 대한 접근 권한을 부여합니다. 설정 방법은 mcp/README.md를 참조하십시오.
기본적으로 지원됨:
AI 자동 생성 콘텐츠
본 콘텐츠는 GitHub Claude Ecosystem의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기