속도를 확 늦춰야 한다는 생각.txt
source https://mariozechner.at/posts/2026-03-25-thoughts-on-slowing-the-fuck-down/
Agent에 대한 생각들이 많이 공감되네요.

업계를 바라보는 지금의 내 표정은 딱 저 거북이 얼굴이다
제대로 프로젝트 하나를 통째로 만들어 줄 수 있는 코딩 에이전트가 등장한 지도 이제 1년쯤 됐다. 그전에도 Aider나 초기 Cursor 같은 전조는 있었지만, 그건 에이전트라기보다 보조 도구에 가까웠다. 지금 세대의 도구들은 꽤 매혹적이고, 그래서 많은 사람들이 예전부터 만들고 싶었지만 시간이 없어서 못 만들던 프로젝트들을 자기 시간 쏟아 가며 만들고 있다.
그 자체는 괜찮다고 생각한다. 자기 시간을 써서 뭔가를 만드는 건 원래 엄청 즐거운 일이고, 그런 개인 프로젝트에서는 코드 품질이나 유지보수성에 크게 신경 쓰지 않아도 되는 경우가 많다. 새로운 기술 스택을 익히는 계기가 되기도 하고.
크리스마스 연휴 동안 Anthropic과 OpenAI는 사람들을 그 중독성 강한 슬롯머신에 더 깊게 끌어들이려고 이것저것 무료로 풀었다. 많은 사람들에게는 그게 에이전트 코딩의 마법을 처음 체감한 순간이었을 거다. 그 흐름에 올라탄 사람은 계속 늘고 있다.
이제 코딩 에이전트는 실제 프로덕션 코드베이스에도 들어가고 있다. 12개월이 지난 지금, 우리는 그 모든 “진보”가 남긴 결과를 슬슬 보기 시작했다. 지금 내 생각은 이렇다.
다 망가져 가고 있다
물론 전부 어디까지나 체감이고 경험담 수준이긴 하다. 그래도 소프트웨어가 점점 건드리기만 하면 깨지는 엉성한 물건이 되어 가는 느낌은 확실하다. 대형 서비스들까지 포함해서 가동률 98%가 예외가 아니라 기본값처럼 느껴지고, UI에는 QA 팀이면 당연히 잡았을 것 같은 얼척없는 버그가 자꾸 나온다. 이런 문제가 에이전트 등장 전부터 있었던 건 맞다. 하지만 지금은 그 속도가 더 빨라지는 것 같다.
우리에겐 각 회사 내부를 들여다볼 수단이 없다. 그래도 가끔은 뭔가가 새어 나와 기자 손에 들어간다. 예를 들면 AI 때문에 AWS 장애가 났다는 이야기 같은 것. AWS는 곧바로 그걸 “정정”했지만, 그 뒤 내부적으로는 90일 리셋 같은 대응이 이어졌다.
마이크로소프트 CEO 사티아 나델라는 Microsoft에서 이제 코드의 상당 부분이 AI로 작성되고 있다는 이야기를 계속하고 있다. 직접적인 증거가 있는 건 아니지만, Windows가 점점 엉망이 되어 간다는 느낌은 분명 있다. 마이크로소프트도 어느 정도는 그렇게 보고 있는 듯하다. 이 블로그 글만 봐도 그렇다.
자사 제품 코드의 100%를 이제 AI가 쓴다고 자랑하는 회사들은 대체로 상상 가능한 최악의 결과물을 내놓고 있다. 누구라고 콕 집진 않겠지만, 기가바이트 단위 메모리 누수, UI 깨짐, 망가진 기능, 잦은 크래시. 그건 그들이 생각하는 품질 보증 마크가 아니다. 에이전트가 전부 다 해 주는 꿈같은 미래를 홍보하는 데도 전혀 도움이 안 된다.
업계 사람들 얘기를 들어 보면, 크고 작은 소프트웨어 회사들에서 “에이전트 코딩하다가 스스로 궁지에 몰렸다”는 말이 점점 더 많이 나온다. 코드 리뷰는 없고, 설계 결정은 에이전트에게 넘겨버렸고, 아무도 원하지 않은 기능만 잔뜩 붙었다. 그렇게 하면 당연히 그렇게 된다.
에이전트와 일할 때 하지 말아야 할 방식, 그리고 그 이유
우리는 사실상 모든 규율과 주도권을 내던지고, 가능한 한 짧은 시간 안에 최대한 많은 코드를 찍어내는 데만 집착하는 상태가 됐다. 그 뒤에 어떤 결과가 오든 일단 신경 안 쓴다.
자율 에이전트 군단을 지휘할 오케스트레이션 레이어를 만들고 있다. 인터넷에서 다들 쓰라니까 Beads도 깔았다. 사실상 지우기도 힘든 악성코드 수준이라는 건 전혀 모른 채로. 그래야 안 뒤처진다더라. 루프를 굴리고 또 굴린다. 봐라, Anthropic은 에이전트 군단을 써서 C 컴파일러도 만들었다. 좀 망가져 있긴 하지만, 다음 세대 LLM이면 고치겠지. 세상에, Cursor는 에이전트 대대를 동원해서 브라우저도 만들었다. 물론 제대로 돌아가진 않고, 중간중간 사람이 조금씩 핸들을 잡아 줘야 했지만. 그래도 다음 세대 LLM이면 해결하겠지. 새끼손가락 걸고 약속! 분산, 분업, 자율성, 다크 팩토리, 소프트웨어는 이제 6개월 안에 완전히 정복된다. SaaS는 끝났고, 우리 할머니도 Claw로 자기만의 Shopify를 만들었다.
물론 이런 식도 거의 아무도 안 쓰는, 심지어 나조차 잘 안 쓰는 사이드 프로젝트에서는 굴러갈 수 있다. 그리고 실제 사용자들이 빡세게 쓰는 제품이면서도 쓰레기 더미가 아닌 소프트웨어에서 이 방식을 진짜로 성공시키는 사람도 어딘가엔 있을지 모른다.
그게 당신이라면, 뭐 좋다. 다만 적어도 내 주변 동료들 사이에서는 이런 방식이 제대로 먹힌다는 증거를 아직 본 적이 없다. 어쩌면 우리 모두 실력이 부족한 걸지도 모르지.
배움은 없고 병목도 없고, 고통만 늦게 터지는 실수 누적
에이전트의 문제는, 결국 실수를 한다는 데 있다. 물론 인간도 실수한다. 단순한 정합성 오류일 수도 있다. 그런 건 찾기도 쉽고 고치기도 쉽다. 덤으로 회귀 테스트 하나 얹어 주면 더 좋고. 아니면 lint가 못 잡는 코드 스멜일 수도 있다. 여기 쓸모없는 메서드 하나, 저기 말 안 되는 타입 하나, 저쪽엔 중복 코드 조금. 이런 건 하나하나만 보면 별일 아니다. 사람도 얼마든지 이런 실수는 한다.
하지만 깡통은 인간이 아니다. 사람은 같은 실수를 몇 번 하다가 결국 덜 하게 된다. 누가 옆에서 소리치기 시작해서든, 아니면 스스로 배우는 과정에 들어가서든 말이다.
에이전트는 그런 식으로 배우지 않는다. 적어도 기본 상태로는 그렇다. 같은 실수를 계속, 정말 계속 반복한다. 학습 데이터에 따라서는 온갖 실수를 멋지게 합성한 새로운 변형까지 만들어 낸다.
물론 가르치려 들 수는 있다. AGENTS.md에 “이 실수 다시 하지 마”라고 적어 둘 수도 있고, 복잡한 메모리 시스템을 꾸며서 과거 실수와 베스트 프랙티스를 다시 찾아보게 만들 수도 있다. 특정 종류의 오류에는 실제로 효과가 있을 수도 있다. 하지만 그러려면 우선 그 실수를 에이전트가 저질렀다는 걸 당신이 직접 발견해야 한다.
그런데 깡통과 인간 사이에는 더 중요한 차이가 하나 있다. 인간은 병목이다. 사람은 몇 시간 만에 코드 2만 줄을 토해내지 못한다. 설령 그런 실수를 꽤 자주 만든다고 해도, 하루 동안 코드베이스에 집어넣을 수 있는 실수의 양에는 한계가 있다. 그래서 실수는 아주 천천히 누적된다. 보통은 그 실수 때문에 겪는 고통이 너무 커지면, 고통을 싫어하는 인간이 시간을 들여 그걸 치운다. 아니면 그 사람이 잘리고 다른 누군가가 와서 치운다. 어쨌든 고통은 줄어든다.
하지만 잘 짜인 에이전트 군단에는 병목도 없고, 인간이 직접 느끼는 고통도 없다. 작고 사소해 보이던 실수들이 감당 불가능한 속도로 쌓이기 시작한다. 당신은 이미 루프 바깥으로 빠져나와 있기 때문에, 그 무해해 보이던 실수들이 괴물 같은 코드베이스를 만들고 있다는 사실조차 모른다. 고통은 이미 늦었을 때 비로소 체감된다.
그러다 어느 날 뒤돌아보면 새 기능 하나 추가하고 싶어진다. 그런데 아키텍처가, 이제는 거의 실수의 집합체가 되어 버린 그 아키텍처가, 당신의 에이전트 군단으로는 제대로 된 변경을 못 하게 막고 있다. 혹은 최신 릴리스 어딘가가 터져서 사용자 데이터가 날아갔다며 유저들이 비명을 지르고 있을 수도 있다.
그제야 코드베이스를 더는 믿을 수 없다는 걸 깨닫는다. 더 심각한 건, 에이전트가 써 놓은 수많은 유닛 테스트, 스냅샷 테스트, E2E 테스트마저 믿을 수 없다는 사실이다. 결국 “이게 진짜 되나?”를 확인하는 유일한 믿을 만한 방법은 제품을 손으로 직접 테스트하는 것뿐이다. 축하한다. 당신은 자기 자신과 회사 둘 다 골로 보낸 셈이다.
배운 복잡성을 되파는 장사꾼들
무슨 일이 벌어지고 있는지 당신은 정말 하나도 모른다. 주도권을 전부 에이전트에게 넘겨버렸기 때문이다. 그들을 풀어놨고, 그들은 복잡성을 퍼 나르는 장사꾼이다. 학습 데이터에도, RL 과정에도 형편없는 아키텍처 결정은 차고 넘친다. 그런 존재들에게 애플리케이션 설계를 맡겼다. 결과가 어떨까?
엄청난 양의 복잡성이다. 형편없는 카고 컬트식 “업계 베스트 프랙티스”가 뒤섞인 혼합물. 이미 늦기 전에 붙잡아 두지 못한 결과물이다. 그런데 문제는 거기서 끝나지 않는다.
에이전트들은 서로의 실행 과정을 보지 못한다. 코드베이스 전체도 못 본다. 다른 에이전트나 당신이 이전에 어떤 결정을 내렸는지도 전부 알지 못한 채 변경을 만든다. 그래서 에이전트의 판단은 언제나 국소적일 수밖에 없고, 그 결과는 앞에서 말한 온갖 실수들이다. 중복 코드가 끝없이 생기고, 추상화를 위한 추상화가 늘어난다.
이 모든 것이 쌓여서 결국 회복 불가능한 복잡성의 늪이 된다. 인간이 만든 대기업 코드베이스에서 흔히 보는 바로 그 난장판이다. 그런 코드베이스가 그렇게 되는 이유는 고통이 너무 많은 사람에게 분산되기 때문이다. 각 개인이 느끼는 고통은 “이건 내가 직접 고쳐야 해”라는 임계치를 넘지 못한다. 애초에 그걸 고칠 수단이 없는 사람도 많다. 조직은 원래 고통 내성이 높기도 하다. 그래도 인간이 만드는 엔터프라이즈 코드베이스는 거기까지 가는 데 수년이 걸린다. 조직은 느리고 기묘한 공진화 속에서 그 복잡성과 함께 변해 가며, 어찌어찌 그걸 다루는 법을 익힌다.
하지만 에이전트와 사람 둘만 있어도, 그 복잡성에 몇 주 만에 도달할 수 있다.
에이전트 검색은 재현율이 낮다
이제 당신은 에이전트가 이 난장판을 고쳐 주길 바란다. 리팩터링하고, 다시 말끔하게 정리해 주길 기대한다. 그런데 이제는 에이전트도 그걸 감당하지 못한다. 코드베이스와 복잡성이 너무 커졌고, 에이전트는 여전히 그 난장판의 일부만 볼 수 있기 때문이다.
이건 단순히 컨텍스트 윈도 크기가 부족하다거나, 긴 컨텍스트 주의 메커니즘이 100만 줄짜리 괴물 코드를 보면 무너진다는 얘기만은 아니다. 그런 건 너무나 뻔한 기술적 한계다. 문제는 그보다 더 교묘하다.
에이전트가 이 난장판을 고치는 데 도움을 주려면, 우선 어디를 바꿔야 하는지와 재사용 가능한 기존 코드가 어디 있는지를 찾아야 한다. 이걸 우리는 에이전트 검색이라고 부른다. 에이전트가 어떻게 찾는지는 도구에 따라 다르다. Bash 도구를 줘서 ripgrep으로 코드베이스를 뒤지게 할 수도 있고, 질의 가능한 코드 인덱스나 LSP 서버, 벡터 데이터베이스를 줄 수도 있다. 하지만 결국 크게 달라지지 않는다. 코드베이스가 커질수록 재현율은 떨어진다. 재현율이 낮다는 건, 결국 에이전트가 일을 제대로 하려면 반드시 찾아야 할 코드를 다 찾지 못한다는 뜻이다.
애초에 그 자잘한 코드 실수들이 생기는 이유도 이것이다. 에이전트는 기존 코드를 놓치고, 같은 걸 또 만들고, 일관성을 깨뜨린다. 그리고 그 결과는 아름답게 피어난 복잡성의 똥꽃이 된다.
그럼 이 모든 걸 어떻게 피할까?
에이전트와는 이렇게 일해야 한다고 본다 (적어도 지금은)
코딩 에이전트는 사이렌 같다. 엄청난 속도로 코드를 뽑아내고, 들쭉날쭉하지만 어쨌든 번뜩이는 지능으로 간단한 작업은 순식간에 꽤 높은 품질로 끝내 버리면서 사람을 유혹한다. 문제는 여기서 “와, 이거 진짜 좋네. 컴퓨터야, 내 일 좀 대신해”라고 생각하는 순간부터 시작된다.
물론 작업을 에이전트에게 위임하는 것 자체는 아무 문제 없다. 좋은 에이전트 작업에는 몇 가지 공통점이 있다. 범위를 잘라 낼 수 있어서 시스템 전체를 이해하지 않아도 된다. 루프를 닫을 수 있다. 즉, 에이전트가 자기 결과물을 스스로 평가할 수 있는 방법이 있다. 결과물이 미션 크리티컬하지 않다. 그냥 임시 도구이거나, 누구의 생계나 매출도 걸려 있지 않은 내부 소프트웨어 조각 정도다. 아니면 그냥 아이디어를 던져 볼 고무 오리 한 마리가 필요한 경우일 수도 있다. 사실상 인터넷의 압축된 집단 지성과 합성 학습 데이터에 아이디어를 한번 부딪혀 보는 셈이다. 이 중 하나라도 해당된다면, 그리고 최종 품질 게이트를 인간인 당신이 맡는다면, 그건 에이전트에게 딱 맞는 작업이다.
Karpathy의 auto-research를 앱 시작 시간 단축에 적용한다고 해 보자. 좋다! 다만 그게 뱉어내는 코드는 전혀 프로덕션 준비가 끝난 상태가 아니라는 걸 분명히 이해해야 한다. auto-research가 통하는 이유는 시작 시간이나 손실값 같은 어떤 지표를 기준으로 에이전트가 자기 작업을 측정할 수 있게 해 주는 평가 함수가 있기 때문이다. 하지만 그 평가 함수는 아주 좁은 지표만 담아낸다. 코드 품질, 복잡성, 심지어 정확성 같은 요소는 당신의 평가 함수가 엉망이면 에이전트가 아주 기분 좋게 무시해 버린다.
핵심은 이거다. 에이전트에게는 지루한 일, 해도 내가 새로 배울 게 없는 일, 아니면 시간이 없어서 직접 못 해 보던 여러 시도를 맡겨라. 그리고 그 결과물을 당신이 평가해라. 그중에서 진짜 말이 되고 맞는 아이디어만 골라서 최종 구현을 마무리해라. 물론 마지막 단계에도 에이전트를 쓸 수는 있다.
그리고 나는 여기서, 진짜 속도를 좀 늦추는 쪽이 맞다고 말하고 싶다. 내가 지금 뭘 만들고 있는지, 왜 만드는지 생각할 시간을 스스로에게 줘라. “아니, 이건 진짜 필요 없다”라고 말할 기회도 만들어라. 하루에 깡통이 생성하도록 허용하는 코드 양에도 한도를 둬라. 그리고 그 한도는 당신이 실제로 리뷰할 수 있는 양에 맞춰라.
시스템의 형태를 결정하는 것, 즉 아키텍처나 API 같은 것은 직접 손으로 써라. 향수를 느끼고 싶으면 탭 자동완성 정도만 써도 된다. 아니면 에이전트와 페어 프로그래밍을 해라. 직접 코드 안에 들어가 있어라. 실제로 손으로 쓰거나, 코드가 한 줄씩 쌓이는 걸 눈으로 따라가는 그 단순한 행위 자체가 마찰을 만든다. 그리고 그 마찰이 있어야 내가 뭘 만들고 싶은지, 이 시스템이 어떤 “감”을 가져야 하는지 더 잘 이해할 수 있다. 이 지점에서 경험과 취향이 들어간다. 지금의 최첨단 모델들은 아직 그걸 대체하지 못한다. 속도를 확 늦추고 약간의 마찰을 감수해야, 사람도 배우고 성장할 수 있다.
그 결과물은 계속 유지보수 가능한 시스템과 코드베이스가 된다. 적어도 에이전트가 없던 시절 우리의 오래된 시스템만큼은 유지보수 가능할 것이다. 물론 그것들도 완벽하진 않았다. 그래도 이제 당신의 제품은 대충 찍어낸 슬롭이 아니라, 사용자에게 정말 좋은 경험을 준다. 기능은 더 적게 만들게 될 수도 있다. 하지만 맞는 기능을 만들게 된다. “아니오”라고 말하는 법을 배우는 것 자체가 하나의 기능이다.
무슨 일이 벌어지는지 내가 아직은 알고 있다는 사실, 그리고 내가 여전히 주도권을 쥐고 있다는 사실 덕분에 마음 편히 잠들 수 있다. 그 이해가 있어야 에이전트 검색의 재현율 문제를 사람이 보완할 수 있고, 그래서 깡통이 내놓는 결과물도 덜 손봐도 되는 쪽으로 좋아진다. 그리고 정말 일이 터졌을 때, 직접 들어가서 고칠 수 있다. 처음 설계가 별로였다면 왜 별로였는지도 이해하고, 그걸 더 나은 구조로 어떻게 리팩터링해야 할지도 안다. 에이전트를 쓰든 말든, 그건 별로 중요하지 않다.
이 모든 것에는 규율과 주도권이 필요하다.
이 모든 것에는 인간이 필요하다.
