메뉴
HN
Hacker News 115일 전

8년간의 갈망, AI와 함께한 3개월의 개발

IMP
8/10
핵심 요약

구글 퍼페토(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! 제 생각에 남은 유일한 합리적인 접근 방식은 관련 [파서 로직을 조심스럽게 추출하는 것]입니다.

원문 보기
원문 보기 (영어)
For eight years, I’ve wanted a high-quality set of devtools for working with SQLite. Given how important SQLite is to the industry 1 , I’ve long been puzzled that no one has invested in building a really good developer experience for it 2 . A couple of weeks ago, after ~250 hours of effort over three months 3 on evenings, weekends, and vacation days, I finally released syntaqlite ( GitHub ), fulfilling this long-held wish. And I believe the main reason this happened was because of AI coding agents 4 . Of course, there’s no shortage of posts claiming that AI one-shot their project or pushing back and declaring that AI is all slop. I’m going to take a very different approach and, instead, systematically break down my experience building syntaqlite with AI, both where it helped and where it was detrimental. I’ll do this while contextualizing the project and my background so you can independently assess how generalizable this experience was. And whenever I make a claim, I’ll try to back it up with evidence from my project journal, coding transcripts, or commit history 5 . Why I wanted it In my work on Perfetto , I maintain a SQLite-based language for querying performance traces called PerfettoSQL . It’s basically the same as SQLite but with a few extensions to make the trace querying experience better. There are ~100K lines of PerfettoSQL internally in Google and it’s used by a wide range of teams. Having a language which gets traction means your users also start expecting things like formatters, linters, and editor extensions. I’d hoped that we could adapt some SQLite tools from open source but the more I looked into it, the more disappointed I was. What I found either wasn’t reliable enough, fast enough 6 , or flexible enough to adapt to PerfettoSQL. There was clearly an opportunity to build something from scratch, but it was never the “most important thing we could work on”. We’ve been reluctantly making do with the tools out there but always wishing for better. On the other hand, there was the option to do something in my spare time. I had built lots of open source projects in my teens 7 but this had faded away during university when I felt that I just didn’t have the motivation anymore. Being a maintainer is much more than just “throwing the code out there” and seeing what happens. It’s triaging bugs, investigating crashes, writing documentation, building a community, and, most importantly, having a direction for the project. But the itch of open source (specifically freedom to work on what I wanted while helping others) had never gone away. The SQLite devtools project was eternally in my mind as “something I’d like to work on”. But there was another reason why I kept putting it off: it sits at the intersection of being both hard and tedious. What makes it hard and tedious If I was going to invest my personal time working on this project, I didn’t want to build something that only helped Perfetto: I wanted to make it work for any SQLite user out there 8 . And this means parsing SQL exactly like SQLite. The heart of any language-oriented devtool is the parser. This is responsible for turning the source code into a “parse tree” which acts as the central data structure anything else is built on top of. If your parser isn’t accurate, then your formatters and linters will inevitably inherit those inaccuracies; many of the tools I found suffered from having parsers which approximated the SQLite language rather than representing it precisely. Unfortunately, unlike many other languages, SQLite has no formal specification describing how it should be parsed. It doesn’t expose a stable API for its parser either. In fact, quite uniquely, in its implementation it doesn’t even build a parse tree at all 9 ! The only reasonable approach left in my opinion is to carefully extract the relevant parts of SQLite’s source code and adapt it to build the parser I wanted 10 . This means getting into the weeds of SQLite source code, a fiendishly difficult codebase to understand. The whole project is written in C in an incredibly dense style ; I’ve spent days just understanding the virtual table API 11 and implementation . Trying to grasp the full parser stack was daunting. There’s also the fact that there are >400 rules in SQLite which capture the full surface area of its language. I’d have to specify in each of these “grammar rules” how that part of the syntax maps to the matching node in the parse tree. It’s extremely repetitive work; each rule is similar to all the ones around it but also, by definition, different. And it’s not just the rules but also coming up with and writing tests to make sure it’s correct, debugging if something is wrong, triaging and fixing the inevitable bugs people filed when I got something wrong… For years, this was where the idea died. Too hard for a side project 12 , too tedious to sustain motivation, too risky to invest months into something that might not work. How it happened I’ve been using coding agents since early 2025 (Aider, Roo Code, then Claude Code since July) and they’d definitely been useful but never something I felt I could trust a serious project to. But towards the end of 2025, the models seemed to make a significant step forward in quality 13 . At the same time, I kept hitting problems in Perfetto which would have been trivially solved by having a reliable parser. Each workaround left the same thought in the back of my mind: maybe it’s finally time to build it for real. I got some space to think and reflect over Christmas and decided to really stress test the most maximalist version of AI: could I vibe-code the whole thing using just Claude Code on the Max plan (£200/month)? Through most of January, I iterated, acting as semi-technical manager and delegating almost all the design and all the implementation to Claude. Functionally, I ended up in a reasonable place: a parser in C extracted from SQLite sources using a bunch of Python scripts, a formatter built on top, support for both the SQLite language and the PerfettoSQL extensions, all exposed in a web playground. But when I reviewed the codebase in detail in late January, the downside was obvious: the codebase was complete spaghetti 14 . I didn’t understand large parts of the Python source extraction pipeline, functions were scattered in random files without a clear shape, and a few files had grown to several thousand lines. It was extremely fragile; it solved the immediate problem but it was never going to cope with my larger vision, never mind integrating it into the Perfetto tools. The saving grace was that it had proved the approach was viable and generated more than 500 tests, many of which I felt I could reuse. I decided to throw away everything and start from scratch while also switching most of the codebase to Rust 15 . I could see that C was going to make it difficult to build the higher level components like the validator and the language server implementation. And as a bonus, it would also let me use the same language for both the extraction and runtime instead of splitting it across C and Python. More importantly, I completely changed my role in the project. I took ownership of all decisions 16 and used it more as “autocomplete on steroids” inside a much tighter process: opinionated design upfront, reviewing every change thoroughly, fixing problems eagerly as I spotted them, and investing in scaffolding (like linting, validation, and non-trivial testing 17 ) to check AI output automatically. The core features came together through February and the final stretch (upstream test validation, editor extensions, packaging, docs) led to a 0.1 launch in mid-March. But in my opinion, this timeline is the least interesting p