한 개발자가 올해 2월부터 코드를 직접 타이핑하지 않고 AI 에이전트로만 개발하는 실험을 6개월간 진행한 경험담입니다. 에이전트가 실수할 때 직접 수정하는 대신 에이전트가 부족한 부분을 파악해 프롬프트와 환경을 개선하는 방식으로 작업했고, 대기 시간에 다른 에이전트를 띄우다 보니 자연스럽게 병렬 에이전트 시스템으로 발전했습니다. AI 코딩 도구의 실무 활용법과 한계를 보여주는 사례로 주목받았습니다.
번역된 본문
올해 2월, 나는 스스로에게 규칙을 하나 정했다: 더 이상 손으로 코드를 작성하지 않겠다는 것이었다. 그 규칙을 지내며 6개월을 살았다.
시스템은 내 머릿속에 있었다
2024년, AI 이전에 내 초능력은 시스템 전체가 어떻게 작동하는지, 특히 각 구성요소 간의 인터페이스를 정확히 알고 있다는 것이었다. 누군가 만들고 싶은 기능이나 고치고 싶은 버그를 가지고 오면, 나는 대개 정확히 어떤 코드 라인이 중요한지 짚어주고 무엇을 바꿔야 하는지 말해줄 수 있었다. 나는 또한 이상해 보이는 결정들이 왜 존재하는지, 어떤 가정들이 문서로 남지 않았는지도 기억했다. 이것은 코드베이스에서 수개월, 수년간 일하며 쌓은 지식이었다. 힘들게 얻은 것이었고 매우 귀중했다. 덕분에 기능을 빠르게, 그리고 더 중요하게는 안전하게 만들 수 있었다.
대가는 모든 것을 따라잡아야 한다는 것이었다. 기여자가 늘어날수록 그 멘탈 모델을 유지하기 위해 변경 사항을 읽는 데越来越多的 시간을 쓰게 됐다. 더 큰 대가는 타이핑이었다. 뭔가를 만들고 싶을 때마다 코드가 머릿속에 보였다. 다만 그것을 충분히 빨리 타이핑할 수 없을 뿐이었다. 타이핑 속도는 문제의 일부일 뿐이었다: 기능 하나는 거의 한 번의 수정으로 끝나지 않았다. 작은 변경이라도 여러 계층에 걸쳐 핸들러, 스키마, 테스트, 문서를 건드렸다. 그리고 그 수정들은 동등하지 않았다: 잘못된 핸들러는 되돌릴 수 있지만, 잘못된 마이그레이션은 뒷처리할 난장판을 남겼다. 그래서 손으로 코드를 쓴다는 것은 하나의 결정을 그것이 닿는 모든 곳에서 안전하게 운반한다는 뜻이었다.
Copilot 자동완성은 즉시 도움이 됐다: 문서 주석이 초안이 되었고, 자주 틀렸지만 빈 파일을 수정하는 것보다는 나았다. Cursor의 탭 완성은 더 도움이 됐다. 모델들은 명확히 빠르게 발전하고 있었다. Claude Code는 많은 것을 바꿨다. 변경 사항을 한 번만 설명하면 에이전트가 여러 파일을 한꺼번에 수정해줬다. 덕분에 타이핑은 크게 줄었다. 하지만 타이핑이 줄었다고 일이 준 것은 아니었다: 모델이 생성한 모든 변경을 머릿속에 있는 원하는 상태와 대조하며 읽어야 했다. 에이전트는 여전히 자주 틀렸고 필요 없는 변경을 만들었다. 점진적으로 작업하게 하는 것이 궤도에 유지하는 방법이었다. 이는 생성된 코드의 일부를 직접 수정한다는 뜻이기도 했다. 결국 병합되는 모든 라인에 대해 책임은 내게 있었으니까. 모델은 책임지지 않는다.
그러다 올해 초, 모델들이 거의 동시에 정말 좋아졌다. GPT-5.3과 Opus 4.6은 갑자기 훨씬 적은 개입으로 더 큰 변경을 처리할 수 있었고, 그 결과물은 마침내 그 위에 쌓아 올릴 만큼 충분했다. 그래서 2월에 규칙을 정했다: 더 이상 손으로 코드를 쓰지 않는다. 에이전트가 막히면, 내가 직접 코드를 마칠 수 없었다. 대신 에이전트에게 무엇이 빠졌는지 파악하고 그것을 고쳐야 했다.
나는 코딩에 대해 읽어서 코딩을 잘하게 되지 않았다. 많은 코드를 쓰고, 실행하고, 실패를 보고, 고치고, 다시 반복하며 잘하게 됐다. AI 에이전트도 결국 소프트웨어다. 프롬프트 가이드를 읽는다고 이해되지 않는다. 실제 작업에 사용하고, 어디서 실패하는지 보고, 프롬프트·도구·환경을 바꾸고 다시 시도해야 한다. 그 규칙이 나에게 그 반복 훈련을 강제했다. 규칙을 한 번 깼는데, 3분 동안이었다. 코드를 열고 몇 줄을 썼는데 기분이 좋았다. 이걸 그리워했구나. 내가 아직 타이핑해야 할 게 얼마나 많은지 깨달을 때까지는. 바로 관뒀다.
하나의 에이전트가 열둘이 되다
내가 직접 코드를 타이핑하지 않게 되자, 자투리 시간이 생기기 시작했다. 에이전트에게 작업을 주면, 작업하는 동안 내가 할 일이 없었다. 기다리는 대신 다른 일을 하는 에이전트를 하나 더 띄웠다. 그리고 또 반복했다. 의도적으로 병렬 시스템을 만든 것이 아니었다. 그냥 작업 사이의 시간을 채운 것뿐이었다. 나는 ADHD가 있다. 딴짓을 한 것이다.
동료들끼리 개발 장비 하나를 공유하면 어떤 일이 벌어질지 상상하기 어렵지 않다. 이제 그들이 서로 대화하지 않으면서 동시에 작업한다고 상상해보라. 그것이 나의 첫 병렬 구성이었다. 에이전트들은 같은 파일과 Git 상태를 변경하고, 의존성을 설치하고, 포트를 두고 다투고, 프로세스를 실행한 채 남겨뒀다. 각 에이전트가 언제 작업할지 조율해야 했
In February of this year, I made a rule for myself: I wasn’t going to write code by hand anymore. I’ve been living by that rule for six months. The system lived in my head Back in 2024, before AI, my superpower was knowing how the entire system worked, especially the interfaces between its different components. If someone came to me with a feature they wanted to build or a bug they were trying to fix, I could usually point them to the exact line of code that mattered and tell them what needed to change. I also remembered why the strange-looking decisions existed and which assumptions were never written down. This was knowledge I’d built over months and years of working in the codebase. It was hard-earned and invaluable. It let me build features quickly and, more importantly, safely. The cost was that I had to keep up with everything. As more people contributed, I spent more and more time reading changes just to maintain that mental model. The bigger cost was the typing. Every time I wanted to build something, I could see the code in my head. I just couldn’t type it out fast enough. Typing speed was only part of the problem: a feature was almost never one edit. Even a small change spanned multiple layers and touched handlers, schema, tests, and docs. And those edits weren’t equal: a bad handler could be reverted, but a bad migration could leave a mess behind. So writing the code by hand meant carrying one decision safely through every place it touched. Copilot autocomplete helped immediately: a doc comment became a first draft, often wrong, but beats editing a blank file. Cursor’s tab complete helped more. The models were clearly improving fast. Claude Code changed a ton. I could describe the change once, and the agent would edit a bunch of files at once. As a result, I typed a lot less. But typing less didn’t mean working less: I read every change the model generated to match it against the desired state I had in my head. Agents would still be wrong quite a lot and make changes that weren’t required. Working incrementally kept them on track. This meant hand editing some of the generated code. After all, I was still responsible for every line that merged. The model wasn’t going to be held accountable. Then, early this year, the models got really good, almost all at once. GPT-5.3 and Opus 4.6 could suddenly handle larger changes with much less steering, and the results were finally good enough to build on. So in February I made the rule: no more code by hand. If an agent got stuck, I wasn’t allowed to finish the code myself. I had to figure out what the agent was missing - and fix that instead. I didn’t get good at coding by reading about coding. I got good by writing a lot of code, running it, seeing it fail, fixing it, and doing it again. AI agents are just software, after all. I wasn’t going to understand them by reading prompt guides. I had to use them for real work, see where they failed, change the prompts, tools, or environment, and try again. The rule forced me to get those reps. I broke it once, for three minutes. I opened the code and wrote a few lines, and it felt great. I had missed this. Right up until I realized how much I still had to type. I noped out. One agent became a dozen Once I stopped typing the code myself, I started finding these pockets of free time. I would give an agent a task, and then there was nothing for me to do while it worked. Instead of waiting, I spun up another agent to do something else. Then I did it again. I wasn’t intentionally building a parallel system. I was just filling the time between tasks. I have ADHD. I got distracted. It’s easy to imagine what would happen if you shared a single dev box between colleagues. Now imagine they don’t talk to each other and they’re all working at the same time. That was my first parallel setup. The agents changed the same files and Git state, installed dependencies, fought over ports, and left processes running. I also had to coordinate when each agent could test, push, or deploy. Worse, I often ended up waiting for the longest-running agent before the others could move forward. I had started more agents to avoid waiting and somehow created a new way to wait. I asked friends and colleagues how they dealt with this, and everyone had a workaround. Worktrees came up first. Each agent got its own checkout and branch, and the source collisions mostly went away, but worktrees only solved the Git part. The agents still shared databases, ports, processes, and the rest of the machine. So people patched around that with AGENTS.md: use a random port, create an ephemeral database, don’t touch another agent’s process. Every conflict became another instruction, and the agents burned context figuring out how not to step on each other instead of doing the task. Containers got closer: separate ports, processes, and local state. But the boundary was leaky: whatever my laptop could reach, the container could potentially reach too. The blast radius of a bad command wasn’t contained, so I was still approving commands. And worst of all, my laptop had to stay awake. If I closed it, all of the work stopped. I closed my laptop. The work kept going. By this point, I had joined exe.dev. We make Linux VMs that come up in a couple of seconds with SSH and HTTPS already set up, so moving the agents off my laptop was the natural next step. Each task got its own machine. I could close my laptop, walk away, and the work kept running. But now I had a new problem: how do I reliably bring up a complete development environment for whatever I want the agent to work on? So, staying true to not writing code, I asked Claude to write a startup script. I told it what I wanted and instructed it to loop until things worked. It installed our toolchains, cloned the repositories, configured Claude Code and Codex, and did everything needed to turn a fresh VM into a development environment. Then it ran the validation loop: bring up a fresh box, run the script, see what broke, fix the script, and try again. The agent boxes worked, but each agent still had its own tmux session. I ended up keeping a dozen terminal windows open just to see what each agent was doing. I had to jump between them to find which agent had finished, which one was stuck, and which one needed something from me. I needed one place to manage all of them. So I built botd . I gave it three rules. First, it had to run somewhere other than my laptop (the agents should keep working when I closed it). Second, mobile had to be first-class . Managing agents shouldn’t require sitting in front of a terminal. Third, it had to preserve every conversation so I could look back across agents and understand where they got stuck, which instructions worked, and which problems kept repeating. botd provisioned and deprovisioned the agent boxes, drove the agents underneath, and kept track of every task. It showed me which agents were working, which were stuck, and which were waiting for me. From my phone or laptop, I could inspect the conversation, send follow-up instructions, and review the diff. Instead of managing a dozen terminal sessions, I had one place to manage the work. None of this worked if I had to approve every tool call. That would just turn me into the queue again. Each agent was running inside an isolated, disposable VM, so I let it run in YOLO mode. It could run bash commands, install packages, start services, and change whatever it needed. A trashed environment cost me nothing but the VM. But an agent that can only touch its own VM isn’t very interesting. I still wanted agents to read logs, pull from Git, call Anthropic or OpenAI, and inspect things in Stripe. That access is where the real risk lived, and the VM did nothing to bound it. An agent reads untrusted content and can be prompt-injected by it; whatever it can reach, an injected agent can leak or corrupt. There were holes I knew I hadn’t filled. So every piece of external access got the same questi