대규모 언어모델(LLM)이 코드를 작성해 주는 시대가 오면서, 개발자들은 코드 유지보수의 부담을 AI에 넘기려는 유혹에 빠지기 쉽습니다. 'DRY(Don't Repeat Yourself)' 원칙을 무시하고 반복적인 코드를 생성해도, 나중에 AI가 알아서 수정해 줄 것이라는 안일한 생각 때문입니다. 하지만 이러한 접근 방식은 예상치 못한 문제를 야기할 수 있습니다.
한 개발자는 프로젝트에서 동일한 접근 권한 확인 로직이 여러 곳(라우트 핸들러, 백그라운드 작업, API 엔드포인트, 웹훅 등)에 필요할 때마다 LLM에 요청했습니다. LLM은 매번 작동하는 코드를 생성했고, 개발자는 이를 그대로 병합했습니다. 결과적으로 '사용자 활성화 여부, 권한, 정지 상태, 계정 상태' 등을 확인하는 거의 동일한 조건문이 여러 파일에 복사-붙여넣기 되었습니다. 개발자는 나중에 AI가 이 모든 것을 처리해 줄 것이라고 생각했지만, 이는 큰 착각이었습니다.
문제는 LLM이 코드를 '진공 상태'에서 생성하지 않는다는 점입니다. LLM은 현재 코드베이스, 기존 패턴, 최근 변경 사항을 학습합니다. 따라서 개발자가 반복적이고 비효율적인 코드를 병합할수록, LLM은 그 패턴을 '이 프로젝트의 스타일'로 인식하게 됩니다. 예를 들어, 다섯 번째 엔드포인트를 요청하면 LLM은 기존의 복사된 조건문들을 기반으로 또 다른 복사본을 생성합니다. 나중에 코드 리팩토링을 요청해도, LLM은 기존의 나쁜 패턴을 보존하려 할 수 있습니다. 결국 개발자는 AI에게 점점 더 나쁜 코딩 습관을 가르치는 셈이 됩니다.
이러한 '코드 스멜(code smell)'은 쌓여서 나중에는 LLM의 도움만으로는 해결하기 어려운 지경에 이르게 됩니다. 중복된 조건문, 거대한 '신(god) 함수', '나중에 고치겠다'는 식의 임시방편적인 병합은 모두 다음 프롬프트에 영향을 미치는 신호가 됩니다. 결국 개발자는 직접 팔을 걷어붙이고 코드를 수정해야 하는 상황에 직면하게 됩니다. 이는 유지보수 작업을 AI에 아웃소싱하려던 원래 의도와는 정반대의 결과입니다. LLM은 개발자가 하는 모든 것을 흡수하고 그대로 반영하므로, 처음부터 좋은 코드를 작성하여 좋은 습관을 가르치는 것이 중요합니다.