지속형 에이전트 런타임
AI 에이전트를 위한 내구성 있는 실행 인프라.
이 프로젝트가 필요한 이유
AI 에이전트를 프로덕션 환경에서 운영하는 것은 (챗봇처럼이 아니라) 원격 컴퓨팅 환경에서 프로그램적이고 다단계적인 작업으로 처리될 때, 대부분의 에이전트 프레임워크가 해결하지 못하는 인프라 문제를 야기합니다:
-
충돌 복구 (Crash recovery): 에이전트 작업은 수 분 또는 수 시간에 걸쳐 많은 LLM 호출을 통해 실행될 수 있습니다. 임시 컴퓨팅 환경(컨테이너, 스팟 인스턴스)에서는 프로세스가 언제든지 중단될 수 있습니다. 내구성 있는 체크포인팅(durable checkpointing) 없이는 완료된 모든 단계가 손실되며 재실행해야 하므로 시간과 LLM 비용이 낭비됩니다.
-
실행 가시성 (Execution visibility): 에이전트가 터미널이 아닌 원격 워커에서 실행될 때, 무슨 일이 일어났고 왜 그런지 이해하기 위해 단계별 비용 추적, 실패 진단, 실행 기록이 필요합니다.
-
실패 관리 (Failure management): 대규모 환경에서 에이전트 작업의 실패는 단순히 로그에 스택 트레이스(stack trace)가 남는 것을 넘어, 재처리(redrive) 기능을 갖춘 검사 가능하고 조치 가능한 구조화된 데드 레터 큐(dead-letter queues)로 관리되어야 합니다.
이 프로젝트는 에이전트를 대규모로 배포하기 위한 개발자 인프라입니다. 이는 '에이전트가 있다'와 '이를 프로덕션에서 신뢰성 있게 500개를 실행할 수 있다' 사이의 계층 역할을 합니다. 목표 사용 사례로는 코딩 에이전트, 배치 문서 처리, 연구 작업 등이 있습니다.
주요 기능:
- 체크포인트 기반 실행 재개(Checkpoint-resume execution) — Postgres를 백엔드로 사용하는 LangGraph checkpointer; 태스크는 노드 경계에서 워커 충돌 시에도 생존합니다 (결정론적 리플레이 아님).
- 리스(Lease) 기반 충돌 복구(Lease-based crash recovery) — 모든 워커가 모든 태스크를 재개할 수 있으며, reaper가 만료된 리스를 복구합니다.
- 다중 공급자 LLM(Multi-provider LLM) — Anthropic, OpenAI, Google, AWS Bedrock 등 구성된 API 키에서 자동 발견됩니다.
- 에이전트별 비용 추적 및 예산 관리(Per-agent cost tracking and budgets) — 단계별 증분 비용 측정, 예산 기반 태스크 일시 중지 기능을 제공합니다.
- 인간 개입 (Human-in-the-loop) — 상태 비저장(stateless)의
waiting_for_approval 및 waiting_for_input 상태를 통한 일시 중지/재개 기능입니다.
- 고객 소유 관측 가능성 (Customer-owned observability) — 태스크별 Langfuse 엔드포인트, 체크포인트 기반 비용/토큰 집계가 가능합니다.
- 재전송(redrive) 기능이 있는 데드 레터(Dead-letter with redrive) — 로그 스크래핑 방식이 아닌 구조화된 실패 검사를 지원합니다.
- 자체 도구 가져오기 (Bring-your-own-tools, BYOT) — URL로 등록되는 고객 제공 MCP 도구 서버를 사용합니다.
- 샌드박스 코드 실행(Sandboxed code execution) — E2B 기반의 셸, 파일 I/O 및 아티팩트 내보내기가 가능하며, 파일 입력은 multipart 업로드 방식으로 이루어집니다.
Java/Spring Boot API, Python 워커, React/Vite 콘솔 및 PostgreSQL 상태 저장소로 구성된 작동 시스템으로 구축되었으며, ECS Fargate + Aurora Serverless v2에 배포할 수 있습니다.
현재 아키텍처 (Current Architecture)
이 시스템은 데이터베이스를 큐(queue)로 사용하는 상태 비저장(stateless) 워커 풀을 사용합니다. 워커들은 상호 교체 가능하며 — 어떤 워커든 모든 태스크를 가져올 수 있고, 어떤 워커든 다른 워커로부터 체크포인트된 태스크를 재개할 수 있습니다. 상태는 로컬 디스크가 아닌 PostgreSQL에 저장되므로, 충돌, 배포 및 스케일링 이벤트에도 태스크가 생존합니다.
- 클라이언트는 설정된 에이전트를 대상으로 API 서비스를 통해 작업을 제출합니다.
- 작업은 PostgreSQL에
queued 상태로 저장됩니다.
- 워커는
FOR UPDATE SKIP LOCKED를 사용하여 작업을 가져옵니다 (claim).
- 워커는 에이전트의 구성(모델, 도구, 시스템 프롬프트)을 로드하고 LangGraph 워크플로우를 실행하며, 체크포인트를 PostgreSQL에 기록합니다.
- 하트비트는 작업 진행 중 리스(lease)를 연장합니다.
- 작업은 인간의 승인 또는 입력을 위해 일시 중지될 수 있으며 (
waiting_for_approval, waiting_for_input), 이 경우 워커가 해제됩니다. 사람이 응답하면 어떤 워커든 재개할 수 있습니다.
- 리퍼(reaper)는 만료된 리스를 복구하고 타임아웃/데드레터 전환을 처리합니다.
에이전트는 런타임에 이 도구들에 접근할 수 있으며, 이는 LangGraph 실행기(executor)에 직접 연결됩니다. 작업별 실제 사용 가능 여부는 에이전트의 allowed_tools 설정과 샌드박스(sandbox)가 프로비저닝되었는지 여부에 따라 달라집니다:
web_search — DuckDuckGo를 통한 웹 검색
read_url — 공개 URL에서 텍스트를 가져오고 추출합니다.
request_human_input — 작업을 일시 중지하고 인간 운영자의 응답을 기다립니다.
create_text_artifact — 텍스트 출력을 다운로드 가능한 작업 아티팩트(S3)로 저장합니다. 비샌드박스 에이전트만 사용 가능하며, 샌드박스가 활성화된 에이전트는 출력 파일에 대해 대신 export_sandbox_file을 사용합니다.
sandbox_exec, sandbox_read_file, sandbox_write_file, export_sandbox_file — E2B 샌드박스 내부의 셸 및 파일 I/O (에이전트가 sandbox.enabled: true로 구성된 경우 사용 가능)
사용자 정의 MCP 도구 서버 URL(BYOT, Bring Your Own Tool)로 구성된 에이전트는 작업 시작 시 해당 서버의 도구가 동일한 도구 목록에 병합됩니다.
리포지토리 레이아웃 (Repository Layout)
지속형 에이전트 런타임 (Persistent Agent Runtime)
시작하기
필수 조건
- Java 21 이상, Python 3.11 이상, Node.js 18 이상, Docker
빠른 시작
상세한 설정 옵션, 환경 변수, 타이밍 구성 및 수동 데이터베이스 설정은 docs/LOCAL_DEVELOPMENT.md를 참조하세요.
AWS에 배포하기
전체 AWS 배포(Aurora Serverless v2, ECS Fargate, 내부 ALB, SSM 접근)는 infrastructure/README.md를 참조하세요.
유용한 진입점
API 서비스: services/api-service/README.md
콘솔: services/console/README.md
워커 서비스: services/worker-service/README.md
백엔드 통합 테스트: tests/backend-integration/README.md
데이터베이스 스키마: infrastructure/database/README.md
공통 명령어 (Common Commands)
make install
make start
make start N=3
...
팁: make -n <target>을 사용하면 타겟의 셸 명령어를 실행하지 않고 미리 볼 수 있습니다. 예를 들어, make -n start N=3은 세 개의 워커에 대한 전체 시작 흐름을 보여줍니다.
개발 현황 (Development Status)
저장소는 활발하게 개발 중입니다.
Phase 1 — 지속형 실행 (Durable Execution) (완료)
- 임대 기반 작업 클레임(
FOR UPDATE SKIP LOCKED)을 포함한 데이터베이스 스키마
- 작업 제출, 목록 조회, 상태 확인, 체크포인트, 취소, 데드 레터 목록 및 재실행을 위한 REST API
- 워커 폴러(Worker poller), 하트비트 관리자(heartbeat manager), 리퍼(reaper)
- 자체 등록, 하트비트, 오래된 워커 정리 기능을 갖춘 워커 레지스트리
- PostgreSQL 기반 LangGraph 체크포인터
- 내장 도구:
web_search, read_url, request_human_input 외에도 외부 사용을 위해 web_search, read_url, calculator를 노출하는 독립형 FastMCP 서버
- 강제 임대 만료 및 데드 레터 전환을 위한 개발 전용 작업 제어 기능
- 동적 모델 제공자 관리: 데이터베이스 기반 제공자/모델 레지스트리, API 키로부터의 자동 검색(auto-discovery), 모델별 비용 추적
- 콘솔 프론트엔드: 대시보드, 작업 목록, 작업 디스패처, 실행 텔레메트리, 데드 레터 큐
- 충돌 복구 및 생명주기 동작에 대한 엔드투엔드 테스트 커버리지
Phase 2 — 다중 에이전트 (Multi-Agent) (진행 중)
완료된 트랙:
트랙별 구성 요소
- 트랙 1 — 에이전트 제어 평면(Agent Control Plane): CRUD, 구성 관리 및 에이전트별 작업 라우팅을 갖춘 일급 개체로서의 에이전트.
- 트랙 2 — 런타임 상태 모델(Runtime State Model): 인간 참여형 워크플로우(
waiting_for_approval, waiting_for_input), 상태 비저장(stateless) 일시 중지/재개, 작업 이벤트 기록.
- 트랙 3 — 스케줄러 및 예산(Scheduler and Budgets): 에이전트 인식 라운드 로빈 스케줄링, 에이전트별 예산, 예산 기반 작업 일시 중지, 증분 비용 추적.
- 트랙 4 — 사용자 정의 도구 런타임(Custom Tool Runtime) (BYOT): URL로 등록된 고객 제공 MCP 도구 서버, 워커 측 MCP 클라이언트 통합, 베어러 토큰 인증.
교차 기능 (Cross-cutting) (완료됨)
- 고객 소유 Langfuse 통합: 작업별 Langfuse 엔드포인트 구성, CRUD API, 연결성 테스트, 체크포인트 기반 비용/토큰 집계.
- 에이전트 기능(Agent Capabilities): E2B 샌드박스 통합 (프로비저닝 / 일시 중지 / 재개 / 파괴 라이프사이클,
sandbox_id를 통한 충돌 복구), 샌드박스 도구 (sandbox_exec, sandbox_read_file, sandbox_write_file, export_sandbox_file), S3에 출력 아티팩트 저장 (LocalStack 로컬), create_text_artifact 도구, 다중 파트 파일 입력 작업 제출 — docs/design-docs/agent-capabilities/design.md 참조.
향후 계획 (Upcoming)
- 트랙 5 — 메모리(Memory): 장기 메모리 추출, 추가 전용 저장소(append-only storage), 압축(compaction).
- 트랙 6 — GitHub 통합: 풀 리퀘스트를 통한 코드 에이전트 입/출력.
AWS 배포 (AWS Deployment) (검증된 엔드투엔드)
- CDK 인프라: VPC, Aurora Serverless v2, ECS Fargate, 내부 ALB, SSM 액세스 호스트.
- 배포 시 자동 스키마 부트스트랩 및 모델 검색.
- 전체 배포 워크스루: infrastructure/README.md 참조.
설계 문서 (Design Documents)
시스템 개요보다는 실제 시스템 계약을 원한다면 여기서 시작하세요.
테스트(Testing)
리포지토리에는 네 가지 실질적인 테스트 계층이 있습니다:
통합 스위트(integration suite)는 의도된 런타임 라이프사이클을 검증하는 가장 좋은 장소입니다:
- 대기열화 -> 실행 중 -> 완료 (queued -> running -> completed)
- 재시도 및 지수 백오프(exponential backoff)
- 데드 레터 동작(dead-letter behavior)
- 취소 및 재전송(cancellation and redrive)
- 충돌 복구 및 체크포인트 재개(crash recovery and checkpoint resume)
- 멀티 워커 조정(multi-worker coordination)
로컬 검증 워크플로우 (Local Validation Workflow)
Makefile 워크플로우의 로컬 End-to-End 검증을 위해:
- 전제 조건 및 로컬 종속성을 확인하려면
make check를 실행합니다.
- 안전한 스키마 설정을 위해
make db-migrate를 사용하거나, 파괴적인 초기화와 스키마 검증을 명시적으로 원할 경우 make db-reset-verify를 사용합니다.
make start 또는 make start N=3으로 스택을 시작합니다.
make status, curl http://localhost:8080/actuator/health, 그리고 선택적으로 curl -I http://localhost:5173을 사용하여 스택이 정상인지 확인합니다.
- 시작 과정에 의심스러운 점이 있다면
make logs로 로그를 추적(tail)합니다.
- 완료되면
make stop으로 스택을 중지합니다.
make start는 콘솔(console), API, 그리고 요청된 워커 개수(worker count)가 준비될 때까지 기다린 후에 성공을 보고합니다.
로컬 개발 중 코드 변경의 경우, make start는 빌드 아티팩트(build-artifact) 기반이 아닌 소스(source)-기반입니다:
- 콘솔은 Vite 개발 서버를 실행하므로, 프론트엔드 편집 시 재빌드 없이 핫 리로드(hot-reload)됩니다.
- API는
./gradlew bootRun을 실행하므로, 시작 전에 별도의 ./gradlew build가 필요하지 않지만, Java 코드 변경 사항을 반영하려면 API 프로세스를 다시 시작해야 합니다.
- 워커는 소스에서
python main.py를 실행하므로, 별도의 빌드가 필요하지 않지만, Python 코드 변경 사항을 반영하려면 워커 프로세스를 다시 시작해야 합니다.