수주 동안 자율적으로 코딩 에이전트를 돌리며, 하나의 프로젝트에서 수백 개의 동시 에이전트를 조율해 수백만 줄의 코드를 작성하게 하며 얻은 교훈을 정리한다.
URL: https://cursor.com/blog/scaling-agents
우리는 코딩 에이전트를 몇 주 동안 자율적으로 실행하는 실험을 해왔다.
우리의 목표는, 보통 인간 팀이 몇 달은 걸려 완성하는 프로젝트에서 에이전트형(agentic) 코딩의 한계를 어디까지 밀어붙일 수 있는지 이해하는 것이다.
이 글은 하나의 프로젝트에서 수백 개의 에이전트를 동시에 돌리고, 그들의 작업을 조율하며, 100만 줄이 넘는 코드와 수조 토큰을 작성하는 과정을 지켜보면서 배운 내용을 정리한다.
오늘날의 에이전트는 집중된 작업에는 잘 작동하지만, 복잡한 프로젝트에서는 느리다. 자연스러운 다음 단계는 여러 에이전트를 병렬로 실행하는 것이지만, 그들을 어떻게 조율할지 알아내는 일은 어렵다.
처음 우리의 직감은, 미리 계획을 세우는 방식은 너무 경직될 것이라는 것이었다. 대규모 프로젝트를 진행하는 경로는 모호하고, 올바른 업무 분할도 시작 시점에는 명확하지 않다. 우리는 에이전트들이 다른 에이전트가 현재 무엇을 하고 있는지에 따라 스스로 무엇을 할지 결정하는, 동적 조율(dynamic coordination)부터 시작했다.
초기 접근은 모든 에이전트에 동등한 지위를 부여하고, 공유 파일을 통해 자율적으로 조율하도록 하는 것이었다. 각 에이전트는 다른 에이전트가 무엇을 하는지 확인하고, 하나의 작업을 점유(claim)한 뒤, 자신의 상태를 업데이트했다. 두 에이전트가 같은 작업을 가져가는 것을 막기 위해 락(locking) 메커니즘을 사용했다.
이 방식은 흥미로운 방식으로 실패했다.
에이전트가 락을 너무 오래 잡고 있거나, 아예 해제하는 것을 잊는 일이 있었다. 락이 올바르게 동작하더라도 병목이 되었다. 20개의 에이전트가 있으면 실제 처리량은 2~3개 에이전트 수준으로 떨어졌고, 대부분의 시간은 대기(waiting)에 쓰였다.
시스템은 취약했다. 에이전트가 락을 잡은 상태로 실패할 수 있었고, 이미 자신이 보유한 락을 다시 획득하려 하거나, 락을 획득하지도 않고 조율 파일을 업데이트하려 하기도 했다.
우리는 락을 낙관적 동시성 제어(optimistic concurrency control)로 대체해 보았다. 에이전트는 상태를 자유롭게 읽을 수 있지만, 마지막으로 읽은 뒤 상태가 바뀌었다면 쓰기(write)가 실패하도록 했다. 이 방식은 더 단순하고 견고했지만, 여전히 더 깊은 문제가 있었다.
계층이 없으니 에이전트는 위험 회피적으로 변했다. 어려운 작업은 피하고, 대신 작고 안전한 변경만 하려 했다. 어떤 에이전트도 어려운 문제나 엔드투엔드 구현에 책임을 지지 않았다. 그 결과, 진전 없이 오랜 시간 동안 작업이 맴도는(churning) 상황이 생겼다.
다음 접근은 역할을 분리하는 것이었다. 모든 에이전트가 모든 일을 하는 평평한 구조 대신, 책임이 분명히 구분된 파이프라인을 만들었다.
**기획자(Planners)**는 코드베이스를 지속적으로 탐색하며 작업(Task)을 만든다. 특정 영역을 위해 하위 기획자(sub-planners)를 생성할 수 있어, 기획 자체도 병렬적이고 재귀적으로 진행된다.
**작업자(Workers)**는 작업을 가져와 그 완료에만 전념한다. 다른 작업자와 조율하거나 큰 그림을 고민하지 않는다. 할당된 작업을 끝낼 때까지 집중해서 처리한 뒤, 변경을 푸시한다.
각 사이클의 끝에서 심판(judge) 에이전트가 계속 진행할지 여부를 결정하고, 다음 반복(iteration)은 새로 시작했다. 이 방식은 조율 문제 대부분을 해결했고, 어떤 단일 에이전트도 시야가 좁아지는(tunnel vision) 일 없이 매우 큰 프로젝트로 확장할 수 있게 해주었다.
이 시스템을 시험하기 위해, 우리는 야심찬 목표에 적용했다. 처음부터 웹 브라우저를 만드는 것이었다. 에이전트는 거의 1주일 동안 실행되며 1,000개 파일에 걸쳐 100만 줄이 넘는 코드를 작성했다. GitHub에서 소스 코드를 살펴볼 수 있다.
코드베이스가 커졌음에도, 새로운 에이전트는 여전히 이를 이해하고 의미 있는 진전을 만들 수 있다. 수백 명의 작업자가 동시에 실행되며, 충돌을 최소화한 채 같은 브랜치로 푸시한다.
단순한 스크린샷처럼 보일지 모르지만, 브라우저를 처음부터 만드는 일은 극도로 어렵다.
또 다른 실험은 Cursor 코드베이스에서 Solid를 React로 제자리(in-place) 마이그레이션하는 것이었다. 3주 이상이 걸렸고, +266K/-193K 편집이 발생했다. 변경을 테스트하기 시작했고, 우리는 이 변경을 머지하는 것이 가능하다고 믿는다.

또 다른 실험은 출시 예정 제품을 개선하는 것이었다. 장기 실행 에이전트가 효율적인 Rust 버전을 통해 비디오 렌더링을 25배 더 빠르게 만들었다. 또한 커서를 따라 자연스러운 스프링 전환과 모션 블러로 부드럽게 확대/이동(zoom/pan)할 수 있도록 지원을 추가했다. 이 코드는 머지되었고 곧 프로덕션에 반영될 예정이다.
여전히 실행 중인 다른 흥미로운 예시도 몇 가지 있다.
우리는 하나의 목표를 향해 이 에이전트들에 수십억 토큰을 투입했다. 시스템이 완벽히 효율적이진 않지만, 기대했던 것보다 훨씬 효과적이다.
극도로 장기간 실행되는 작업에서는 모델 선택이 중요하다. 우리는 GPT-5.2 모델이 장시간 자율 작업에 훨씬 더 적합하다는 것을 발견했다. 지시를 따르고, 집중을 유지하며, 드리프트(drift)를 피하고, 정확하고 완전하게 구현하는 능력이 뛰어났다.
Opus 4.5는 대체로 더 일찍 멈추고, 편리할 때 지름길을 택하며, 제어권을 빠르게 되돌려주는 경향이 있다. 또한 서로 다른 모델이 서로 다른 역할에서 뛰어나다는 것도 알게 되었다. GPT-5.2는 GPT-5.1-codex보다 더 나은 기획자다. 후자는 코딩에 특화되어 훈련되었음에도 그렇다. 우리는 이제 범용 모델 하나를 쓰기보다, 역할에 가장 잘 맞는 모델을 각각 사용한다.
우리의 개선 중 상당수는 복잡성을 더하기보다 제거하는 데서 나왔다. 우리는 처음에 품질 관리와 충돌 해결을 위한 ‘통합자(integrator)’ 역할을 만들었지만, 해결하는 문제보다 더 많은 병목을 만들었다는 것을 알게 됐다. 작업자들이 이미 스스로 충돌을 처리할 수 있었다.
가장 좋은 시스템은 종종 예상보다 단순하다. 처음에는 분산 컴퓨팅과 조직 설계에서 가져온 시스템을 모델링하려 했다. 하지만 그 모든 것이 에이전트에 그대로 적용되지는 않는다.
적절한 구조의 양은 중간 어디쯤에 있다. 구조가 너무 적으면 에이전트가 충돌하고, 일을 중복하며, 드리프트한다. 구조가 너무 많으면 취약성이 생긴다.
시스템의 동작은 놀랄 만큼 많은 부분이 에이전트를 어떻게 프롬프트하느냐에 달려 있었다. 에이전트가 잘 조율하고, 병적인(pathological) 행동을 피하며, 장기간 집중을 유지하게 하려면 광범위한 실험이 필요했다. 실행 환경(harness)과 모델도 중요하지만, 프롬프트가 더 중요했다.
멀티 에이전트 조율은 여전히 어려운 문제다. 지금 시스템은 작동하지만, 최적과는 거리가 멀다. 기획자는 자신의 작업이 완료되면 다음 단계를 계획하기 위해 깨어나야 한다. 에이전트가 가끔 너무 오래 실행되기도 한다. 우리는 여전히 드리프트와 터널 비전을 막기 위해 주기적인 ‘새로 시작(fresh start)’이 필요하다.
하지만 핵심 질문—문제에 더 많은 에이전트를 투입함으로써 자율 코딩을 확장할 수 있는가—에 대한 답은 우리가 예상했던 것보다 더 낙관적이다. 수백 개의 에이전트가 하나의 코드베이스에서 몇 주 동안 함께 일하며, 야심찬 프로젝트에서 실제 진전을 만들어낼 수 있다.
우리가 여기서 개발하고 있는 기법은 결국 Cursor의 에이전트 기능에 반영될 것이다. AI 보조 소프트웨어 개발에서 가장 어려운 문제를 함께 풀고 싶다면, hiring@cursor.com으로 연락해 달라.