8년간의 갈망, AI와 함께한 3개월의 개발
구글 퍼페토(Perfetto) 개발자가 AI 코딩 에이전트의 도움을 받아 3개월 만에 SQLite 개발자 도구인 'syntaqlite'를 성공적으로 구축한 후기를 공유했습니다. 저자는 AI가 단순히 코드를 자동 생성하는 수준을 넘어, 파서 구현 등 지루하고 까다로운 작업의 속도를 획기적으로 높여주었지만 일부 한계점도 존재했다고 체계적으로 분석했습니다. 이 글은 AI 코딩 도구가 실제 오픈소스 개발 워크플로우에 어떤 긍정적, 부정적 영향을 미치는지 실증적인 사례를 제공한다는 점에서 큰 의미가 있습니다.
8년 동안 나는 SQLite 작업을 위한 고품질 개발자 도구 세트를 간절히 원했습니다. 산업계에서 SQLite가 얼마나 중요한지를 고려할 때 1, 누구도 SQLite를 위한 훌륭한 개발자 경험을 구축하는 데 투자하지 않았다는 사실이 오랫동안 미스터리였습니다 2. 몇 주 전, 저녁, 주말, 휴가를 활용해 3개월 동안 약 250시간의 노력 3을 기울인 끝에, 마침내 오랜 숙원이었던 syntaqlite(GitHub)를 출시했습니다. 그리고 이것이 가능했던 주된 이유는 AI 코딩 에이전트 덕분이라고 확신합니다 4.
물론 AI가 한 번에 프로젝트를 완성했다고 주장하거나, AI가 그저 쓰레기 코드(slop)를 양산할 뿐이라고 반박하는 글은 넘쳐납니다. 저는 이와는 매우 다른 접근 방식을 취하여, AI가 도움이 되었던 부분과 방해가 되었던 부분을 체계적으로 분석하며 syntaqlite를 구축한 경험을 공유하고자 합니다. 이를 통해 프로젝트의 배경과 저의 경험을 설명하여, 이 경험이 얼마나 범용적으로 적용될 수 있는지 독자 여러분이 직접 평가할 수 있도록 할 것입니다. 또한 주장을 할 때마다 프로젝트 저널, 코딩 기록, 또는 커밋 내역 5에서 얻은 증거로 이를 뒷받침하려고 노력하겠습니다.
왜 이것을 원했는가 Google에서 Perfetto 작업을 하면서 나는 PerfettoSQL이라는 성능 추적(tracing) 쿼리를 위한 SQLite 기반 언어를 유지보수하고 있습니다. 이는 기본적으로 SQLite와 동일하지만 추적 쿼리 경험을 개선하는 몇 가지 확장 기능이 포함되어 있습니다. Google 내부에는 약 10만 줄의 PerfettoSQL 코드가 있으며 다양한 팀에서 사용하고 있습니다. 언어가 자리 잡기 시작하면 사용자들은 포매터(formatter), 린터(linter), 편집기 확장 프로그램과 같은 것들을 기대하기 시작합니다. 오픈소스의 기존 SQLite 도구들을 우리가 적용할 수 있을 것이라고 기대했지만, 더 자세히 알수록 더 큰 실망만 안겨주었습니다. 제가 찾은 것들은 신뢰할 수 없거나, 충분히 빠르지 않거나 6, PerfettoSQL에 맞게 수정하기에 유연성이 부족했습니다. 분명 밑바닥부터 무언가를 새로 구축할 기회가 있었지만, 그것은 항상 '우리가 당장 작업해야 할 가장 중요한 일'이 아니었습니다. 우리는 기존 도구들로 마지못해 버티고 있었지만 항상 더 나은 도구를 갈망했습니다.
반면, 여가 시간을 활용해 무언가를 해볼 수 있는 옵션도 있었습니다. 10대 시절 많은 오픈소스 프로젝트를 진행했었지만 7, 대학에 진학하면서 동기가 더 이상 없다고 느껴 점차 멀어졌습니다. 프로젝트의 메인테이너가 된다는 것은 단순히 '코드를 공개하고 결과를 지켜보는 것' 이상의 일입니다. 버그를 분류하고, 크래시를 조사하고, 문서를 작성하고, 커뮤니티를 구축하며, 무엇보다 프로젝트의 방향성을 가지고 있어야 합니다. 하지만 오픈소스에 대한 갈망(특히 원하는 것을 자유롭게 개발하면서 다른 사람들을 돕는 것)은 결코 사라지지 않았습니다. SQLite 개발자 도구 프로젝트는 항상 '내가 일하고 싶은 것'으로 마음속에 자리 잡고 있었습니다. 하지만 내가 계속 미뤘던 데는 또 다른 이유가 있었습니다. 그 작업이 '어렵고 지루함'의 교차점에 있었기 때문입니다.
무엇이 이것을 어렵고 지루하게 만드는가 만약 개인 시간을 들여 이 프로젝트를 진행하게 된다면, Perfetto에만 도움이 되는 것을 만들고 싶지 않았습니다. 모든 SQLite 사용자에게 적용할 수 있는 도구를 만들고 싶었습니다 8. 그리고 이것은 SQLite와 정확히 똑같이 SQL을 파싱하는(parsing) 것을 의미합니다. 언어 지향적(language-oriented) 개발자 도구의 핵심은 파서(parser)입니다. 파서는 소스 코드를 '파서 트리(parse tree)'로 변환하는 역할을 하며, 이 트리는 다른 모든 것이 구축되는 기반이 되는 핵심 데이터 구조입니다. 파서가 정확하지 않으면 포매터와 린터는 필연적으로 그 부정확성을 물려받게 됩니다. 내가 찾았던 많은 도구들이 SQLite 언어를 정확히 표현하는 대신 대략적으로 근사화하는 파서를 사용해 문제가 있었습니다. 불행히도 다른 많은 언어들과 달리, SQLite에는 파싱 방법을 설명하는 공식 명세(formal specification)가 없습니다. 파서를 위한 안정적인 API도 노출하지 않습니다. 사실, 매우 독특하게도 SQLite의 구현체는 아예 파서 트리 자체를 아예 만들지 않습니다 9! 제 생각에 남은 유일한 합리적인 접근 방식은 관련 [파서 로직을 조심스럽게 추출하는 것]입니다.