AI가 만든 코드가 점점 복잡해질 때 멈춰야 하는 신호
AI에게 계속 수정을 맡길수록 코드가 복잡해지고 버그가 늘어날 때, 더 진행해도 되는 상황과 멈춰서 정리해야 하는 신호를 구분합니다.
AI로 코딩할 때 처음 며칠은 속도가 무섭게 납니다. 화면이 나오고, 버튼이 붙고, 데이터가 저장되고, 혼자서는 엄두가 안 나던 것들이 하나씩 생깁니다.
그러다 어느 순간부터 속도가 꺾입니다. 한 가지를 고치면 두 가지가 깨지고, AI는 "이제 해결했습니다"라고 말하지만 새 에러가 생깁니다. 파일 이름은 늘어나고, 비슷한 코드가 여러 군데 생기고, 내가 만든 서비스인데 구조가 낯설어집니다.
이때 필요한 것은 더 센 프롬프트가 아닐 수 있습니다. 잠깐 멈춰야 하는 신호를 알아차리는 것이 먼저입니다.
신호 1. 같은 기능을 처리하는 코드가 여러 군데 있다
AI는 요청을 받을 때마다 가장 빠른 길로 코드를 추가하려는 경향이 있습니다. 그래서 이미 있는 함수를 재사용하기보다 비슷한 함수를 새로 만들 때가 있습니다.
예를 들어 날짜 포맷 함수가 utils/date.ts에도 있고, 예약 페이지 안에도 있고, 관리자 페이지 안에도 생깁니다. 처음에는 문제 없어 보이지만 나중에 형식을 바꾸려고 하면 세 군데를 다 찾아야 합니다.
이런 신호가 보이면 새 기능을 더 붙이기 전에 같은 역할의 코드를 모아야 합니다.
- 같은 API 호출 코드가 페이지마다 반복된다
- 버튼 스타일이 컴포넌트마다 다르게 복사되어 있다
- 결제 금액 계산이 여러 파일에 흩어져 있다
- 타입 이름은 다른데 내용은 거의 같다
중복은 당장 에러를 만들지는 않지만, 다음 수정의 비용을 계속 올립니다.
신호 2. AI가 고칠수록 파일이 길어진다
처음에는 100줄짜리 파일이었는데 어느새 800줄이 되어 있다면 조심해야 합니다. 특히 한 파일 안에 화면, 상태 관리, 데이터 요청, 에러 처리, 스타일 조건이 모두 들어가면 AI도 사람도 맥락을 놓치기 쉽습니다.
파일이 길다는 것 자체가 무조건 문제는 아닙니다. 문제는 그 파일을 바꿀 때마다 예상하지 못한 곳이 같이 바뀌는 느낌입니다.
예를 들어 예약 페이지에서 버튼 문구만 바꾸려 했는데 예약 저장 로직까지 같이 건드리게 된다면, 파일 역할이 너무 커졌을 수 있습니다.
이때는 새 기능을 붙이기보다 먼저 나눌 기준을 잡아야 합니다. 화면 컴포넌트, 데이터 요청 함수, 계산 로직, 상수 문구처럼 역할을 분리하면 이후 수정이 훨씬 안정됩니다.
신호 3. 에러를 막는 코드가 계속 늘어난다
AI가 버그를 고칠 때 자주 쓰는 방식 중 하나가 방어 코드를 더하는 것입니다. 값이 없으면 빈 배열로 처리하고, 문제가 생기면 기본값을 넣고, 조건문을 추가해서 일단 화면이 안 깨지게 만듭니다.
이 방식이 항상 나쁜 것은 아닙니다. 실제 서비스에서는 방어 코드가 필요합니다. 다만 원인을 모른 채 방어 코드만 늘어나면 문제가 숨어버립니다.
이런 패턴이 보이면 멈춰야 합니다.
- undefined를 피하려는 조건문이 계속 늘어난다
- 에러 메시지는 사라졌는데 데이터가 안 보인다
- 실패했는데 성공한 것처럼 화면이 넘어간다
- 콘솔 에러를 없애기 위해 실제 검증을 건너뛴다
버그가 해결된 것과 조용히 숨겨진 것은 다릅니다. 운영 서비스에서는 조용히 실패하는 쪽이 더 위험할 때가 많습니다.
신호 4. 수정할 때마다 다른 화면이 깨진다
가장 확실한 정지 신호입니다. 로그인 문제를 고쳤더니 관리자 페이지가 깨지고, 모바일 레이아웃을 고쳤더니 데스크톱 CTA가 사라지는 식입니다.
이런 경우는 보통 코드가 서로 강하게 얽혀 있습니다. 공통 컴포넌트를 바꿨는데 여러 화면이 영향을 받거나, 전역 상태를 수정했는데 예상하지 못한 페이지까지 변하는 상황입니다.
AI에게 계속 "깨진 것만 다시 고쳐줘"라고 하면 임시 패치가 쌓입니다. 그러면 다음 수정 때 더 큰 문제가 생깁니다.
이 시점에는 기능 추가를 멈추고 영향 범위를 먼저 봐야 합니다. 어떤 파일을 바꾸면 어떤 화면이 영향을 받는지, 공통으로 쓰이는 컴포넌트가 무엇인지 확인하는 단계가 필요합니다.
신호 5. 만든 사람도 설명하기 어려워졌다
가장 현실적인 기준은 이것입니다. 내가 AI와 함께 만든 서비스인데도 "이 기능이 어디서 처리되는지" 설명하기 어렵다면, 이미 정리할 시점입니다.
개발자가 아니어도 최소한 이 정도는 말할 수 있어야 합니다.
- 사용자가 입력한 데이터가 어디에 저장되는지
- 결제 후 어떤 화면으로 돌아오는지
- 배포는 어디서 되는지
- 로그인 사용자는 어디서 관리되는지
- 문제가 생기면 어떤 로그나 화면을 봐야 하는지
이 질문에 전혀 답할 수 없다면, 새 기능을 더 만드는 것보다 현재 구조를 문서화하고 중요한 흐름을 확인하는 일이 먼저입니다. 모르는 상태에서 계속 만들면 나중에 맡기는 비용도 커집니다.
멈춘다는 건 포기한다는 뜻이 아니다
멈춘다는 말이 서비스를 버리자는 뜻은 아닙니다. 오히려 계속 만들기 위해 잠깐 정리하는 것입니다.
추천하는 멈춤 방식은 이렇습니다.
- 새 기능 요청을 잠깐 중단한다
- 현재 정상 동작하는 흐름을 적는다
- 최근 AI가 수정한 파일을 확인한다
- 같은 역할의 코드가 중복된 곳을 찾는다
- 배포와 데이터 저장이 여전히 되는지 확인한다
- 이후 수정 범위를 작게 나눠서 다시 진행한다
이 과정을 거치면 AI를 다시 쓸 때도 훨씬 잘 됩니다. AI가 문제인 것이 아니라, AI에게 줄 프로젝트 상태가 너무 흐려진 것일 수 있습니다.
정리
AI가 만든 코드가 복잡해질 때 멈춰야 하는 신호는 분명합니다.
- 같은 기능 코드가 여러 군데 생긴다
- 핵심 파일이 계속 길어진다
- 원인 해결보다 방어 코드가 늘어난다
- 수정할 때마다 다른 화면이 깨진다
- 만든 사람도 구조를 설명하기 어렵다
이 중 두세 개가 동시에 보이면 새 기능을 붙이기보다 정리부터 하는 편이 좋습니다. 바이브코딩의 장점은 빠르게 만드는 것이지만, 계속 운영하려면 중간중간 사람이 구조를 붙잡아줘야 합니다.
LastFix가 보는 지점도 여기입니다. AI가 멈춘 프로젝트를 처음부터 다시 만들기보다, 어디가 얽혔고 어디부터 풀면 되는지 먼저 진단합니다.