Vibe Coding 이후가 진짜다—AI가 짠 코드를 설계로 길들이는 법

Vibe Coding 이후가 진짜다—AI가 짠 코드를 설계로 길들이는 법

속도는 AI가 해결했다, 이제 남은 문제는 '내가 무엇을 만들었는지 아는가'다

Vibe Coding 지식 부채 Slot Pattern OCP ESLint 커스텀 룰 컴포넌트 설계 AI 코딩 품질
광고

AI 코딩 도구가 일상이 된 지금, 개발자들은 이상한 역설에 빠져 있다. 코드는 그 어느 때보다 빠르게 쌓이는데, 그 코드를 온전히 이해하는 사람은 점점 줄어들고 있다. dev.to에 올라온 한 16세 개발자의 고백은 이 역설을 날카롭게 드러낸다. Cursor와 Claude를 총동원해 한 달 만에 200개가 넘는 파일을 만들고 30개국 사용자를 확보했지만, 정작 자신이 짠 인증 미들웨어를 설명하지 못했다는 것. 코드는 작동했고, 테스트는 통과했고, 배포는 성공했다. 하지만 그는 자신이 만든 시스템을 몰랐다.

이것이 Vibe Coding의 그림자다. Andrej Karpathy가 명명한 이 개발 방식—AI가 생성한 코드를 완전히 이해하지 않고도 빠르게 출시하는 흐름—은 분명히 강력하다. 진입 장벽을 낮추고, 혼자서도 풀스택 제품을 만들 수 있게 해준다. 문제는 코드가 깨졌을 때 시작된다. 연구에 따르면 AI 생성 코드에는 사람이 작성한 코드보다 2.74배 많은 보안 취약점이 존재한다. AI는 당신의 시스템의 위협 모델을 모른다. 그리고 Vibe Coding 중인 당신도 종종 모른다. 그래서 취약점은 자신 있게, 조용히 프로덕션에 올라간다.

기술 부채(Technical Debt)는 익숙한 개념이다. 지금 지름길을 택하면 나중에 갚아야 한다는 것. 하지만 Vibe Coding이 만들어내는 건 그보다 더 은밀한 지식 부채(Knowledge Debt)다. 기능을 이해 없이 출시할 때마다, 내가 아는 것과 시스템이 실제로 하는 것 사이의 간격이 벌어진다. 이 간격은 보이지 않다가 갑자기 드러난다. 새 팀원이 코드를 물어볼 때, 프로덕션 장애가 처음 보는 방식으로 터질 때, 보안 연구자가 취약점을 발견했을 때. 더 무서운 건 이 간격이 복리로 쌓인다는 사실이다. 이해 없이 출시할수록 나중에 이해하기가 더 어려워진다.

그렇다면 컴포넌트 설계 레벨에서 이 문제는 어떻게 나타날까. velog에 공유된 상품 카드 리팩토링 사례는 Vibe Coding 이후에 필요한 설계 근육을 잘 보여준다. 기존 ProductCard 컴포넌트는 아이콘 필터링 로직, 스타일, 노출 조건을 모두 내부에서 처리했다. AI가 빠르게 뽑아줄 법한 구조다—작동하고, 깔끔해 보이고, 일단은 문제없다. 하지만 아이콘 종류가 추가될 때마다, 필터링 로직이 바뀔 때마다 카드 컴포넌트 전체를 손대야 했고, 7종의 카드에 동일한 패턴이 반복되면서 변경 비용이 선형으로 늘었다.

해법은 Slot Pattern이었다. Open-Closed Principle(OCP)—확장에는 열려 있고, 수정에는 닫혀 있어야 한다—을 컴포넌트 설계에 적용한 것이다. 핵심 아이디어는 단순하다. ProductCard는 아이콘이 무엇인지 알 필요가 없다. 그냥 ReactNode를 받아서 렌더링할 자리만 선언한다. 아이콘의 비즈니스 로직(유효 기간 필터링, 최대 노출 개수 제한 등)은 전용 IconBadge 컴포넌트가 캡슐화하고, 상위 컨테이너에서 둘을 조합해 슬롯에 주입한다. 이렇게 되면 카드를 건드리지 않고도 새 아이콘 유형을 추가하거나 스타일을 바꿀 수 있다. 컴포넌트 간 경계가 명확해지고, '이 컴포넌트가 무엇을 아는가'라는 질문 자체가 설계 기준이 된다.

설계 원칙만으로는 부족하다. 팀 단위에서 이 원칙이 일관되게 지켜지려면 자동화된 품질 게이트가 필요하다. velog의 커스텀 ESLint 플러그인 제작기는 그 실전 예시다. 세 가지 규칙이 핵심이다. 첫째, match-context-suffixuseContext로 받는 변수에는 반드시 Context 접미사를 붙여야 한다(authauthContext). 일반 변수와 Context 데이터를 이름만으로 구분하게 만든다. 둘째, match-array-list-suffix—배열 타입 변수에는 List를 붙인다(membersmemberList). 타입 추론 없이도 구조를 읽을 수 있게 된다. 셋째, match-handler-naming—내부 구현 함수는 handle로, Props로 넘기는 인터페이스는 on으로 시작한다. 함수의 역할이 이름에 드러나면 코드 리뷰 비용이 줄고, AI가 생성한 코드도 이 컨벤션 안에서 자동 교정된다.

세 가지 사례가 하나의 방향을 가리킨다. AI는 이미 속도 문제를 해결했다. 이제 병목은 다른 곳에 있다. '내가 만든 코드를 내가 설명할 수 있는가', '컴포넌트가 알아야 할 것과 몰라야 할 것을 의도적으로 설계했는가', '팀의 코드 컨벤션이 자동화된 규칙으로 강제되고 있는가'. 이 세 질문에 답하지 못하면, Vibe Coding의 속도는 그냥 지식 부채를 쌓는 속도가 된다.

AI 코딩 도구를 가장 잘 쓰는 개발자는 가장 많이 쓰는 사람이 아니다. AI를 '매우 빠른 주니어 개발자'처럼 대하는 사람—모든 출력을 리뷰하고, 왜 그렇게 짰는지 묻고, 자기가 설명할 수 없는 코드를 거부하는 사람이다. Slot Pattern으로 컴포넌트 경계를 설계하고, 커스텀 ESLint 룰로 컨벤션을 자동 강제하는 것은 그 '의도적인 느림'을 시스템 레벨에서 구현하는 방식이다. 속도는 포기하지 않으면서, 지식 부채만 쌓이지 않게 막는 구조. 결국 Vibe Coding 이후를 살아남는 법은 AI를 덜 쓰는 게 아니라, AI가 만든 코드를 책임질 설계 근육을 키우는 것이다.

출처

더 많은 AI 트렌드를 Seedora 앱에서 확인하세요