The 80/20 Rule of AI Code — Why the Last 20% Takes 80% of Your Time
AI wrote the first 80% of my feature in 10 minutes. The code was clean. The logic made sense. The...
개요 #
화요일에 AI가 기능의 첫 80%를 10분 만에 짜줬다. 코드는 깔끔했고 로직도 말이 됐다. 해피 패스는 첫 시도에 돌아갔다. 그런데 같은 기능을 붙잡고 있다가 목요일 저녁이 됐다.
AI가 실패해서가 아니다. 오히려 정확히 엉뚱한 부분 — 쉬운 부분 — 에서 성공했고, 진짜 어려운 일은 통째로 사람한테 넘겼기 때문이다. 엣지 케이스, 에러 처리, null 체크, 실제 사용자가 해피 패스에서 예상하지 못한 행동을 할 때만 드러나는 상황들. AI는 그것들을 쓰지 않았다. 존재 자체를 몰랐다.
이게 AI 코드의 80/20 법칙이다. 첫 80%는 빠르고 인상적이고 거의 마법 같다. 마지막 20%에 진짜 일이 살아 있고, 그게 전체 시간의 80%를 잡아먹는다.
80% — 빠르고, 깔끔하고, 진짜로 인상적인 부분 #
불만을 늘어놓기 전에 이 부분만큼은 솔직하게 짚고 싶다.
AI는 첫 80%를 정말 잘한다. 명확한 프롬프트를 주면 해피 패스가 어떻게 생겼는지 파악하고, 돌아가는 코드를 뽑아낸다. "그럭저럭 돌아간다"가 아니라 실제로 돌아간다. 변수 이름도 합리적이고, 로직도 예상한 대로 흐른다.
처음 이걸 봤을 때는 뭔가 부정행위에 성공한 기분이었다. 티켓이 닫히고, 벨로시티 그래프가 올라가고, 몇 년 만에 가장 빠르게 뭔가를 출시하고 있었다.
그 속도가 빠른 건 AI가 익숙한 영역에서 움직이기 때문이다. 해피 패스는 가장 많이 밟힌 길이다. 학습 데이터 어딘가에 비슷한 형태로 존재하고, 수천 번 풀린 적 있는 문제다. 모델이 자신 있게 패턴 매칭으로 통과할 수 있는 버전이다.
80%는 진짜다. 속도도 진짜다. 문제는 우리가 그 80%를 마치 전부인 것처럼 다루기 시작했다는 점이다. 전부가 아닌데도.
20% — 화요일이 목요일이 되는 지점 #
AI가 해피 패스를 썼다. 그럼 AI가 쓰지 않은 것들을 솔직하게 나열해 보자.
빈 리스트. 사용자에게 아직 데이터가 없으면 어떻게 될까? 새 계정, 비어 있는 데이터베이스, 항상 항목이 있을 거라고 AI가 가정한 리스트가 사실은 비어 있는 경우. AI는 확인하지 않았다. 출시 사흘 뒤 사용자 제보로 알게 되고, 한 시간 동안 처리 안 된 케이스를 추적하다가, 화요일에 썼어야 할 체크를 추가한다.
에러 처리. AI는 네트워크가 응답한다고 가정한다. API가 요청한 걸 돌려준다고 가정한다. 서드파티 서비스가 살아 있다고 가정한다. 모든 try-catch, 모든 폴백, "실패했을 때 사용자에게 뭘 보여줄까" 하는 모든 결정은 사람 몫이다. 일이 잘못되는 상황은 프롬프트에 없었으니 AI는 그냥 비워뒀다.
도메인 특화 엣지 케이스. 매번 놀라는 지점이다. AI는 당신의 비즈니스 로직을 모른다. "비어 있음"이 애플리케이션의 세 군데에서 서로 다른 의미라는 걸 모른다. 형식이 다르게 저장된 레거시 데이터를 모른다. 아무도 예상 못 한 방식으로 제품을 쓰는 엔터프라이즈 고객을 모른다. 그건 당신이 아는 것이지, AI는 들어본 적도 없다.
성능 절벽. AI는 주어진 예시에서 돌아가는 코드를 쓴다. 규모에 대한 스트레스 테스트는 하지 않는다. 병목은 기능이 라이브로 나가고, 데이터가 많은 사용자에게서 페이지가 갑자기 4초씩 걸릴 때 발견된다. 코드가 틀린 게 아니다. 실제 부하를 염두에 두고 쓰이지 않았을 뿐이다.
유지보수 비용. 이건 가장 늦게 드러난다. AI는 오늘의 문제를 푸는 코드를 쓴다. 석 달 뒤 요구사항이 살짝 바뀌어 그 코드를 확장하려 하면, 추상화가 새 모양에 맞지 않는다는 걸 깨닫는다. 리팩터링 비용이 처음부터 새로 짜는 것보다 더 든다.
각각이 시간을 잡아먹는다. 합치면 AI 생성 코드로 출시한 어떤 기능에서든 전체 노력의 약 80%로 꾸준히 불어난다.
30초가 3시간이 된 사건 #
얼마 전 풀 리퀘스트 하나를 보고 있었다. 30초쯤 프롬프트로 뽑아낸, 약 200줄짜리 AI 생성 코드.
그 코드와 3시간을 보냈다.
코드가 깨져서가 아니다. 코드는 멀쩡했다. AI가 조용히 "내 문제 아님"으로 결정해 둔 것들을 전부 채우는 데 3시간을 썼다. 에러 경로, null 체크, 자명하지 않은 결정을 설명하는 주석, 사용자가 실제로 뭘 하는지 직접 고민해서 찾아낸 엣지 케이스.
30초 동안은 빠른 기분이었다. 3시간 동안은 느린 기분이었다.
하지만 자꾸 되돌아오는 생각이 있다. 그 3시간이 진짜 일이었다. 30초는 뼈대였다. AI가 일을 줄여준 게 아니라 일을 옮긴 것이다. 구조를 짜는 시간에서, 그걸 실제로 만드는 시간으로. 그리고 그 일이 더 느린 이유는 AI에게 진짜 없는 것 — 당신의 구체적인 상황, 구체적인 사용자, 이 코드베이스와 쌓아온 구체적인 이력에 대한 맥락 — 을 요구하기 때문이다.
그때부터 생성에 얼마나 걸렸는지는 신경 쓰지 않게 됐다. 대신 더 정직한 숫자를 추적하기 시작했다. 실제로 출시 가능한 상태가 될 때까지 얼마나 걸리는가.
이건 AI에 대한 불평이 아니다 #
분명히 해두자. 80/20 분할은 AI의 실패가 아니다. 사실상 설계 그대로다.
AI는 흔한 경우에 최적화돼 있다. 흔한 경우가 곧 해피 패스다. 흔한 경우를 빠르게 만들어내는 건 진짜 유용하다. 거기에 대해 깎아내릴 생각은 없다.
문제는 AI가 아니다. 문제는 우리가 AI를 중심으로 생산성을 측정하기 시작한 방식이다.
우리는 벨로시티를 잰다. 닫힌 티켓, 생성된 라인 수, 기여 그래프. 이 지표들은 80%를 아름답게 담아낸다. 80%는 빠르고 눈에 보이고 초록색 사각형으로 나타나니까.
20%는 그 지표들에 보이지 않는다. 에러 처리에 쓴 시간을 보여주는 대시보드는 없다. "어제는 AI가 예상 못 한 엣지 케이스에 하루를 썼습니다"로 시작하는 스탠드업도 없다. 어디에도 안 나타난다. 그런데 실제 시간 대부분이 거기로 간다.
80%는 데모까지 데려다준다. 20%는 프로덕션까지 데려다준다. 20%가 얼마나 걸리는지 추적하지 않는다면, 진짜 생산성을 추적하는 게 아니다. 프롬프트를 얼마나 빨리 쳐서 기분 좋아질 수 있는지를 추적하는 것이다.
그래서 내가 실제로 바꾼 것들 #
AI를 그만둔 건 아니다. 그만둘 생각도 없다. 다만 몇 가지를 바꿨다.
20%를 미리 예산에 넣는다. AI 생성 코드가 들어가는 작업을 추정할 때, 생성 시간으로 가늠되는 값에 대략 4배를 더한다. AI가 "10분짜리 기능"이라고 하면, 내 머릿속에선 40분짜리라고 생각하고 계획한다. 비관이 아니라 그냥 그 패턴이 계속 들어맞기 때문이다.
불행한 경로를 명시적으로 프롬프트에 넣는다. 메인 코드를 생성하기 전에 프롬프트에 적는다. 입력이 비어 있으면 어떻게 해야 하나? API가 실패하면 어떻게 해야 하나? 여기 어떤 엣지 케이스가 있나? AI는 스스로 떠올리지 않는다. 이름을 붙여 주면 적어도 한 번은 다뤄본다.
코드가 존재하기 전에 실패하는 테스트부터 쓴다. 뭐가 이걸 깨뜨릴까? 짓궂은 사용자라면 뭘 할까? 그런 테스트를 먼저 써서 AI에게 목표를 준다. 전부 잡아내지는 못해도, AI 혼자 찾는 것보다는 더 잡는다.
그 3시간을 기억한다. 데모에서 돌아가니까 빨리 밀어 넣고 싶어질 때, 그 3시간을 떠올린다. 30초는 기분이 좋았다. 3시간이 진짜 일이었다.
이 중 무엇도 20%를 사라지게 하지는 못한다. 다만 그것을 예측 불가능한 게 아니라 예측 가능한 것으로 만든다. 관리하는 것과 기습당하는 것의 차이가 거기에 있다.
질문 하나 #
AI가 빠르게 생성해 준 무언가에서, 마지막 20%에 가장 오래 쓴 시간은 얼마인가?
숫자가 있다면 실제 숫자가 궁금하다. 생성에 걸린 시간과 출시까지 실제로 걸린 시간의 격차 — 원문 작성자가 궁금해한 바로 그 숫자다. 작성자의 답은 "생성 30초, 마무리 3시간"이었다.
이 글은 위 출처를 바탕으로 한국 독자를 위해 재작성한 기사입니다. 원문의 사실과 수치에 근거하며, 별도의 견해를 포함하지 않습니다.

