장기간 자율 코딩 확장하기

작성자 Wilson Lin작성일 리서치

우리는 몇 주 동안 코딩 에이전트를 자율적으로 실행하는 실험을 진행해 왔습니다.

우리의 목표는 일반적으로 인간 팀이 수개월에 걸려 완성하는 프로젝트에서 에이전트 코딩을 어디까지 확장할 수 있는지 이해하는 것입니다.

이 글에서는 하나의 프로젝트에서 수백 개의 에이전트를 동시에 실행하고, 작업을 조율하며, 이들이 백만 줄이 넘는 코드와 수조 개의 토큰을 작성하는 과정을 지켜보면서 얻은 인사이트를 공유합니다.

단일 에이전트의 한계

오늘날의 에이전트는 범위가 좁은 작업에는 잘 작동하지만, 복잡한 프로젝트에는 느립니다. 자연스러운 다음 단계는 여러 에이전트를 병렬로 실행하는 것이지만, 이들을 어떻게 조율할지 결정하는 일은 쉽지 않습니다.

처음에는 미리 세부 계획을 세우는 방식이 너무 경직될 것이라고 생각했습니다. 대규모 프로젝트를 진행하는 경로는 모호하고, 작업을 어떻게 나누는 것이 최선인지도 시작 단계에서는 분명하지 않습니다. 그래서 우리는 다른 에이전트들이 현재 무엇을 하고 있는지에 따라 각 에이전트가 스스로 할 일을 결정하는, 동적으로 조율하는 방식부터 시작했습니다.

조율을 배우기

초기 접근 방식에서는 에이전트들에게 동등한 지위를 부여하고, 공유 파일을 통해 스스로 조율하도록 했습니다. 각 에이전트는 다른 에이전트들이 무엇을 하고 있는지 확인하고, 작업을 하나 맡은 뒤 자신의 상태를 업데이트했습니다. 두 에이전트가 같은 작업을 동시에 잡는 것을 막기 위해 락(lock) 메커니즘을 사용했습니다.

이 방식은 여러 흥미로운 방식으로 실패했습니다:

  1. 에이전트가 락을 너무 오래 쥐고 있거나, 아예 해제를 잊어버리곤 했습니다. 락이 제대로 작동하더라도 병목이 되었습니다. 에이전트가 스무 개여도 실제 처리량은 두세 개 수준으로 떨어지고, 대부분의 시간은 대기하는 데 쓰였습니다.

  2. 시스템은 취약했습니다. 에이전트가 락을 쥔 상태에서 실패하거나, 이미 보유한 락을 다시 획득하려 하거나, 아예 락을 획득하지 않고 조율용 파일을 업데이트하기도 했습니다.

우리는 락을 낙관적 동시성 제어로 교체해 보았습니다. 에이전트는 상태를 자유롭게 읽을 수 있지만, 마지막으로 읽은 이후 상태가 변경되었으면 쓰기 작업은 실패하게 했습니다. 이 방식은 더 단순하고 견고했지만, 여전히 더 근본적인 문제가 남아 있었습니다.

위계 구조가 없자 에이전트들은 위험을 회피하게 되었습니다. 어려운 작업을 피하고, 작고 안전한 변경만 수행했습니다. 어떤 에이전트도 어려운 문제나 end-to-end 구현에 책임을 지지 않았습니다. 그 결과, 오랜 시간 동안 실질적인 진전 없이 일만 공회전하는 상황이 발생했습니다.

플래너와 워커

다음으로 시도한 방법은 역할을 분리하는 것이었습니다. 모든 에이전트가 모든 일을 다 하는 단일 계층 구조 대신, 책임이 명확히 구분된 파이프라인을 만들었습니다.

  • **플래너(Planner)**는 코드베이스를 지속적으로 탐색하면서 작업을 만듭니다. 특정 영역에 대해서는 서브 플래너를 생성할 수 있어, 플래닝 자체가 병렬적이면서 재귀적으로 이루어집니다.

  • **워커(Worker)**는 작업을 가져와 이를 완료하는 데만 온전히 집중합니다. 다른 워커와 조율하거나 전체적인 큰 그림을 고민하지 않습니다. 할당된 작업을 끝낼 때까지 몰입한 다음, 변경사항을 푸시하기만 하면 됩니다.

각 사이클이 끝날 때마다 judge 에이전트가 계속 진행할지 여부를 결정하고, 그다음 이터레이션은 초기 상태에서 새로 시작합니다. 이 방식은 대부분의 조율 문제를 해결해 주었고, 어떤 단일 에이전트도 터널 비전(tunnel vision)에 빠지지 않으면서 매우 큰 프로젝트까지 확장할 수 있게 해 주었습니다.

수주간 실행

이 시스템을 테스트하기 위해 우리는 야심 찬 목표를 세웠습니다. 바로 웹 브라우저를 처음부터 직접 만드는 것이었습니다. 에이전트들은 거의 일주일 동안 실행되면서 1,000개 파일에 걸쳐 100만 줄이 넘는 코드를 작성했습니다. GitHub에서 소스 코드를 직접 살펴볼 수 있습니다.

코드베이스 규모에도 불구하고, 새로 생성된 에이전트들도 여전히 이를 이해하고 의미 있는 진전을 낼 수 있습니다. 수백 개의 워커가 동시에 실행되며, 거의 충돌 없이 동일한 브랜치에 푸시합니다.

겉으로는 단순한 스크린샷처럼 보이지만, 브라우저를 처음부터 만드는 일은 극도로 어렵습니다.

또 다른 실험으로는 Cursor 코드베이스에서 Solid를 React로 인플레이스 마이그레이션하는 작업을 진행했습니다. 이 작업은 +266K/-193K 변경과 함께 3주 이상이 걸렸습니다. 아직 면밀한 검토가 필요하지만, CI와 초기 검사를 통과한 상태였습니다.

Solid에서 React로 마이그레이션을 보여주는 PR

또 다른 실험은 곧 출시될 제품을 개선하는 것이었습니다. 장시간 실행되는 에이전트가 효율적인 Rust 버전으로 비디오 렌더링을 25배 빠르게 만들었습니다. 또한 자연스러운 스프링 트랜지션과 모션 블러를 사용해 커서를 따라 매끄럽게 확대 및 이동할 수 있는 기능도 추가했습니다. 이 코드는 이미 병합되었고 곧 프로덕션에 반영될 예정입니다.

현재도 실행 중인 흥미로운 예시가 몇 가지 더 있습니다:

우리가 배운 것

우리는 이러한 에이전트들에 걸쳐 수조 개의 토큰을 단 하나의 목표를 위해 사용해 왔습니다. 시스템이 완전히 효율적인 것은 아니지만, 예상했던 것보다 훨씬 더 효과적입니다.

매우 장시간 실행되는 작업에서는 모델 선택이 중요합니다. 우리는 GPT-5.2 모델이 장시간에 걸친 자율 작업, 즉 지시를 따르고, 집중력을 유지하고, 드리프트(점진적 일탈)를 피하면서, 구현을 정확하고 완전하게 수행하는 데 훨씬 더 뛰어나다는 것을 발견했습니다.

Opus 4.5는 보통 더 일찍 멈추고, 편리할 때 지름길을 택해 빠르게 제어권을 돌려줍니다. 또한 서로 다른 모델이 서로 다른 역할에서 뛰어나다는 것도 알게 되었습니다. GPT-5.2는 GPT-5.1-Codex보다 계획을 세우는 데 더 뛰어난데, 후자가 전적으로 코딩을 위해 학습되었음에도 그렇습니다. 이제 우리는 하나의 범용 모델 대신 각 역할에 가장 적합한 모델을 사용합니다.

많은 개선점은 복잡성을 더하는 것이 아니라 줄이는 과정에서 나왔습니다. 처음에는 품질 관리와 충돌 해결을 위한 integrator 역할을 만들었지만, 이것이 문제를 해결하는 것보다 더 많은 병목을 만든다는 것을 알게 되었습니다. worker들은 이미 스스로 충돌을 처리할 수 있었습니다.

최상의 시스템은 종종 예상보다 더 단순합니다. 우리는 처음에 분산 컴퓨팅과 조직 설계에서 차용한 시스템들을 모델링하려고 했습니다. 하지만 그 모든 것이 에이전트에 잘 작동하는 것은 아니었습니다.

적절한 구조의 수준은 그 중간 어딘가에 있습니다. 구조가 너무 적으면 에이전트들이 서로 충돌하고, 작업을 중복하며, 드리프트가 발생합니다. 구조가 너무 많으면 시스템이 오히려 취약해집니다.

시스템 동작의 놀랄 만큼 많은 부분이 에이전트에게 어떻게 프롬프트를 주느냐에 달려 있습니다. 이들이 잘 협력하고, 비정상적인 행동을 피하며, 장기간에 걸쳐 집중을 유지하게 만들기 위해서는 광범위한 실험이 필요했습니다. 하네스와 모델도 중요하지만, 프롬프트가 더 중요합니다.

앞으로의 방향

다중 에이전트 조정은 여전히 어려운 문제입니다. 현재 시스템은 작동하지만, 최적과는 거리가 있습니다. 플래너는 자신의 작업이 끝나면 다시 활성화되어 다음 단계를 계획해야 합니다. 에이전트는 때때로 지나치게 오랫동안 실행되기도 합니다. 드리프트와 터널 비전을 막기 위해서는 여전히 주기적인 초기화가 필요합니다.

하지만 ‘문제에 더 많은 에이전트를 투입하는 방식으로 자율 코딩을 확장할 수 있는가?’라는 핵심 질문에는 우리가 예상했던 것보다 더 낙관적인 답을 얻었습니다. 수백 개의 에이전트가 몇 주 동안 하나의 코드베이스에서 함께 일하며, 야심 찬 프로젝트에서 실제로 의미 있는 진전을 이룰 수 있습니다.

우리가 여기서 개발하고 있는 기술은 궁극적으로 Cursor의 에이전트 기능을 고도화하는 데 활용될 것입니다. AI 지원 소프트웨어 개발에서 가장 어려운 문제를 함께 풀어 가는 데 관심이 있다면, hiring@cursor.com으로 연락을 기다리고 있겠습니다.

장기간 자율 코딩 확장하기 · Cursor