개발 생산성의 함정: 쓰레기 코드 청소법

AI가 코드를 뚝딱 만들어주는 세상이다. 뭐 하나 만들어달라고 요청하면 9초 만에 1,000줄짜리 코드가 화면을 가득 채운다.

과거 같으면 며칠 밤을 새워야 겨우 뽑아냈을 분량이다. 📉 그런데 이 편리함의 이면에 어떤 일이 벌어지고 있는지 들여다본 적 있는가. AI가 싸지른 쓰레기 코드, 이른바 '바이브 슬롭(Vibe Slop)'이 전 세계 개발자들의 컴퓨터를 잠식하고 있다. 코드를 짜는 건 에이전트인데, 그 흉물스러운 결과물을 치우느라 밤을 지새우는 건 온전히 인간의 몫이 되었다.

헐, 이게 정말 우리가 꿈꾸던 미래인가 싶다. 👀

AI 에이전트가 만든 코드가 쓰레기가 되는 이유

추상화의 폭발과 과도한 엔지니어링

안드레 카르파시(Andrej Karpathy)가 지적했듯, AI 에이전트는 기본적으로 '더 많은 것'을 토해내는 괴물에 가깝다. 100줄이면 충분한 로직에 팩토리, 인터페이스, 설정 파일, 그리고 4개의 테스트 파일까지 세트로 얹어준다.

작은 걸 하나 요청했을 뿐인데 코드베이스 전체가 거대한 미로로 변해버린다. 팩토리 패턴을 왜 여기서 써야 하는지, 이 인터페이스가 대체 무슨 쓸모가 있는지 의문을 품으며 지난주 내내 코드베이스를 '언슬로핑(unslopping)'하는 데 시간을 쏟는 일이 다반사가 되었다. 🏗️

모델들은 사용자의 대변인이라도 된 것처럼 "make wrong assumptions on your behalf and just run with them", 즉 제멋대로 잘못된 가정을 세운 뒤 검토 과정도 없이 폭주한다.

부서진 코드는 에러라도 명확해서 찾기 쉽지만, AI가 싼 슬롭 코드는 컴파일도 되고 테스트도 통과하며 겉보기엔 멀쩡하게 작동한다. 하지만 그 복잡함이 애초에 필요 없었기에 코드를 한 줄 한 줄 뜯어보며 허탈감에 빠지게 된다.

내가 타이핑하지 않았다는 이유로, 내부에 무엇이 들어있는지 100% 확신하지 못한 채 배포해야 하는 '바이브 코드 안시어티(vibe code anxiety)'가 개발자들을 짓누르고 있다.

실제로 커서(Cursor)의 보고서에 따르면 AI를 적극 활용하는 상위 1% 개발자는 하루 평균 생성하는 AI 코드량이 일반 개발자의 46배에 달한다고 한다. 🚀 돌이켜보면 무분별한 무단투기처럼 폐기물 처리 코드가 순식간에 불어나는 양상과 닮아 있다.

하지만 코드가 늘어난 만큼 유지보수 비용도 정비례로 폭발한다. 소프트웨어 컨설턴트 제임스 쇼어가 지적했듯, AI로 코드를 두 배 빨리 짜더라도 유지보수 비용이 그만큼 줄어들지 않으면 약 5개월 뒤 생산성은 도입 전 수준으로 곤두박질친다.

AI를 쓰다 중단해도 이미 쌓인 쓰레기 코드의 유지보수 부담은 영구적으로 남는다. 속도 이득은 일시적이지만, 부채는 영원하다는 뜻이다.

멈출 줄 모르는 장황한 답변과 헛소리

에이전트에게 버그 수정을 요청할 때마다 돌아오는 클로드 특유의 장황한 답변, 이른바 'Claude-isms'를 마주하면 진이 빠진다. "You're absolutely right!

This function is load-bearing. It's not X.

It's Y..." 같은 쓸데없이 긴 텍스트가 화면을 도배한다. AI는 본질적으로 수많은 판단 콜(Judgment call)을 내리며 코드를 짜 내려간다.

객체 스프레드를 어떻게 할지, 타입을 어떻게 대충 때울지 전부 모델 마음대로다. 🤖

AI가 데이터를 묶을 때 선호하는 `const byId = users.reduce((acc, user) => { acc[user.id] = user; return acc; }, {} as Record

결국 AI 시대의 개발자 직무는 더 이상 타이핑러가 아니다. 500줄의 생성된 코드 중 "우리에겐 30줄이 필요하다"고 냉정하게 솎아내는 것, 즉 무엇이 존재할 가치가 있는지 결정하는 것이 진정한 핵심 역량이 되었다. 💡

챗봇에 대충 명령을 던지는 시대는 끝났다. 에이전트를 효과적으로 통제하고 지휘하지 못하면 우리는 결국 AI가 배설한 코드의 하수인이 될 뿐이다.

🔥 AI 시대의 치명적인 생산성 착시

코드 생산이 공짜가 되었다고 좋아할 일이 아니다. 읽는 것, 이해하는 것, 앞으로 수년간 유지보수하는 것은 전혀 공짜가 아니며 오히려 더 비싸졌다.

AI가 만들어낸 저품질 코드를 무분별하게 병합하는 순간, 우리는 속도 이득을 영구적인 기술 부채와 교환하는 어리석음을 범하게 된다.

에이전트를 길들이는 첫 번째 무기, Attention Span

마크다운으로 에이전트의 입을 틀어막기

에이전트는 기본적으로 말이 너무 많다. 그리고 쓸데없이 살을 붙여서 코드를 망친다.

이 장황한 출력을 제어하기 위해 등장한 개념이 바로 **'Attention Span'**이다. 마크다운 파일들의 집합으로 구성된 이 도구는 에이전트에게 답변을 어떤 식으로 출력해야 하는지 뼈 때리는 지침을 내려준다.

Claude Code에서는 출력 스타일로 간단히 설치할 수 있고, 다른 에이전트에서도 `AGENTS.md` 파일을 통해 쉽게 연동할 수 있다. 📝

제공되는 스타일 중 **Spartan(스파르탄)**은 정말 raw한 런다운 방식의 답변만 원할 때 쓴다. 감탄사나 장황한 설명은 일절 배제한다.

**Attention-kind**는 상태 업데이트와 체크리스트를 포함해 핵심 답변이 먼저 나오고 짧은 포인트들을 한눈에 스킴할 수 있게 도와준다. 소셜 앱 데이터베이스 선정 같은 질문을 던졌을 때, 기존에는 수백 단어짜리 장황한 에세이가 나왔다면 이 스타일을 적용하면 몇 초 만에 읽을 수 있는 간결한 가이드가 완성된다.

미리 슬롭이 코드가 되기 전에 싹수를 노란색으로 만들어버리는 셈이다. 에이전트가 헛소리를 시작하려고 할 때 마크다운 지시사항으로 멱살을 잡고 본론만 말하게 강제하는 효과를 낸다.

코딩하기 전에 생각을 먼저 하게 만드는 장치이자, 개발자가 불필요한 텍스트 읽기에 허비하는 시간을 극적으로 줄여주는 실용적인 방패다. 🛡️

스파르탄 스타일로 정보의 밀도 높이기

정보의 밀도가 낮으면 AI와의 협업은 재앙이 된다. 에이전트가 늘어놓는 친절한 설명들은 대부분 독소다.

"You're absolutely right!"으로 시작하는 아첨을 듣고 싶어서 에이전트를 쓰는 게 아니다. 정확하고 간결한 코드 스니펫과 핵심 로직만 받아내야 한다.

Attention Span은 바로 그 군더더기를 도려내는 칼슘 같은 존재다.

마크다운 파일 몇 줄로 에이전트의 성향을 교정할 수 있다는 건 엄청난 행운이다. 모델이 제멋대로 살을 붙여서 1,000줄짜리 쓰레기를 만들기 전에, "필요한 최소한의 라인만 작성하라"고 목줄을 채워야 한다.

🐕‍🦺 그렇지 않으면 에이전트는 끊임없이 새로운 추상화를 발명해내고, 우리는 그 괴기스러운 구조를 해독하느라 밤을 새워야 한다.

결국 에이전트를 다루는 기술은 프롬프트의 현란함이 아니라 제어력의 단단함에서 온다. 불필요한 출력을 원천 차단하는 스타일 설정을 통해, 우리는 AI를 말 많은 비서가 아니라 묵묵히 일하는 도구로 되돌려 놓을 수 있다.

그것이 바이브 슬롭의 시대에 살아남는 첫 번째 생존 전략이다.

📊 데이터로 보는 AI 코드의 명암

상위 1%의 개발자는 하루에 일반 개발자 평균의 46배에 달하는 코드를 생성하고 주당 풀 리퀘스트 병합 횟수도 15배에 달한다. 하지만 이 압도적인 생산성 수치 뒤에는 버그와 보안 취약점이 가득한 '바이브 슬롭'이 전 세계 코드 저장소로 밀려 들어오는 어두운 단면이 함께 존재한다.

코드의 군더더기를 도려내는 Andrej Karpathy Skills

코딩 전에 생각하게 만드는 3가지 규칙

안드레 카르파시가 지적한 불만 사항들을 하나로 응축해 파일 하나로 만든 공개 저장소, **'andrej-karpathy-skills'**는 GitHub에서 이미 20만 개 이상의 스타를 기록하며 폭발적인 반응을 얻고 있다.

이 저장소가 제시하는 4가지 규칙 중 핵심은 명확하다. 첫째, **Think before coding**.

가정하지 말고 모호하면 물어보라. 둘째, **Simplicity first**.

이슈를 고치는 라인만 바꾸고 나머지는 건드리지 마라. 셋째, **Goal-driven execution**.

그냥 고쳐달라 하지 말고 테스트를 통과시키는 명확한 성공 기준을 쥐어주라. 🎯

"로그인 버그를 고쳐줘"라고 모호하게 던지면 모델은 온갖 상상의 나래를 펼치며 관련 없는 파일 수십 개를 난장판으로 만들어놓는다. 대신 버그를 재현하는 테스트 코드를 먼저 던져주고, "이 테스트를 초록색으로 만들어라"라는 확실한 성공 기준을 부여해야 한다. 이 철학이야말로 에이전트가 엉뚱한 길로 폭주하는 걸 막아주는 가장 강력한 브레이크다.

다만 마크다운 파일 형태의 지시사항은 한계가 명확하다. 컨텍스트가 커지고 세션이 길어지면 지능형 모델들도 지시사항을 슬쩍 무시하고 자기 마음대로 코드를 짜기 시작한다.

말로만 주의를 주는 방식에는 구멍이 뚫리기 마련이다. 그래서 우리에게는 말 안 듣는 에이전트를 강제로 멈춰 세울 물리적인 채찍이 필요하다. ⚡

단순성 우선 원칙으로 레거시 지키기

AI는 가만히 두면 레고 블록을 무한대로 조립하는 아이처럼 행동한다. 기존에 잘 돌고 있는 모듈을 갑자기 리팩터링하겠다고 나서고, 전혀 필요 없는 제네릭과 추상화 계층을 도입한다.

Simplicity first 원칙은 바로 이 쓸데없는 유연성 집착을 처단한다. 고치라고 한 곳만 고치고, 나머지는 손대지 말라는 엄격한 락(lock)을 건다.

개발 현장에서 가장 끔찍한 순간은 남이 짠 지저분한 코드를 이어받을 때인데, 이제는 내가 시키지 않았는데도 AI가 알아서 그런 지저분한 코드를 매일 생산해내고 있다. 🤦‍♂️ 기존 스타일을 그대로 유지하고 최소한의 Diff만 남기게 하는 것이 진짜 실력 있는 엔지니어링이다.

AI에게 더 많은 코드를 짜게 하는 것은 능력이 아니라 재앙의 원인이다.

코드베이스의 순수성을 지키려면 에이전트의 자율성을 제한해야 한다. 크고 복잡한 시스템일수록 단순함은 최고의 미덕이다.

Karpathy Skills가 제안하는 규칙들은 단순한 코딩 가이드가 아니라, AI라는 통제 불능의 기관차 선로에 박아두는 말뚝과도 같다.

💡 Karpathy Skills 핵심 요약

  • 모호한 요청을 금지하고, 코딩 전에 선택지를 먼저 표면화하게 만든다.
  • 불필요한 추상화나 파일 생성 없이, 오직 이슈를 고치는 라인만 최소한으로 수정한다.
  • 단순한 지시를 넘어 명확한 테스트와 성공 기준(Success criteria)을 부여해 에이전트를 통제한다.

말로 안 되면 강제로, Anti-slop과 린터의 압박

조건부 객체 스프레드와 모호한 파라미터 금지

마크다운 지시사항은 모델이 잊어버리거나 무시할 수 있지만, 실패하는 **린트(Lint) 명령어**는 절대 무시하지 못한다. JavaScript/TypeScript용 린터인 Oxlint 같은 도구를 활용해 프로젝트 전역에 엄격한 규칙을 박아두는 이유가 여기에 있다.

AI가 눈 질끈 감고 생성해내는 쓰레기 패턴들을 린터가 실시간으로 잡아내 에러를 뿜어내도록 강제하는 것이다. 🛑

대표적인 규칙 첫 번째는 조건부 객체 스프레드 방지다. AI는 `const options = { ...(timeout !== undefined ?

{ timeout } : {}) };` 같은 기괴하고 가독성 떨어지는 코드를 짜는 걸 아주 좋아한다. 이 규칙을 켜면 에이전트는 어쩔 수 없이 `const options: { timeout?: number } = {}; if (timeout !== undefined) { options.timeout = timeout; }` 형태로 훨씬 명확하고 리뷰하기 쉬운 코드를 다시 토해내야 한다.

두 번째는 모호한 파라미터 방지다. `function save(value: object) {}`처럼 무엇을 던지는지 알 수 없는 멍청한 코드를 린터가 즉각 차단한다.

유저를 저장한다면 반드시 `type User = { id: string; name: string; }; function save(value: User) {}` 형태로 명시하도록 강제한다. 언어의 타입 시스템과 린터의 규칙을 결합할 때 비로소 AI의 방종을 통제할 수 있다.

완료 전 검증으로 가짜 성공 선언 차단하기

GitHub의 `superpowers` 레포지토리에 있는 'verification-before-completion' 스킬은 에이전트의 버릇을 고치는 끝판왕이다. 에이전트가 작업 끝났다고 "Done!", "Fixed!"를 외치기 전에 반드시 거쳐야 할 3단 콤보 규칙을 강제한다.

첫째, 어떤 명령어가 이 주장을 증명하는가? 둘째, 메모리에서 그것을 신선하게 직접 실행했는가?

셋째, 전체 출력 결과와 exit code를 온전히 읽었는가? 이 증거를 첨부하기 전에는 절대 완료를 선언하지 못한다. 📋

AI는 원래 "Done was just the likeliest next word", 즉 문맥상 다음에 올 가장 그럴듯한 단어로 "완료되었다"를 뱉어내는 경향이 있다. 실제로 작동하는지 테스트도 안 해보고 입으로만 다 고쳤다고 사기를 치는 셈이다. 😤

린트 통과 여부, 타입 체크, 깨끗한 diff만 허용하고 "Everything should work now" 같은 위슬 워드(whistle word)를 원천 금지하는 것만이 바이브 슬롭을 막는 유일한 길이다.

에이전트를 믿지 마라. 의심하고, 검증하고, 또 증거를 요구하라. 린터와 자동화된 테스트 파이프라인이야말로 인간 개발자가 AI라는 거대한 파도 속에서 정신을 차리고 생존할 수 있는 유일한 방주다.

본문 이미지 1

제주삼다수 그린 무라벨, 2L, 12개

이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

코드를 찍어내는 속도보다 그것을 검증하고 걷어내는 비용이 더 커진 시대다. AI 에이전트가 만들어내는 달콤한 생산성의 환상에 취해 쓰레기 코드를 방치한다면, 우리의 소프트웨어 생태계는 멀지 않은 미래에 스스로 무너질 것이다.

에이전트에게 쥐여줄 더 강력한 프롬프트를 찾기 전에, 우리의 코드베이스를 지켜줄 단단한 린터와 규칙부터 점검할 때다.

우리는 코드를 타이핑하는 사람이 아니라, 무엇이 존재할 가치가 있는지 결정하는 사람이어야 한다.

#AI코딩 #바이브슬롭 #코드품질 #개발자 #생산성 #안드레카르파시 #AI에이전트 #코드리뷰 #클린코드 #소프트웨어공학 #코딩꿀팁 #개발공부 #코딩테스트 #프롬프트엔지니어링 #Claude #AI모델 #기술블로그 #코드정리 #개발도구 #생산성도구 #프로그래밍 #IT트렌드 #개발환경 #코드최적화 #코드리팩토링 #린터 #에이전트지능 #버그수정 #기술부채 #코드베이스

댓글 쓰기

0 댓글