Cursor의 SQLite Rust 실험을 통해 배울 수 있는 것들

MMaximilian Schwarzmüller
Computing/SoftwareInternet Technology

Transcript

00:00:00SQLite가 Rust로 재작성되었습니다.
00:00:02최근 Bun도 Rust로 재작성되었는데
00:00:04왜 다들 모든 것을 Rust로
00:00:06재작성하는지 궁금해하실 수 있지만, 이건 Rust에 관한 이야기가 아닙니다.
00:00:09SQLite에 관한 이야기조차 아닙니다.
00:00:11이미 Rust 기반으로 SQLite를
00:00:15현대화하여 재구현한
00:00:18Turso 데이터베이스가 있다는 건 알고 있습니다.
00:00:19상용 환경에 바로 적용할 수 있는
00:00:21Rust 기반 SQLite 데이터베이스를
00:00:23찾으신다면 그걸 사용하시면 됩니다.
00:00:26대신, 아래 링크에서 확인해 보실 수 있는
00:00:29'mini SQLite'라는 이 실험은
00:00:32SQLite나 Rust에 관한 것이 아닙니다.
00:00:34대신 Cursor 팀이 진행한 실험으로,
00:00:37에이전트 스웜(Agent Swarm) 및 AI 에이전트
00:00:40시스템 구축, 그리고 문서만으로 SQLite 같은 것을
00:00:44만들어낼 수 있는 조합과 그렇지 않은 조합을
00:00:47파악하는 것에 관한 내용입니다.
00:00:51이 실험의 핵심이 바로 그것이기 때문이죠.
00:00:53매우 상세하고 흥미로운 블로그 포스트가 하나 있어서
00:00:56한번 자세히 살펴보겠습니다.
00:00:57거기엔 우리가 이야기해 볼 만한 흥미로운 인사이트가
00:00:59많이 담겨 있으며, 링크도 아래에 남겨두었습니다.
00:01:02그 글에서는 이 실험을 어떻게 진행했는지 설명하는데, 출발점이자
00:01:07아이디어는 SQLite 문서를 그대로 활용하는 것이었습니다.
00:01:12한 문서로 합치면 무려 835페이지에 달하는 분량이죠.
00:01:18물론 이 문서는 기본적으로 사람을 위해 작성된 것입니다.
00:01:23가장 읽기 쉬운 문서라고 할 수는 없지만,
00:01:27AI 에이전트 개념보다 훨씬 이전에 나왔으니 당연히 사람을 위한 것이겠죠.
00:01:32그럼에도 불구하고 이 문서는 일종의 초정밀 명세서 역할도 합니다.
00:01:37SQLite 사용법과 의도된 동작,
00:01:43의도된 기능들이 상세히 기술되어 있기 때문입니다.
00:01:48Cursor 팀은 이 문서와 함께
00:01:52공개 테스트 세트인 SQLogicTest를 가져왔습니다.
00:01:57이는 SQLite의 동작이나 특히 쿼리를
00:02:02검증하는 수많은 테스트의 집합입니다.
00:02:05그리고 에이전트들이 그 문서를 바탕으로 구축한 구현체가
00:02:13이 대규모 공식 테스트 슈트에서 실제로 잘 작동하는지 확인하는 데 사용했습니다.
00:02:19먼저 몇 가지 중요한 주의 사항을 말씀드리겠습니다.
00:02:23이 테스트 슈트는 쿼리와 쿼리 동작을 검증하는 데 집중되어 있습니다.
00:02:29SQLite가 가진 모든 기능과 역량을 전부 테스트하지는 않습니다.
00:02:35전반적인 성능을 테스트하는 것도 아닙니다.
00:02:38동시성(Concurrency)도 테스트하지 않습니다.
00:02:40SQLite에는 이 테스트 슈트가 검증하지 않는 요소가 아주 많습니다.
00:02:44그리고 이 실험의 결과물 중 하나인 mini SQLite는
00:02:49실제로 다양한 에이전트 조합으로 SQLite를 여러 번 재구축한 것입니다.
00:02:53자세히 살펴보겠지만, 이건 탐구 목적으로 만들어진 것일 뿐입니다.
00:02:57실제 상용 환경용이 아닙니다.
00:02:59실제 서비스에 쓸 물건이 아닙니다.
00:03:01단지 문서를 활용해 SQLite를 재구축하고,
00:03:06재구축한 버전이 해당 테스트를 모두 통과하도록 하는 실험의 결과물일 뿐입니다.
00:03:13Cursor 팀은 여기서 다양한 모델 조합을 사용했습니다.
00:03:17왜 조합일까요?
00:03:18뒤에서 살펴보겠지만,
00:03:21기획자(Planner), 작업자(Worker), 검수자(Reviewer) 에이전트가 협업하는 방식을 사용했기 때문입니다.
00:03:28그들은 다양한 조합으로 SQLite 데이터베이스를 재구축한 뒤, 비등한 품질이 나오는지 측정했습니다.
00:03:37이 조합들은 모두 동일한 수준의 품질과 테스트 통과율을 달성했지만, 비용 차이를 측정해 보았습니다.
00:03:45예를 들어, 기획자와 작업자 에이전트 모두에 GPT-5.5를 사용했을 때는 문서를 기반으로 Rust로 SQLite를 구현하는 데 약 10,000달러가 들었습니다.
00:03:59반면, Opus 4.8과 초고속·초저가에 매우 효율적이지만 최고 지능 수준은 아닌 Cursor의 Composer 2.5를 조합했을 때는 비용이 단 1,300달러밖에 들지 않으면서도 다른 조합과 동일한 품질 및 테스트 통과율을 달성했습니다.
00:04:24핵심 아이디어는 더 뛰어난 모델인 Opus 4.8을 기획 및 작업 설계에 활용하고, 이를 Composer 2.5를 사용하는 작업자 에이전트에게 전달하는 것이었습니다.
00:04:39그리고 이것이 이 아티클이 주는 중요한 시사점 중 하나입니다. 완전히 새로운 개념은 아니지만요.
00:04:44소프트웨어를 개발할 때 직접 적용해 볼 수도 있습니다.
00:04:47작업 복잡도에 따라 작업을 나눈 뒤, 서브 에이전트를 활용해 기획에 집중하는 에이전트와
00:05:03전체 작업 중 세부 작업을 설계하는 개별 직무용 에이전트를 두고, 이를 구현하는 다수의 에이전트를 배치하는 것은 좋은 방법입니다.
00:05:14맥락(Context)만 잘 제공된다면, 뛰어난 코드를 뽑아내는 데 반드시 최고 성능의 지능이 필요하지는 않다는 것이 밝혀졌기 때문입니다.
00:05:24작업이 명확히 정의되고 필요한 정보가 작업 설명에 모두 들어 있다면 말이죠. 물론 다른 요인들도 영향을 미칠 수 있습니다.
00:05:33예를 들어 주변 코드베이스의 구조나 에이전트에 제공하는 예시 코드의 형태 등이 영향을 줍니다.
00:05:39이 모든 것이 결과물에 영향을 주지만, 작업 명세가 명확하고 맥락이 충분하다면 코드를 작성하는 작업자 에이전트는 수가 많아도 괜찮습니다.
00:05:49이번 실험의 대부분은 바로 이 점에 관한 것이었습니다.
00:05:52이정도 규모의 작업을 처리할 수 있는 시스템을 어떻게 설계할 것인가 하는 점이죠.
00:05:57앞서 말씀드렸듯, 여러분의 프로젝트에서도 기획자+작업자 에이전트 구조를 고려해 볼 만합니다.
00:06:07물론 모든 작업에 다 필요한 것은 아닙니다.
00:06:10간단한 버그 수정이나 매우 단순한 작업이라면 에이전트(Codex, Claude Code 등 무엇이든)에게 바로 말해도 충분합니다.
00:06:19“이런 문제가 있어.”
00:06:20“이걸 구현해 줘.”
00:06:21추가 맥락을 제공하고 일을 맡기면 됩니다.
00:06:24코딩 에이전트 하네스에 따라 서브 에이전트를 자체적으로 실행할 수도 있습니다.
00:06:28Claude Code는 그렇게 할 수도 있습니다.
00:06:31Pi 같은 다른 하네스는 적절한 확장 기능을 주지 않으면 실행하지 않을 수도 있습니다.
00:06:36하지만 서브 에이전트 없이 단일 에이전트만으로도 많은 작업을 문제없이 해결할 수 있습니다.
00:06:43더 복잡한 프로젝트나 복잡한 작업의 경우, 검수자 에이전트를 포함해 역할을 분할하는 것이 유용할 수 있습니다.
00:06:51저 역시 개인적으로 선호하는 방식입니다.
00:06:54이 역시 작업의 복잡도에 따라 달라지겠지만요.
00:06:56역할을 분할하는 접근법은 실제로 아주 잘 작동합니다.
00:06:59물론 이것 자체가 엄청나게 획기적인 신기술은 아닙니다.
00:07:02새로운 점은 이번 SQLite 재작성과 같은 작업에서 기획자, 작업자, 검수자 에이전트의 병렬 프로세스가 여러 개 작동하며, 작업자뿐만 아니라 기획자와 검수자도 여럿 존재한다는 것입니다.
00:07:18그리고 그들은 끊임없이 충돌합니다.
00:07:19Cursor 팀이 결국 알아낸 사실이 바로 이것입니다.
00:07:22매우 흥미로운 이 블로그 포스트에서
00:07:26그들은 올해 초 에이전트 하네스를 사용해 웹 브라우저를 처음부터 구축했던 실험을 언급합니다.
00:07:33그리고 이번 SQLite 재작성에도 동일한 하네스, 아니 에이전트 시스템을 사용했습니다.
00:07:40동시에 지금까지의 경험에서 얻은 인사이트를 바탕으로 새로운 시스템을 구축하여 실험했습니다.
00:07:47이 실험과 블로그 포스트를 통해 다양한 접근법을 비교하고, SQLite를 재구축하는 시스템을 설정 및 운영하면서 직면한 제반 과제들을 깊이 있게 다룹니다.
00:07:59수백, 수천 명의 작업자가 동시에 작업하는 시스템을 다룰 때 직면한 첫 번째 과제 중 하나는 전통적인 버전 관리 시스템인 Git이 더 이상 제 역할을 못 한다는 점이었습니다.
00:08:13스웜에 관한 이전 포스트에서 언급했듯, Git이나 Cargo 같은 도구는 동시성 제어를 위해 거친 잠금(Coarse Locks)에 의존하므로 동일한 데이터에 여러 작업자가 동시에 쓸 수 없습니다.
00:08:30단일 개발자에게는 괜찮지만, 수백 명의 동시 에이전트가 쏟아내는 작업량을 처리하기엔 불가능합니다.
00:08:36올해 초 브라우저 스웜은 시간당 약 1,000건의 커밋을 기록했습니다.
00:08:41그게 브라우저를 재구축한 스웜이었습니다.
00:08:45이번 실험을 위해 설계한 새 시스템은 초당 약 1,000건의 커밋을 기록합니다.
00:08:52올해 초 운영했던 기존 스웜은 시간당 1,000건의 커밋을 기록했는데, 이 역시 보통 사람보다는 훨씬 많은 수치입니다.
00:09:02하지만 새 시스템은 초당 약 1,000건의 커밋을 생성하며, 이는 엄청난 수치이자 명백히 Git이 감당하도록 설계된 범주를 벗어납니다.
00:09:14당연한 결과죠.
00:09:15이러한 작업 속도를 지원하기 위해 완전히 새로운 버전 관리 시스템을 처음부터 구축했습니다.
00:09:21처리량만이 이 레이어를 직접 만든 유일한 이유는 아니었습니다.
00:09:25시스템의 모든 변경 사항은 버전 관리 시스템을 통과합니다.
00:09:29따라서 충돌이 가장 먼저 가시화되는 지점입니다.
00:09:31다음 섹션에서 설명할 여러 조율 메커니즘도 내부에서 직접 구현되었습니다.
00:09:37정말 흥미로운 대목입니다.
00:09:39AI 에이전트 시대를 위한 새로운 버전 관리 시스템을 만든 것입니다.
00:09:43우리 모두가 사용하는 기존 Git에 문제가 있다는 뜻은 아닙니다.
00:09:48오해는 마시고요.
00:09:49우리 대부분이 당장은 마주하지 않을 규모와 작업 수준의 실험을 이야기하는 것입니다.
00:09:57그럼에도 기존 시스템인 Git은 수백 개의 에이전트와 주체가 동일한 코드에서 동시에 작업하는 상황을 고려해 만들어지지 않았습니다.
00:10:07그래서 엄청나게 높은 동시성을 처리할 뿐만 아니라 에이전트를 통한 충돌 해결까지 지원하는 새 버전 관리 시스템을 구축했습니다.
00:10:19파일 내 동일한 코드를 두 변경 사항이 건드릴 때 충돌이 드러나는 곳이 바로 버전 관리 시스템이기 때문입니다.
00:10:28이것이 첫 번째 중요한 포인트입니다.
00:10:30실험을 효율적으로 진행하고 수행하기 위해 완전히 새로운 버전 관리 시스템을 구축했습니다.
00:10:37언급했듯, 초당 1,000건의 커밋이 일어나는 규모와 변경 속도에서는 자연스럽게 수많은 문제가 발생했습니다.
00:10:48직면한 문제들과 그 해결책은 향후 소프트웨어 공학이 어떤 모습일지 보여주기에 매우 흥미롭습니다.
00:11:01바로 '분할 뇌(Split-Brain) 설계 문제'입니다.
00:11:03두 기획자가 서로를 인지하지 못한 채 코드베이스의 다른 위치에 동일한 개념을 서로 다른 방식으로 구현하는 현상입니다.
00:11:10즉, 다른 위치에서 동일한 개념이 다르게 중복 구현되는 문제입니다.
00:11:16보통은 이를 추출해서 로직을 재사용하고 싶겠죠?
00:11:21우리는 프롬프팅을 통해 이를 해결했습니다.
00:11:24복잡한 시스템을 새로 만든 게 아니라 프롬프팅으로 해결한 것입니다.
00:11:28기획자 에이전트가 결정을 하위로 위임하지 않고 직접 내리도록 했습니다.
00:11:34그리고 위임된 두 하위 트리가 동일한 문제에 대해 중복 결정을 내리지 않도록 강제했습니다.
00:11:39결국 설정의 문제입니다.
00:11:40시스템을 기획자, 작업자 등으로 나눌 때, 병렬 작업자뿐만 아니라 병렬 기획자들의 작업 영역이 충돌하거나 겹치지 않도록 명확히 정의하는 것이 핵심입니다.
00:12:02따라서 이는 당연히 인간의 설계 작업에서부터 시작됩니다.
00:12:08작업을 구성하고 프롬프트하는 방식 말이죠.
00:12:11“프롬프팅을 통해 해결했다”는 것처럼요.
00:12:13에이전트 트리가 수많은 병렬 노드와 리프로 분가할 때, 하위 작업을 분할하는 에이전트들이 겹칠 확률이 적은 방향으로 작업을 나누도록 프롬프트를 구성해야 합니다.
00:12:34결국 인간 입장에서 시스템을 올바르게 구축하는 기획 과제인 셈입니다.
00:12:43이것이 그들이 이 문제를 해결하고 다룬 방식입니다.
00:12:47그들이 직면한 또 다른 문제는 기획자 간의 경합이었습니다.
00:12:51더 까다로운 형태의 경합은 두 기획자가 서로를 인지한 상태에서 동일한 파일을 두고 수정 작업을 번복하며 다투는 경우입니다.
00:12:59문제는 서로 다른 두 상이 존재할 때 병합 도구만으로는 의견 대립을 해결할 수 없다는 점입니다.
00:13:04대신 에이전트가 공유 설계 문서에 결정 사항을 기록하도록 했습니다.
00:13:08특정 결정에 의존하는 코드는 해당 문서로 역참조되는 컴파일 검사 참조를 가집니다.
00:13:13기획자들이 모르는 사이에 상충할 때, 화해자(Reconciler)가 문서를 병합하고 참조를 통해 해결책을 하류로 전파합니다.
00:13:21이전 포인트와 연관해서, 기획자들에게 작업을 분할하더라도 소프트웨어 개발 특성상 코드베이스 내에서 기획자와 작업자가 건드려야 하는 공통 영역이나 로직의 중복을 완전히 피할 수는 없습니다.
00:13:43기획자 에이전트들이 특정 구현을 두고 다투기 시작할 때, 기획자들이 작성한 문서를 병합해 주는 조정자(Reconciler) 에이전트를 도입하여 해결했습니다.
00:13:59작업자들에게 전달하기 위해 작성된 문서들이었죠.
00:14:02대립하는 기획자 에이전트들의 문서를 병합하는 조정 단계를 중간에 두어, 일관된 언어를 사용하고 단일 구현에 합의하도록 함으로써 코드베이스의 여러 곳에서 동일한 기능이 다르게 재구현되는 상황을 방지했습니다.
00:14:21제가 이해하기로 이 두 가지가 함께 작동합니다.
00:14:24당연하게도 머지 충돌(Merge Conflict)도 발생했습니다.
00:14:29기획 단계에서 중복을 최소화하고 일관된 언어를 쓰도록 보장하는 것이 첫 번째 중요 단계입니다.
00:14:38하지만 하나의 계획을 바탕으로 일하는 여러 작업자가 존재하는 이상, 동일한 파일을 건드려 서로 충돌할 가능성은 매우 높습니다.
00:14:50서로 동일한 파일에서 작업하지 않도록 조율하는 작업자들도 많습니다.
00:14:55그렇기 때문에 동일한 파일에서 작업하지 않으려는 것이죠.
00:14:57동일한 파일에서 작업하지 않는 이유입니다.
00:14:58충돌을 해결하려면 작업을 멈추고 상대 에이전트의 맥락을 흡수한 뒤 병합해야 합니다.
00:15:03두 에이전트나 두 사람이 동일한 파일에서 작업할 때 충돌을 해결하려면, 에이전트든 사람이든 일단 멈추고 판단을 내려야 합니다.
00:15:19충돌을 해결할 구현 방식을 찾아야 하죠.
00:15:23하지만 작업자 에이전트는 이 작업에 취약해서, 상대의 변경 사항을 덮어쓰거나 자신의 작업을 포기해 버립니다.
00:15:29여러분도 이런 경험이 있으실지 모르겠습니다.
00:15:31저는 확실히 겪어봤습니다.
00:15:32하나 이상의 AI 에이전트와 함께 코드베이스에서 작업하면서 코드를 변경할 때 말이죠.
00:15:38무섭게 들릴지 모르지만 직접 코드를 작성할 때 이야기입니다.
00:15:40내가 코드를 수정했다고 가정해 봅시다.
00:15:42코드의 특정 부분을 수정하면
00:15:44에이전트는 그 변경을 취소하고 그냥 덮어버리곤 합니다.
00:15:48수정 사항을 존중하지 않는 거죠.
00:15:50에이전트에겐 할 일이 정해져 있으니까요.
00:15:52해당 파일을 수정해야 한다고 판단하면 그대로 진행해 버립니다.
00:15:57그 사이에 작업자가 코드를 수정했는지 여부는 신경 쓰지 않습니다.
00:16:01커밋된 변경 사항이라면 상황이 조금 다릅니다. 에이전트들이 커밋을 쉽게 되돌리지 않도록 후속 학습(Post-training) 및 미세조정되어 있기 때문입니다.
00:16:13하지만 커밋되지 않은 변경 사항이라면 작업자 에이전트는 전혀 신경 쓰지 않습니다.
00:16:17에이전트는 개의치 않는 거죠.
00:16:19여기서도 정확히 동일한 문제가 발생했습니다.
00:16:21이를 해결하기 위해 머지 충돌 시 중립적인 제3자 에이전트가 개입하여 모두를 대신해 충돌을 해결하는 시스템을 만들었습니다.
00:16:29엔지니어링 팀의 머지 큐(Merge Queue)와 유사하게, 공정하고 효율적인 대안을 찾는 것이 유일한 목표입니다.
00:16:35이 부분 역시 매우 흥미롭습니다.
00:16:38이 역시 일종의 화해/조정 과정입니다.
00:16:41잠시 멈춰 서서 한 걸음 물러나 충돌 해결책을 찾던 과거 방식처럼,
00:16:49에이전트들을 일단 멈추게 하는 방식입니다.
00:16:51이 사례가 명확히 보여주는 점은(새로운 사실은 아니지만), 적절한 맥락이 제공된 깨끗한 컨텍스트(Fresh Context)가 매우 중요하다는 것입니다.
00:17:03Cursor 팀처럼 거대한 규모의 과제를 수행하든, 소규모 프로젝트를 진행하든 간에
00:17:12기획자, 작업자, 검수자 에이전트로 역할을 나누는 것의 가장 큰 장점은 정돈된 컨텍스트 윈도우를 사용할 수 있다는 점입니다.
00:17:24컨텍스트 윈도우가 비어 있다는 뜻은 아닙니다.
00:17:26해당 작업에 꼭 필요한 정확한 맥락으로 채워진 새로 시작된 에이전트 세션을 의미합니다.
00:17:33예를 들어 작업자 에이전트는 자신이 구현할 때 사용한 맥락이 윈도우에 남아있어 자기 작업을 검수하는 데 취약합니다.
00:17:41일종의 편향(Bias)이 생기는 것이죠.
00:17:44따라서 검수자 에이전트는 깨끗한 컨텍스트 윈도우에서 시작하여, 작업자의 작업 내용, 계획, 수정된 파일 정보만 전달받아야 합니다.
00:17:55그래야 객관적으로 결과를 검수할 수 있기 때문입니다.
00:17:59이것이 바로 올바른 맥락으로 채워진 깨끗한 컨텍스트 윈도우가 중요한 이유입니다.
00:18:04마찬가지로 여기서도 편향 없는 새로운 에이전트에 꼭 필요한 맥락만 제공하여 머지 충돌을 해결했습니다.
00:18:17이후 기존 작업자 에이전트들에게 충돌 해결 정보를 전달해 덮어쓰지 못하게 하거나, 새로운 작업자 에이전트를 시작하도록 시스템을 구성했을 것입니다.
00:18:30이 부분의 전말이 완전히 명시되어 있지는 않네요.
00:18:32그들이 직면한 또 다른 문제는 '메가 파일(Mega Files)'이었습니다.
00:18:35일부 파일은 에이전트들이 작업하기 위해 자주 찾는 위치가 됩니다.
00:18:39각 에이전트는 소량의 코드만 추가할 뿐, 파일 크기를 작게 유지할 책임을 지는 에이전트는 없습니다.
00:18:45이 이러한 메가 파일들은 전체 시스템의 병목이 됩니다.
00:18:49전송, Diff 연산, 머지에 많은 비용이 들고 지속적인 충돌의 발상지가 됩니다.
00:18:54이 역시 비록 훨씬 작은 규모일지라도 한 번쯤 경험해 보셨을 법한 현상입니다.
00:19:00저도 분명 겪어봤습니다.
00:19:01우리가 겪는 일 중 하나죠.
00:19:02특히 테스트 작성 시에 그렇죠.
00:19:03제 경험상 에이전트들은 같은 파일에 계속 테스트를 추가하는 걸 좋아합니다.
00:19:08테스트뿐만은 아니지만, 자주 목격되는 영역 중 하나죠.
00:19:13특히 여러 에이전트가 작업 중이고 각자 해야 할 일 목록이 있을 때 더 그렇습니다.
00:19:18사람이 아니니까 신경 쓰지 않거든요.
00:19:21무언가를 신경 쓸 이유가 없죠.
00:19:23그저 주어진 작업만 수행할 뿐이니까요.
00:19:24파일 크기나 시스템의 전체적인 아키텍처는 안중에 없습니다.
00:19:30에이전트들이 작업만 실행하게 방치하면 어느 순간 코드베이스가 혼돈에 빠지게 됩니다.
00:19:37에이전트는 개의치 않기 때문이죠.
00:19:39자기 작업을 처리하는 데만 신경 씁니다.
00:19:42그리고 이런 메가 파일은 문제의 명확한 지표입니다.
00:19:48더 많은 에이전트가 오랜 기간 작업할수록 메가 파일이 생겨나게 됩니다.
00:19:55파일을 분할하거나 코드베이스 구조를 잘 유지할 책임이 있는 에이전트는 없기 때문이죠.
00:20:02그건 자기들 목적이 아니니까요.
00:20:04그래서 이를 해결하고자 작업 에이전트에게 비대해진 파일을 표시(flag)하는 기능을 주었습니다.
00:20:09표시가 되면 새 커밋을 차단하고 별도의 에이전트가 비대해진 파일을 작은 모듈로 분해합니다.
00:20:16즉, 또 다른 새로운 에이전트가 투입되는 거죠.
00:20:19여기서도 반복적인 패턴이 보입니다.
00:20:21이 모든 문제는 문제를 식별한 뒤 적절한 작업과
00:20:28적절한 컨텍스트가 부여된 새 에이전트를 투입해 문제를 해결하고, 다른 에이전트들이 작업을 이어가도록 하는 방식이었습니다.
00:20:35메가 파일 문제 역시 마찬가지입니다.
00:20:38'골화(Ossification)' 문제도 직면했습니다.
00:20:40에이전트들은 사람이 참여하는 기존 코드베이스에서 작업하면서
00:20:44핵심 코드는 변경이 필요하더라도 건드리지 않도록 학습되었습니다.
00:20:48제가 이전에 말했던 것과는 다릅니다.
00:20:50에이전트가 작업 중인 파일을 수정했을 때 그걸 그냥 버려버리는 상황이 아니라,
00:20:55일반적인 상황에 관한 것입니다.
00:20:57에이전트는 전달받은 프롬프트와 계획을 바탕으로 한 명확한 작업목표가 있습니다.
00:21:03당연히 특정 파일의 변경도 포함되죠.
00:21:07에이전트와 작업하며 매일 느끼는 점 중 하나는 모델에 따라
00:21:16기존 코드를 지우거나 바꾸는 것을 엄청 주저하는 모델들이 있다는 것입니다.
00:21:21코드를 삭제하고 정리하는 대신 10개의 폴백과 10개의 if 조건문, 레거시 코드를 계속 쌓아두려 하죠.
00:21:31에이전트가 함수를 확실히 삭제하거나 코드 파일을 없애도록 하려면 명시적으로 프롬프트를 작성해야 합니다.
00:21:39파인튜닝 때문에 스스로 그렇게 하지는 않습니다. 모델 제약사들이 제멋대로 작동하며
00:21:47온갖 프로덕션 코드를 망가뜨리는 모델을 만들고 싶어 하지 않으니까요.
00:21:50하지만 신규 프로젝트가 아니거나 실제로 서비스 중인 기존 코드베이스에서 작업하는 게 아니라면,
00:21:57코드를 건드리지 않고 영원히 보존하려는 이러한 성향은 매우 문제가 되고 짜증 날 수 있습니다.
00:22:05또한 에이전트들이 다른 에이전트가 작성한 코드를 개선하려 하지 않고
00:22:16그 위에 계속 덧붙이기만 해서 결국 코드베이스가 비대해지는 부작용을 낳기도 했습니다.
00:22:23이를 해결하기 위해 '의도적인 파괴' 권한을 허용했습니다.
00:22:27핵심 변경이 가치 있다고 판단한 에이전트는 범위 밖의 수정 패치를 적용하고 사유를 주석으로 남길 수 있습니다.
00:22:36이것 역시 여러분의 프로젝트에 더 작은 규모로 적용해 볼 수 있는 방법입니다.
00:22:41에이전트에게 “이건 초기 개발 단계이고
00:22:46아직 배포되지 않았다.
00:22:48아직 라이브 상태가 아니니
00:22:49호환성을 깨는 파괴적인 변경도 괜찮다.
00:22:51코드를 과감하게 정리해라.
00:22:54리팩토링도 환영한다”라고
00:22:56명시적으로 권한을 부여하는 것이죠.
00:22:58AI 모델의 기본 파인튜닝 지침을 덮어써서 에이전트를 격려하고,
00:23:04단순히 코드를 덧붙이는 대신 코드베이스를 진정으로 발전시킬 수 있도록 지침을 해제해야 합니다.
00:23:14작은 규모에서도 볼 수 있는 현상이 대규모 사례에서 잘 드러난 셈입니다.
00:23:19검토(Review) 방식으로는 '리뷰 렌즈(Review lenses)'라는 접근법을 사용했습니다.
00:23:24기획자 및 작업자 에이전트가 있지만, 특정 버그가 수정되거나 코드베이스가 개선될 때까지 검토 작업을 진행해 후속 과제를 생성하고 루프를 다시 시작해야 합니다.
00:23:38장시간 실행되는 멀티 에이전트 시스템에서는 오류가 누적되므로, 사소한 실수들이 굳어지기 전에 에이전트 군집 스스로 교정할 수단이 필요합니다.
00:23:47충분히 납득이 가는 부분입니다.
00:23:48작은 규모에서 우리도 모두 경험해 본 일이죠.
00:23:50리뷰 에이전트에게 작업자의 전체 기록을 주거나, 결과물만 주거나, 코드베이스만 주는 등 다양한 리뷰 렌즈를 실험했습니다.
00:24:00서로 다른 학습 내용과 페르소나를 가진 다양한 모델에서 검토를 진행해 보기도 했습니다.
00:24:05단 하나의 렌즈가 모든 것을 잡아낼 수는 없지만, 서로 연결된 렌즈들을 쌓아 올림으로써 자율주행 시스템처럼 완벽한 단일 부품 없이도 인간 이상의 신뢰도에 도달할 수 있었습니다.
00:24:16리뷰는 감수하는 작업에 비해 훨씬 비용이 적게 들기 때문에 리뷰에 투입되는 컴퓨팅 자원은 수익성이 매우 높습니다.
00:24:21이 스택형 리뷰 시스템이 지속적인 실행 품질 유지에 결정적인 역할을 했다고 봅니다.
00:24:28핵심 시사점은 다음과 같습니다.
00:24:30하나 이상의 리뷰어 에이전트가 코드베이스 전체를 검토하게 하는 것은 불가능하다는 것입니다.
00:24:39양량이 너무 많기 때문이죠.
00:24:41대신, 전체 대화 기록을 주거나 결과만 주거나 코드베이스만 주는 등 다양한 방식을 실험했습니다.
00:24:47그리고 결국 도움을 준 것은 서로 다른 관점(렌즈)과 페르소나를 가진 여러 리뷰어를 두어 각각 다른 요소에 집중하게 만드는 것이었습니다.
00:25:00코드베이스와 함께 작업자가 수행한 작업에 대한 일부 정보를 제공하는 방식이었던 것으로 이해됩니다.
00:25:06결과적으로 여러 리뷰어의 출력을 결합하여 종합적인 리뷰 결과를 만들어내고, 기획자가 이를 바탕으로 다시 계획을 세워 작업자가 코드를 수정하게 했습니다.
00:25:23더 작은 규모의 프로젝트에서도 이러한 접근 방식을 바로 적용해 볼 수 있습니다.
00:25:28물론, 우리는 그 정도로 거대한 시스템을 만드는 것은 아닙니다.
00:25:34하지만 제 경험상 각자 다른 역할을 부여받은 여러 리뷰어 에이전트를 두는 게 아주 효과적이었습니다. 한 에이전트는 “이것이 관용적인 Rust 코드인가?”에 집중하고,
00:25:46또 다른 검토자는 성능이나 보안 문제에 집중할 수 있죠.
00:25:51또 다른 리뷰어는 네이밍 컨벤션 같은 요소에 집중하게 설정할 수 있습니다.
00:25:58이처럼 각기 다른 렌즈를 부여하고 해당 리뷰어에게 딱 필요한 컨텍스트만 제공하는 겁니다.
00:26:03“작업자가 해당 기능을 구현했다”는 식의 정보 말이죠.
00:26:07작업자의 계획이나 거친 작업 단계 정보 정도만 주고 그 이상은 주지 않는 식입니다.
00:26:15그 후 여러 리뷰어의 결과를 모아 또 다른 리뷰어를 통해 취합 및 종합할 수 있습니다.
00:26:22개인적으로 선호하는 방식은 리뷰 결과 자체를 재검토하는 리뷰어를 두는 것인데, 모델들이 무언가를 지적하고 싶어 하는 경향이 있기 때문입니다.
00:26:36어떤 코드를 건네든 한 줄짜리 코드라 하더라도,
00:26:40거기서 5개쯤 문제를 찾아내는 것처럼 느껴질 때가 있습니다.
00:26:43따라서 지적된 리뷰 항목을 분류하고 실제 문제가 아닌 지적 사항은 걸러내는 리뷰어를 두는 편이 제 경험상 꽤 잘 작동했습니다.
00:26:55글에서 언급되었듯 이러한 리뷰어의 조합, 스택형 리뷰 구조가 훌륭한 결과물을 만들어내고 이를 바탕으로 다시 구현 작업을 진행할 수 있게 돕습니다.
00:27:06물론 이는 만드는 소프트웨어나 작업의 규모에 따라 달라집니다.
00:27:11대부분의 일반 소프트웨어 개발에는 이러한 구조가 지나치게 복잡하지만, 미래의 소프트웨어 엔지니어링 및 시스템 구조를 엿볼 수 있어 개인적으로 매우 흥미로웠습니다.
00:27:27마지막으로 에이전트가 직접 환경을 조성하게 만든 점도 있습니다.
00:27:32에이전트들에게 '필드 가이드(문서 지침서)'를 작성하도록 한 아이디어인데, 전체 작업의 컨텍스트 역할을 해야 한다는 지침 외에는 아무런 제약을 주지 않았습니다. 에이전트들이 발견한 핵심 문제나 교훈 등을 기록하며 일종의 공유 메모리 시스템을 형성하게 한 것입니다.
00:28:00에이전트가 메모를 남기고 결정 사항을 문서화할 수 있는 추가 메모리 시스템을 구축해 준 셈입니다.
00:28:10Bun을 Rust로 재작성한 실험처럼, 전반적으로 이번 실험은 매우 흥미로웠습니다.
00:28:16한편으로는 섬뜩하게 느껴질 수도 있죠.
00:28:17어떤 기분인지 충분히 이해합니다.
00:28:18그그렇다고 앞으로 모든 소프트웨어를 이런 방식으로 개발해야 한다고 단정 지어서는 안 됩니다.
00:28:24우선 이 결과물이 실제 상용화 가능한 수준의 소프트웨어가 아니기 때문입니다.
00:28:28실제 상용화 단계까지 완성도를 올리려면 상당한 시간이 더 소요될 것입니다.
00:28:33이 점을 간과해서는 안 됩니다.
00:28:35몇 시간 만에 이런 형태를 만들었다고 해서 상용화까지 몇 시간밖에 안 남았다는 뜻은 아닙니다.
00:28:43초반 80%를 완성하는 것이 나머지 20%를 채우는 것보다 훨씬 빠르기 마련입니다.
00:28:48우리 모두 잘 알고 있는 사실이죠.
00:28:49따라서 이 점을 기억하는 것이 중요합니다.
00:28:51또한 SQLite 재작성이라는 특수한 과제의 경우, 공식 문서와 테스트 수트만 제공받았다고는 하지만,
00:29:04신규 프로젝트에서는 얻기 힘들 만큼 엄청나게 상세한 명세가 사전에 존재했다는 점을 알아야 합니다.
00:29:13새로운 소프트웨어를 만들 때는 20년 이상 쌓인 문서처럼 정교한 사양서를 가질 수 없습니다.
00:29:24또한 에이전트에 공식 문서만 제공되었더라도, SQLite 소스 코드 및 Turso의 Rust 재구현체 같은 자료들은 이미 실험에 사용된 AI 모델 대부분의 학습 데이터에 포함되어 있었을 가능성이 매우 높습니다.
00:29:46즉, 모델 입장에서 완전히 새로운 작업은 아니었다는 의미입니다.
00:29:51지속적인 수정과 피드백이 핵심인 완전히 새로운 소프트웨어를 밑바닥부터 개발하는 것과는 다릅니다.
00:29:58새로운 소프트웨어가 무엇이든, 지속적인 변경 없이 처음부터 끝까지 만들어내는 것은 극도로 어려우며 불가능에 가깝다고 봅니다.
00:30:11초기에 완벽한 사양서를 작성해 한 번에 끝내는 것은 불가능하기 때문입니다.
00:30:17규모와 상관없이 무언가를 구축하는 과정에서는 항상 새로운 요소를 발견하거나 변경하고 싶은 부분이 생깁니다.
00:30:26따라서 이번 실험 결과를 일반적인 소프트웨어 개발 방식으로 일반화할 수는 없습니다.
00:30:34그럼에도 불구하고 매우 매력적인 실험임은 틀림없습니다.
00:30:37매우 흥미로운 실험이며 우리 모두에게 중요한 시사점을 던져줍니다.
00:30:43작업 분할이나 명확한 컨텍스트 창 확보처럼 아주 새로운 개념은 아니지만 유용한 가르침을 줍니다.
00:30:50향후 새로운 버전 관리 시스템이 필요해지고 등장할 것이라는 흥미로운 통찰도 보여줍니다.
00:30:57그리고 멀티 에이전트 오케스트레이션이 대세가 될 것이라는 점도 보여주죠.
00:31:01이 모든 것은 에이전트 시스템을 설계하고, 신규 소프트웨어의 아키텍처 구조를 결정하는 인간의 역할이 필수적임을 증명합니다.
00:31:21명세서를 작성하고, 소프트웨어 아키텍처를 구상하며, 이를 구현할 에이전트 시스템을 구축하고 검토하는 일의 중요성이 커지고 있습니다.
00:31:336년 전 개발 방식과는 확실히 달라지고 있지만, 개인적으로 이러한 변화의 방향성이 매우 기대됩니다.
00:31:45에이전트 시스템 구축과 소프트웨어 아키텍처 설계 양쪽 모두에서 시스템적인 사고 영역으로 이동하고 있다는 점이 매우 흥미롭습니다.
00:31:59그리고 두 영역이 서로 협력하게 만드는 것이죠.
00:32:01이러한 실험들은 아주 깊은 인상을 줍니다.
00:32:04여기서 얻은 교훈들 또한 매우 가치 있습니다.
00:32:07그리고 축소되고 단순화된 형태의 일부 교훈들은 일상적인 소프트웨어 개발 프로젝트에도 유용하게 적용될 수 있습니다.
00:32:17이번 실험에 대해 어떻게 생각하시는지 여러분의 의견을 댓글로 자유롭게 남겨주세요.

Key Takeaway

Cursor의 SQLite Rust 재구축 실험은 명확한 맥락과 검수 구조만 갖춰지면 고성능 기획 모델과 저비용 작업 모델의 조합, 그리고 전용 버전 관리 및 충돌 조정 에이전트 시스템을 통해 단 1,300달러의 비용으로 복잡한 소프트웨어를 완벽히 구현할 수 있음을 보여준다.

Highlights

  • Cursor 팀은 835페이지 분량의 SQLite 공식 문서와 SQLogicTest 수트를 활용해 멀티 에이전트 시스템으로 Rust 기반 SQLite 재구축 실험을 진행했다.

  • 기획자와 작업자 에이전트에 모두 GPT-5.5를 사용했을 때 10,000달러가 들었으나, 기획에 Opus 4.8을 쓰고 작업에 Composer 2.5를 조합했을 때는 동일한 품질을 내면서 비용이 1,300달러로 줄었다.

  • 초당 1,000건의 커밋을 생성하는 멀티 에이전트 환경의 거친 잠금 문제를 해결하기 위해 Git을 대체하는 고동시성 전용 버전 관리 시스템을 새로 구축했다.

  • 병렬 기획자 간의 설계 충돌 및 분할 뇌 문제는 프롬프팅 지침과 결정 사항을 통합하는 조정자(Reconciler) 에이전트를 통해 통제했다.

  • 상용 코드 보존용으로 파인튜닝된 에이전트의 코드 파괴 주저 현상을 극복하기 위해, 미배포 상태임을 명시하고 과감한 리팩토링 및 코드 삭제를 허용하는 파괴 권한을 제공했다.

Timeline

실험의 목적 및 모델 조합별 비용 비교

  • Cursor 팀의 mini SQLite 실험은 데이터베이스 자체보다 에이전트 스웜 및 소프트웨어 재구축 가능성을 탐구하기 위한 목적을 가진다.
  • 기획자와 작업자 에이전트 모델의 적절한 조합을 통해 동일한 구현 품질을 유지하면서 비용을 최대 87% 절감했다.

835페이지에 달하는 SQLite 공식 문서와 SQLogicTest 검증 수트를 기반으로 에이전트 시스템을 구동했다. 기획자와 작업자 모두에 GPT-5.5를 적용했을 때는 10,000달러의 비용이 발생했다. 반면 기획 및 설계에 Opus 4.8을 배치하고 작업 구현에 Composer 2.5를 조합한 방식은 1,300달러의 비용만으로 비등한 수준의 품질과 테스트 통과율을 기록했다. 이는 작업 명세와 맥락이 명확할 경우 코드를 작성하는 하위 에이전트에 최상위 지능 모델을 사용할 필요가 없음을 증명한다.

에이전트 역할 분담과 에이전트 전용 버전 관리 시스템 구축

  • 수백 개 에이전트가 동시에 생성하는 초당 1,000건의 커밋을 처리하기 위해 기존 Git을 대체하는 새 버전 관리 시스템을 만들었다.
  • 작업의 복잡도에 따라 기획자, 작업자, 검수자 에이전트로 역할을 나누어 병렬 처리 효과를 극대화했다.

기존 Git과 Cargo는 거친 잠금(Coarse Locks) 방식의 동시성 제어를 사용하므로 수백 개의 에이전트가 동시에 작업을 제출하는 환경을 감당하지 못한다. 올해 초 브라우저 스웜이 기록한 시간당 1,000건의 커밋을 넘어 이번 실험에서는 초당 1,000건의 커밋을 안정적으로 처리할 수 있는 고동시성 전용 버전 관리 시스템이 구축되었다. 이 시스템은 동시성 처리 외에도 에이전트 간 변경 충돌을 감지하고 해결하는 기본 레이어 역할을 수행한다.

기획자 간의 설계 충돌 및 분할 뇌 문제 해결

  • 독립된 기획자들이 동일한 개념을 중복 구현하는 분할 뇌 문제는 프롬프트를 통한 작업 영역 분할로 해결했다.
  • 동일한 파일을 두고 대립하는 기획자 간의 경합은 설계 문서를 통합하는 조정자(Reconciler) 에이전트를 도입해 통제했다.

여러 기획자 에이전트가 서로를 인지하지 못하면 코드베이스 내에 동일한 로직을 다르게 중복 생성하는 분할 뇌 현상이 일어난다. 기획 에이전트가 결정을 하위로 넘기지 않고 직접 내리도록 프롬프트를 구성해 작업 영역이 겹치지 않게 조율했다. 또한 공통 코드나 설계를 두고 기획자 간의 경합이 일어날 경우, 결정 사항을 기록한 공유 문서를 조정자 에이전트가 병합하고 컴파일 검사 참조를 통해 하류 작업자들에게 통일된 지침을 전파했다.

머지 충돌 및 메가 파일 병목 현상 대응

  • 동일 파일 수정 시 발생하는 머지 충돌을 해결하기 위해 중립적인 제3자 조정 에이전트를 개입시켰다.
  • 코드 추가로 인해 파일이 비대해지는 메가 파일 현상은 감지 플래그 및 전담 리팩토링 에이전트를 통해 모듈화했다.

작업자 에이전트는 타 에이전트의 커밋되지 않은 변경 사항을 덮어쓰거나 자기 작업을 포기하는 경향이 있다. 이를 방지하기 위해 깨끗한 컨텍스트 윈도우를 가진 중립적 제3자 에이전트가 머지 큐 스타일로 충돌을 원자적으로 해결하도록 설계했다. 또한 에이전트들이 특정 파일에 지속적으로 코드를 덧붙여 병목이 발생하는 메가 파일 문제는 작업자가 감지 플래그를 세우면 새 커밋을 차단하고 분할 전담 에이전트를 투입해 파일 크기를 작게 유지했다.

골화 문제 극복 및 스택형 리뷰 렌즈 시스템

  • 상용 환경 위주의 파인튜닝 지침을 덮어쓰기 위해 에이전트에게 의도적인 파괴 및 리팩토링 권한을 명시적으로 부여했다.
  • 다양한 시각을 가진 검수자 에이전트를 연결한 스택형 리뷰 렌즈 구조로 코드 품질과 신뢰도를 향상시켰다.

일반적인 AI 모델은 기존 코드를 삭제하는 것을 꺼리고 폴백 및 조건문을 쌓아두는 '골화' 성향을 보인다. 초기 개발 단계에서는 명시적 프롬프트를 통해 호환성을 깨는 변경과 리팩토링 권한을 제공해야 코드베이스 비대화를 막을 수 있다. 검수 단계에서는 관용성, 성능, 보안, 네이밍 등 특정 역할과 컨텍스트만 부여된 여러 검수자 에이전트를 배치하고, 지적 사항의 타당성을 다시 거르는 종합 검수자를 두어 오류 누적을 차단했다.

실험의 한계점 및 미래 소프트웨어 공학의 방향성

  • 기존 정교한 명세와 학습 데이터의 존재로 인해 이번 실험 결과를 일반적인 신규 소프트웨어 개발에 그대로 적용하기는 어렵다.
  • 미래의 소프트웨어 엔지니어링은 아키텍처 설계, 명세 작성, 멀티 에이전트 시스템 오케스트레이션 중심으로 이동한다.

이번 결과물은 실제 상용 환경에 즉시 투입 가능한 수준은 아니며, 초기 80% 구현 이후의 완성도를 높이는 작업에는 더 많은 자원이 소요된다. 또한 SQLite는 20년 이상 검증된 명세서와 테스트 수트가 존재하고 학습 데이터에도 관련 코드가 대량 포함되어 있어 완벽히 백지 상태에서 시작하는 프로젝트와는 조건이 다르다. 그럼에도 정교한 컨텍스트 분리, 전용 버전 관리, 에이전트 시스템 구축 등 오케스트레이션 및 아키텍처 설계 영역에서 엔지니어의 역할이 핵심으로 떠오르고 있음을 보여준다.

Community Posts

View all posts