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이번 실험에 대해 어떻게 생각하시는지 여러분의 의견을 댓글로 자유롭게 남겨주세요.