최종 업데이트: 2026년 10월
AI가 생성한 코드를 정리한다는 것은 순서대로 세 가지를 의미합니다. 첫째, 실제로 무엇이 있는지 파악하고, 둘째, 무엇을 생존시킬 가치가 있는지 결정하며, 셋째, 다음 배치가 깨끗하게 도착하도록 안전장치(guardrails)를 마련하는 것입니다. 대부분의 팀은 도구링(tooling)부터 시작하지만, 이 문제에서 벗어나는 팀들은 트리아지(triage)부터 시작합니다.
이 플레이북은 에이전트가 작성한 코드가 왜 성능 저하(degrade)되는지, AI 의존도가 높은 코드베이스를 어떻게 트리아지할 수 있는지, 실제로 어떤 정리 옵션들이 존재하는지, 그리고 이 문제가 재발하는 것을 어떻게 막을 수 있는지를 다룹니다.
AI 생성 코드가 부채(debt)가 되는 이유
코딩 에이전트들은 2025년과 2026년에 엄청난 양의 코드를 배포했습니다. 그중 상당수는 작동합니다. 하지만 문제는 나중에, 누군가가 그것을 수정해야 할 때 나타나며, 이들은 알아볼 수 있는 패턴을 따릅니다:
카드 집 구조입니다. 깨지기 쉽고 유연성이 부족합니다. 한 가지를 변경하는 것만으로도 시스템 전체에 위험을 초래할 수 있기 때문에, 팀들은 아예 건드리지 않는 방식으로 대처합니다. 이 코드는 첫 번째 수정이 발생하기 전까지는 작동하지만, 이는 설계상 유지보수가 되지 않음을 의미하는 또 다른 표현입니다.
검증할 수 없습니다. 스파게티 구조(Spaghetti structure) 때문에 의미 있는 테스트 커버리지를 사후적으로 적용하기가 거의 불가능합니다. 얽힌 코드의 현재 동작을 단언하는 테스트는 대부분 그 복잡한 구조를 그대로 고정시킬 뿐입니다.
정보 과부하 속에 신호가 묻힙니다. 에이전트들은 너무 많은 보일러플레이트(boilerplate) 코드를 생성하여, 리뷰어들이 역대 가장 많은 양의 코드를 읽으면서도 심각한 버그를 놓칩니다. 리뷰 피로도는 생성된 볼륨에 직접적인 함수 관계를 가집니다.
자체 실패를 숨깁니다. 에이전트가 오류를 만났을 때, 그것은 종종 증상이 사라질 때까지 또 다른 검사(check)와 재시도(retry)를 추가하는 경향이 있습니다. 근본적인 문제는 그대로 남아 있고 그 위에 코드가 더 쌓입니다. 동일한 호출 주변에 중첩된 try/except 블록으로 에이전트 의존도가 높은 코드베이스를 grep 검색해보면, 보통 이러한 고고학적 흔적을 발견하게 됩니다.
모든 곳에서 로직을 중복합니다. 같은 문제가 여러 장소에서 다르게 해결되므로, 한 번의 수정은 버그의 사본들을 뒤에 남기게 됩니다.
과도하게 설계하고, 의존성을 만듭니다. 단순한 기능이 프레임워크가 됩니다. 그리고 그 결과물을 유지할 수 있는 유일한 주체가 해당 에이전트를 만든 공급업체라면, 추가 단계만 더해진 컨설팅 회사식 종속성(consulting-firm lock-in)을 재현하는 것입니다.
이 모든 것이 에이전트가 실수였다는 의미는 아닙니다. 이는 생성 자체가 어려운 부분이 아니었다는 것을 의미합니다. 그 결과를 효과적이고, 유지보수가 가능하며, 변경하기 안전하게 만드는 것이 어려운 부분입니다.
어떤 클린업 도구를 건드리기 전에, 영향 범위(blast radius)를 파악해야 합니다. 모듈 또는 서비스당 다음 세 가지 질문을 던지세요:
- 반드시 살아남아야 하는 비즈니스 로직을 담고 있는가? 그렇다면, 단순히 느낌에 의존한 재작성이 아니라 동작 보존 처리(behavior-preserving treatment)가 필요합니다.
- 다른 것이 이 부분에 의존하는 것이 있는가? 논리가 중복되어 있다면, 한 곳에서의 수정이 다른 다섯 곳의 버그를 살아남게 할 수 있습니다. 리팩토링 도구가 필요하기 전에 호출 지점 맵(call-site map)이 필요합니다.
- 오늘날 검증할 수 있는가? 동작이 보존되었다는 것을 증명할 방법이 없다면, 어떤 클린업 작업도 도박입니다. '리팩토링해야 한다'와 '교체해야 한다'를 가르는 것은 코드 품질이 아니라 검증 능력(Verification capability)입니다.
분류의 결과물은 세 가지로 나뉩니다: 제자리에 수정할 가치가 있는 코드, 통째로 교체할 가치가 있는 코드, 그리고 앞의 두 가지가 가능해질 때까지 격리하고 건드리지 말아야 할 코드입니다.
2단계: 각 버킷에 맞는 적절한 도구 클래스 선택
서로 다른 클린업 작업들은 근본적으로 다른 도구를 필요로 하며, 대부분의 나쁜 결과는 한 종류의 도구를 다른 종류의 작업에 사용하는 데서 발생합니다.
규칙 기반 리팩토링 엔진(OpenRewrite와 그 생태계, JS/TS를 위한 Codemod 및 jscodeshift 계보)은 대규모 코드베이스 전반에 걸친 기계적이고 반복 가능한 변환(의존성 업그레이드, API 마이그레이션, 패턴 재작성 등)에 탁월합니다. 이들은 결정론적이며 감사 가능합니다. 자신만의 레시피가 없는 논리는 풀지 못할 것입니다.
코딩 어시스턴트(Coding assistants) (Copilot, Cursor, Claude Code 및 유사 도구)는 로컬(local), 감독 하의 정리 작업에는 효과적입니다. 즉, 여기서는 함수를, 저기서는 모듈을 수정하며 개발자가 모든 변경 사항(diff)을 읽어보는 방식입니다. 그러나 이들은 전체 규모의 부채 감소(fleet-wide debt reduction)에는 적합하지 않은 도구입니다. 왜냐하면 문제를 야기했던 검토 병목 현상(review bottleneck) 자체가 여전히 병목으로 남아있기 때문입니다.
**거버넌스 기반 마이그레이션 플랫폼(Governed migration platforms)**은 정리 작업을 일련의 편집 작업이 아닌 프로그램처럼 취급합니다. 즉, 인간이 승인하는 계획을 세우고, 검토 가능한 이정표(milestone)로 작업을 배포하며, 원래 시스템에 대해 동작을 검증합니다. Morph by Modelcode는 이러한 모델을 기반으로 구축되었으며, 중복 문제에 대한 답변은 구조적입니다. Morph가 작성하는 모든 것은 완전히 새로운 것이기 때문에, 전체 마이그레이션은 데드 코드(dead code)와 중복된 로직(duplicated logic)이 없는 신선한 코드베이스를 생성하며, 모듈식 마이그레이션의 경우 주변 레거시 코드가 그대로 유지되는 동안 Morph가 제공하는 모든 것은 깨끗합니다. 또한 각 이정표를 검증하는 데 사용했던 통합 테스트(integration tests)도 코드와 함께 배포되므로, 검증 증거가 리포지토리(repo)에 남게 됩니다. 어시스턴트와의 트레이드오프는 신중함입니다. 자동 완성이 아니라 거버넌스와 증명을 얻게 됩니다.
솔직한 경험칙은 이렇습니다. 부분적인 정리 작업에는 어시스턴트를, 기계적인 전체 검토(mechanical sweeps)에는 규칙 엔진을, 부채가 구조적이며 동작이 가정되는 것이 아니라 증명되어야 할 때는 거버넌스 플랫폼을 사용해야 합니다.
단계 3: 기본 상태를 검증 가능하게 만들기 (Make verified the default state)
어떤 도구를 선택하든, 프로세스를 변경하지 않는 정리 작업은 다음 정리 작업을 예약할 뿐입니다. 이 구덩이(hole)에서 벗어나려는 팀들은 동일한 가드레일(guardrails)에 수렴합니다:
- 생성 전 인간의 승인을 받은 계획(A human-approved plan before generation). 사람 또는 에이전트에 의해 코드가 작성되기 전에 범위(Scope), 목표(Target), 그리고 수용 기준(Acceptance Criteria)을 정의해야 합니다.
- 그 계획에 매핑되는 작고 검토 가능한 변경 사항(Small, reviewable changes mapped to that plan). 리뷰하기에는 너무 큰 변경 사항은 신뢰하기에도 너무 큽니다.
- 단순히 단위 테스트(unit tests)가 아니라 행동 검증(Behavioral verification). 이전 경로와 새 경로를 동일한 실제 여정(real journeys)을 통해 실행하고 실제로 발생하는 것을 비교해야 합니다. 엉킨 코드에서 녹색 단위 테스트가 나온 것은 거의 증명하지 못합니다. 동일한 관찰된 행동(identical observed behavior)이 당신이 신경 쓰는 것을 증명합니다.
- 모든 변경 사항에 근거 자료 첨부(Evidence attached to every change). 기록 담당 검토자(reviewer of record), 실행된 테스트, 그리고 결과물입니다. 감사관이나 미래의 유지보수자가 "왜 이 변경이 이루어졌나요?"라고 물었을 때, 그 답은 이미 존재해야 합니다.
- 패턴 결정은 당신이 해야 합니다(You decide the patterns). 어떤 프레임워크를 표준화할지, 무엇을 사용 중단(deprecate)하고 영원히 버릴지를 결정해야 합니다. 에이전트가 결정하는 순간, 당신은 다시 의존성 함정(dependency trap)에 빠지게 됩니다.
FAQ
AI 생성 코드를 망가뜨리지 않고 정리하려면 어떻게 해야 하나요?
우선 분류(Triage)부터 하십시오. 비즈니스 로직을 담고 있는 코드와 단순한 구조물(scaffolding)을 분리해야 합니다. 오늘날 검증할 수 있는 부분만 제자리에 수정하고, 그렇지 않은 부분은 통째로 교체해야 합니다. 원래 시스템과의 행동 비교(동일한 입력, 동일한 관찰된 출력 및 부작용)만이 아무도 완전히 이해하지 못하는 코드에 대한 유일하게 신뢰할 수 있는 안전장치입니다.
AI 생성 기술 부채(technical debt)는 일반적인 기술 부채와 다른가요?
주로 속도와 형태에서 다릅니다. 인간이 작성한 부채보다 더 빠르게 축적되며, 로직을 중앙 집중화하기보다는 중복시키고, 재시도 계층 뒤에 실패를 숨깁니다. 해결 원칙은 고전적이지만, 그 양(volume)은 그렇지 않습니다.
AI가 작성한 코드를 리팩토링해야 할까요, 아니면 재생성해야 할까요?
검증 가능하고 구조적으로 복구 가능하다면(salvageable), 규칙 기반 도구와 지도형 어시스턴트(supervised assistants)를 사용하여 리팩토링합니다. 하지만 검증이 불가능하거나 중복 문제가 구조적인 경우, 거버넌스 하에 재생성(승인된 계획, 마일스톤 검토, 행위 검증)하는 것이 일반적으로 '고대 유적 발굴'보다 비용 효율적입니다. 결정적인 질문은 동작(behavior)이 보존되었음을 증명할 수 있는지 여부입니다.
팀들은 AI 에이전트가 작성한 코드를 장기적으로 어떻게 유지 관리하나요?
검증을 기본 상태로 만듦으로써 가능합니다. 즉, 모든 변경 사항에 통합 테스트(integration tests)를 포함하고, 모든 병합(merge)에 증거를 첨부하며, 인간의 승인(human sign-off)을 필수 관문(hard gate)으로 삼는 것입니다. 에이전트 출력을 공급업체 코드처럼 취급하는 팀(검토되고, 검증되며, 소유권이 있는)은 이를 잘 유지 관리합니다. 반면, 완성된 작업물처럼 취급하는 팀은 그렇지 못합니다.