전체 사례No. 029
ZoomInfo 15-agent swarm으로 Angular→React 938파일을 1주에 이전하다
- 사례 번호
- 029
- 1차 출처
- ZoomInfo Engineering Blog
- 원문 게시
- 2026-04-08

1. 왜 이 사례인가
서로 다른 프레임워크 간의 대규모 마이그레이션은 전통적으로 수많은 시니어 엔지니어가 수개월씩 매달려야 하는 고된 작업입니다. 줌인포(ZoomInfo)의 애플리케이션(Applications) 팀은 핵심 기능을 Angular에서 React로 전면 재작성해야 하는 과제에 직면했습니다. 과거 해당 기능을 Angular로 처음 구축했을 당시의 기준을 대입하면 시니어 엔지니어 4~5명이 최소 6개월 동안 전담해야 하는 규모였으며, 마이그레이션 대상 파일만 938개에 달했습니다.
팀은 이 난제를 풀기 위해 클로드 코드(Claude Code)를 기반으로 멀티 에이전트 스웜(multi-agent swarm) 체계를 구축했습니다. 팀 리드 역할을 맡은 Claude Opus 1대와 작업자 역할을 수행하는 15대의 Claude Sonnet 워커—엔지니어링 10대, 단위 테스트 1대, Playwright E2E 1대, 코드 리뷰 2대, 기능 동등성 검증 및 감사(parity/audit) 1대—로 구성된 위계형 팀을 구성했습니다. 그 결과 단 1명의 오케스트레이터가 1주일 동안 분산된 8~12시간의 실작업(working hours)만으로 938개 파일 전체의 이식 작업을 완수했습니다. 엔지니어의 주된 역할이 직접 코드를 작성하는 것에서 스캐폴딩(scaffolding)·컨텍스트(context)·피드백 루프(feedback loop)를 설계하고 조율하는 것으로 전환된 대표적인 ‘에이전트 퍼스트 마이그레이션(agent-first migration)’ 사례입니다.
2. Problem
Angular에서 React로의 프레임워크 전환은 단순한 문법 변환 수준에 그치지 않습니다. 레거시 아키텍처를 면밀히 분석하고, 기존 기능을 역으로 문서화하며, 새로운 프레임워크 문법에 맞게 코드를 재작성하는 것은 물론, 단위 및 E2E 테스트를 거쳐 기존 화면과 동작이 완벽히 일치하는지 행동 동등성(behavioral parity)까지 빈틈없이 검증해야 합니다. AI 도입 이전(Pre-AI) 방식으로는 숙련된 엔지니어 4~5명이 6개월 이상 투입되어야 하는 극심한 인력 집약적 프로젝트였습니다.
그렇다고 정교한 통제 장치 없이 AI에게 작업을 전적으로 맡기면 이른바 ‘AI 슬롭(AI slop)‘이 걷잡을 수 없이 누적됩니다. Jest/RTL 환경에서 모의 객체(mock)나 타이머를 제대로 해제하지 않아 발생하는 테스트 메모리 누수, Angular의 의존성 주입(DI)이나 RxJS 스트림을 관용적인 React 훅과 Context 대신 기형적인 우회 코드로 변환하는 아키텍처적 환각(hallucination), 충돌하는 린트(lint) 및 타입 규칙 속에서 언어 서버(LSP)의 자기 수정이 꼬여 무한 반복되는 순환 AST(추상 구문 트리) 변환 루프 등이 대표적입니다.
여기에 하드웨어 자원의 물리적 한계도 운영상의 큰 제약으로 작용했습니다. 15대의 동시 실행 에이전트(concurrent agents)는 Apple M2 Pro(32GB RAM) 단일 머신 환경에서 감당할 수 있는 경험적 한계선(15-agent limit)이었습니다. 그 이상의 에이전트를 가동하면 각 워커가 띄우는 TypeScript Language Server의 메모리 점유(footprint)가 급증하여 시스템 전체가 크래시되는 현상이 발생했습니다.
확인된 사실: 938개 파일 이전 대상, Angular→React 핵심 기능 재작성, 과거 구축 기준 6개월 및 4~5명 소요 규모, Claude Code Agent Teams 아키텍처 적용, Opus 리드 + 15대 Sonnet 워커 구성, Apple M2 Pro 32GB 환경의 15개 에이전트 동시 실행 경험적 한계, 2026-04-08 원문 게시.
3. Solution
3.1 Blueprint: 병렬화 최적화 실행 계획
본격적인 전환에 앞서 Claude Code 에이전트가 레거시 코드베이스 전체(/src/legacy)를 사전에 정밀 분석하여 migration_plan.md라는 컴포넌트 단위 실행 계획을 수립했습니다. 프롬프트 단계에서부터 15대의 자율 워커가 병렬로 독립 실행될 수 있도록 컴포넌트 간 상호 의존성을 분리한 단계별(decoupled phases) 작업 구조를 도출하도록 요구했습니다.
3.2 Agent Teams Mode
새로운 세션에서 계층형 팀(hierarchical team) 구조를 초기화하고 역할을 세분화했습니다:
| 역할 | 수 | 임무 |
|---|---|---|
| Engineering | 10 | Angular 컴포넌트의 React 변환 및 테마 적용 |
| Unit Test | 1 | Jest/RTL 단위 테스트 작성 |
| Playwright | 1 | Playwright MCP 기반 브라우저 E2E 테스트 |
| Code Review | 2 | 가이드라인 및 컨벤션 준수 여부 리뷰 |
| Parity & Audit | 1 | 기능 완전성 검증 및 todo_list.md 관리 |
팀 리드를 맡은 Claude Opus는 중앙 상태 파일인 shared_memory.json과 todo_list.md를 실시간으로 모니터링했습니다. 응답이 멈춘(stall) 워커를 감지하여 프로세스를 재시작하고, 자율 해결 범위를 벗어난 “지나치게 복잡한(too complex)” 이슈는 건너뛴 뒤 사람 오케스트레이터에게 즉각 알림(human alert)을 보내 판단을 요청하도록 조율했습니다.
3.3 Agent-legible codebase
팀은 코드베이스를 사람이 눈으로 읽던 방식에서 벗어나 AI 에이전트가 정확하게 파싱하고 실행할 수 있는 구조(Agent-legible)로 재정리했습니다:
- 동적 상태 관리(Dynamic state):
shared_memory.json과todo_list.md를 스웜 전체의 상태 머신(state machine)이자 작업 큐로 운영하여, 복수의 에이전트가 동일한 파일을 중복으로 가져가 작업(pickup)하는 충돌을 방지했습니다. - 아키텍처 인덱스(Architectural index): 진입점인
claude.md가 라우터 역할을 하여agents.md로 연결하고, 이는 다시 컴포넌트 구조, 스타일링, 테스트 작성법, 상태 관리 do/don’t 규칙을 명시한 세부 모듈형 마크다운 문서들로 맥락을 명확히 분기했습니다. - 살아있는 청사진(Living blueprint):
migration_plan.md는 고정된 문서가 아니라 Opus 리드와 사람이 지속적으로 반복 갱신(iteratively update)하는 실행 지침이었습니다. 여기에 프론트엔드 디자인 스킬(front-end design skill), TypeScript 언어 서버(LSP)의 실시간 타입 검증, Playwright MCP를 통한 실제 브라우저 렌더링 검증이 유기적으로 결합되었습니다.
3.4 Entropy 관리: Audit agent gate
에이전트가 코드를 양산하면서 발생할 수 있는 코드베이스 엔트로피를 통제하기 위해 다층 방어 체계를 가동했습니다. 감사(Audit) 에이전트는 코드에 임시 TODO 주석을 방치하거나, 컴포넌트 경계(boundary)를 침범하거나, 아키텍처 가이드라인을 어긴 코드를 사람이 검토하는 PR 단계 이전에 사전 CI/CD 게이트(preliminary CI/CD)로 걸러냈습니다. 동시에 감독관 역할을 맡은 Opus 리드는 하트비트 타임아웃(heartbeat timeout)을 통해 통신이 끊긴(dropped) 워커를 자동으로 재초기화했습니다.
확인된 사실: migration_plan.md 청사진 생성, 15개 역할로 분담된 스웜 구조, shared_memory.json 및 todo_list.md 기반 동적 상태 관리, agents.md 기반 모듈형 컨텍스트 인덱스, TypeScript LSP 및 Playwright MCP 결합, 감사·리뷰 에이전트 기반 사전 검증, AI 슬롭 패턴(테스트 메모리 누수, DI 환각, 순환 AST 변환 루프)과 그 완화 장치.
4. Impact
줌인포 엔지니어링 블로그에서 공개한 전환 전후 비교 지표는 다음과 같습니다(기준일: 2026-04-08).
| 접근 | 시간 | 사람 엔지니어 | 에이전트 |
|---|---|---|---|
| 전통적 수동 이식 | 6개월 | 4~5 | 0 |
| Agent Teams Mode | 1주 (8~12 working hrs) | 1 (오케스트레이터) | 15 |
전체 마이그레이션 범위는 938파일에 달했습니다. 사람 엔지니어는 단순 반복형 코드 변환 노동에서 벗어나, 시스템 전반의 아키텍처 엣지 케이스를 해결하고 최종 완성도를 다듬는 ‘라스트 마일(last mile)’ 검증에만 집중할 수 있었습니다.
원문 블로그의 결론은 분명합니다. 멀티 에이전트 체계는 결코 모든 문제를 저절로 해결해 주는 마법의 탄환(silver bullet)이 아니며, 에이전트가 유발하는 코드 엔트로피를 통제하기 위해서는 엄격한 기술적 규율(engineering discipline)이 필수적으로 뒷받침되어야 합니다. 에이전트에게는 정형화된 일상적 실행(routine execution)을 맡기고, 사람은 전체 워크플로 오케스트레이션과 최종 품질에 대한 관리·감독(oversight)을 책임져야 한다는 점을 실증했습니다.
확인된 사실: 위 표의 비교 수치, 938개 파일 이전 완료, 1주(8~12 working hrs) 및 1인 오케스트레이터 운영, human의 라스트 마일 집중 및 엔트로피 관리 규율의 필요성.
5. Insight
병목은 코드 타이핑이 아니라 컨텍스트의 명확성(Context clarity)입니다. 개발 생산성의 한계는 코드를 얼마나 빨리 작성하느냐가 아니라 에이전트에게 얼마나 명확한 맥락을 주입하느냐에 달려 있습니다. 이에 따라 엔지니어의 핵심 산출물은 직접 짜는 코드에서 가이드라인, 테마 파일, 로컬 검증 서버, 정교한 프롬프트로 이루어지는 환경 설계(environment design)로 이동합니다.
에이전트 가독성(Agent-legibility)은 생산성의 핵심 승수(Force multiplier)입니다. 사람만 읽을 수 있는 거대하고 단편적인 README 문서로는 에이전트 스웜을 가동할 수 없습니다. claude.md 라우터를 거쳐 agents.md와 모듈형 가드레일, 그리고 실시간 작업을 동기화하는 공유 상태 관리(shared_memory.json)를 갖출 때 비로소 다수의 에이전트가 충돌 없이 유기적으로 협업할 수 있습니다.
인간의 지능은 마지막 20%(Last 20%)를 위해 아껴두어야 합니다. 대량의 컴포넌트 변환이나 반복적인 테스트 작성 같은 고부하 작업(high-volume lifting)은 에이전트 스웜이 도맡고, 엔지니어링 미감(taste), 조직의 히스토리에 대한 이해(institutional memory), 복잡한 아키텍처 엣지 케이스 해결은 사람의 몫입니다. 기계적 작업을 덜어낼 때 비로소 고난도 라스트 마일에 역량을 집중할 수 있습니다.
하드웨어 자원을 고려한 확장(Hardware-aware scaling)이 필수적입니다. 15대의 에이전트 동시 실행은 Apple M2 Pro(32GB RAM) 환경에서 확인된 경험적 상한선이었습니다. 에이전트가 구동하는 TypeScript Language Server의 메모리 점유를 고려하여, 초기에는 3~5대로 시작한 뒤 가용 메모리의 약 80% 수준까지 단계적으로 확장하는 운영 방식이 안전합니다.
복제 조건과 한계. Claude Code의 Agent Teams 체계, 언어 서버(LSP), Playwright MCP, 정교한 프롬프트 및 공유 상태 파일 운영, 사전 감사 게이트가 사전에 구비되어야 합니다. 또한 1주일 만에 완수한 938파일 이식은 특정 핵심 기능 단위의 마이그레이션 범위이며, 원문 블로그 역시 이를 엔터프라이즈 전사 코드베이스 전체의 완전 전환으로 일반화하여 주장하지는 않습니다. 아울러 실환경 배포 이후의 프로덕션 장애율이나 장기적 유지보수 비용 등은 공개되지 않았습니다.
한 줄 요약: 대규모 프레임워크 전환은 에이전트 스웜, 에이전트 친화적 코드베이스, 감사 게이트, 그리고 사람의 라스트 마일 검증이 결합될 때 비로소 개발 속도와 기능 동등성을 동시에 확보할 수 있습니다.
6. 원문에 없는 추정 (구현 가설)
6.1 shared_memory.json 기반 작업 큐와 파일 잠금
근거: 원문은 15대의 자율 에이전트가 단일 리포지토리에서 동시에 작업했으며, shared_memory.json과 todo_list.md가 실시간 상태와 마스터 큐를 추적하여 “두 에이전트가 동일한 파일을 중복으로 집어 들지 않음(no two agents picked up the same file)“을 보장했다고 기술합니다.
15대에 달하는 워커가 파일 충돌이나 레이스 컨디션 없이 병렬 작업을 수행하려면, 각 엔지니어링 워커가 특정 컴포넌트 변환에 착수하기 전 shared_memory.json 파일에 {file_path, assigned_agent_id, status: "in_progress", timestamp} 형태의 레코드를 원자적(atomic)으로 기록하거나, 중앙의 Opus 팀 리드가 작업을 배분한 뒤 배타적 파일 잠금(file lock)을 부여하는 메커니즘을 사용했을 것입니다. 작업이 성공적으로 끝나면 상태를 done으로 전환하고, 변환에 실패하거나 타임아웃이 발생하면 재시도 카운트를 올리거나 Opus 리드가 대기열로 작업을 회수하여 다른 워커에 재할당했을 것으로 보입니다. 아울러 todo_list.md는 migration_plan.md에서 사전에 도출된 의존성 분리 단계(phases)와 실시간으로 동기화되어, 상위 의존성을 가진 컴포넌트 변환이 완료되어야만 하위 컴포넌트 작업이 큐에 풀리는 백로그 관리 체계로 운영되었을 가능성이 큽니다.
6.2 Playwright MCP E2E agent와 실패 로그 루프
근거: 원문은 Playwright 에이전트가 브라우저 기반 E2E 동등성 테스트를 전담하되, 테스트 실패 시 React 코드를 직접 수정하지 않고 shared_memory.json에 DOM 불일치 및 콘솔 에러를 기록한 뒤 팀 리드에게 경고를 보냈다고 기술합니다.
Playwright 에이전트는 헤드리스 브라우저 환경에서 레거시 Angular 애플리케이션과 새로 컴파일된 React 애플리케이션을 동일한 사용자 시나리오로 병렬 실행하여 시각적 및 기능적 동등성을 검증했을 것입니다. 이 과정에서 DOM 구조의 차이나 렌더링 오류, 콘솔 예외가 감지되면, Playwright 에이전트가 코드를 직접 고치다 예기치 않은 부작용을 일으키는 것을 막기 위해 에이전트의 역할 권한을 ‘검증 및 기록’으로 엄격히 제한한 것으로 풀이됩니다. 대신 실패 지점의 셀렉터, 캡처된 스크린샷 메타데이터, 스택 트레이스를 구조화된 JSON 형태로 shared_memory.json에 적재하고 Opus 리드에게 인터럽트를 발생시키면, 리드가 해당 결함을 분석하여 엔지니어링 워커에게 명확한 수정 프롬프트와 함께 재할당하거나, 자율 해결이 불가능한 구조적 결함일 경우 사람 엔지니어의 라스트 마일 작업 목록으로 에스컬레이션하는 피드백 루프를 운용했을 것입니다.
6.3 Audit agent preliminary gate와 AI slop 탐지
근거: 원문은 감사(Audit) 에이전트가 코드 내 잔여 TODO 주석, 컴포넌트 경계 침범, 아키텍처 가이드라인 위반을 사람이 검토하는 PR 단계 전에 사전 차단했으며, 테스트 메모리 누수와 DI 환각 및 AST 순환 변환 루프 등 AI 슬롭 패턴을 관찰했다고 기술합니다.
감사 에이전트는 워커가 작성을 마친 코드가 PR로 넘어가기 전, 정적 분석 도구(ESLint, TypeScript 컴파일러)의 실행 결과와 agents.md에 명시된 규칙 체크리스트를 프롬프트에 주입하여 검증하는 사전 CI/CD 통과 관문(preliminary gate)으로 기능했을 것입니다. 특히 충돌하는 린트 규칙과 타입 검사 사이에서 언어 서버의 자체 수정이 꼬여 발생하는 순환 AST 루프를 차단하기 위해, 특정 파일에 대한 자동 수정 커밋이나 수정 시도가 일정 횟수(예: 3~5회)를 초과할 경우 해당 워커 프로세스를 즉시 강제 종료(kill)하고 사람이 개입하도록 경고를 띄우는 서킷 브레이커(circuit breaker) 로직이 결합되었을 개연성이 높습니다. 또한 Jest/RTL 환경의 테스트 메모리 누수나 Angular DI/RxJS의 기형적 변환 패턴 역시 사전 정의된 정적 패턴 매칭 및 린트 룰셋을 통해 사전 검출하여 사람이 불필요한 저품질 코드를 일일이 검토하지 않도록 방어막을 구축했을 것으로 추정됩니다.
7. 출처
- ZoomInfo Engineering — Experience with Multi-Agent AI for Framework Migration at ZoomInfo
https://engineering.zoominfo.com/experience-with-multi-agent-ai-for-framework-migration-at-zoominfo
발행일: 2026-04-08 (Applications Team at ZoomInfo)