AI는 이제 단순한 개발 보조 도구를 넘어 코드를 생산하는 주체로 자리잡고 있다. 이로인해 소프트웨어 개발은 다시 한 번 변화의 기로에 서 있으며 이번에는 단순히 도구의 진화가 아닌 역할의 변화를 요구한다. 이러한 상황에서 필자를 비롯한 많은 개발자가 이런 상황에서 혼란을 겪고있다.

근래에는 바이브 코딩(Vibe coding)이라는 용어가 유행하고 있다. 어떤 사람은 적극적으로 지지하며 앞으로 개발자의 역할은 축소될 것이라고 주장하고, 어떤 사람은 아직 멀었다고 반박하며 조롱하기도 한다. 사실, 필자가 바이브 코딩을 했을 때는 아직 신뢰할 수 없는 부분이 많다고 느끼기도 했다. 그렇게 관심을 접어가던 중 발상이 뒤집혔다. 만약 AI가 만든 코드를 신뢰할 수 없다면, 그 코드를 쉽게 파괴하고 쉽게 다시 생산할 수 있도록 설계하면 어떨까?라는 생각이 들었다. 그리고 이 생각은 필자가 이전에 소프트웨어 파괴의 미학에서 제안한 파괴 지향 개발(Destruction-Oriented Development)과 연결되었다. 그리고 최근 여러 사람과 대화 후 이 생각에 대한 확신이 더욱 커졌다. AI가 만든 코드를 신뢰할 수 없다면, 그 코드를 쉽게 파괴하고 다시 만들 수 있도록 설계하는 것이야말로 AI 시대의 개발자가 가져야 할 태도라는 것이다.

이 글에서는 지금의 혼돈을 어떻게 바라볼지, 그리고 앞으로 우리는 어떠한 태도를 가져야 할지에 대해 이야기하고자 한다. 또한, 어쩔 수 없이 AI를 사용하는 시대가 온다면, 어떻게 맞서는게 좋을지 이야기해보려 한다. 참고로 만약 이전 글을 읽지 않았다면 한 번 읽어보기를 권장한다.

새로운 혼돈의 탄생

AI는 비즈니스에 이어 탄생한 새로운 혼돈이다. 예측할 수 없고, 통제하기 어렵고, 과정을 설명조차 할 수 없다. 과거에는 이해 가능한 코드, 설계 의도가 분명한 코드가 기준이었다면, 이제는 점차 낯설고 알 수 없는 코드가 당연해지고 있다. 자연어로 설명만 하면 코드가 생성되지만, 그 내부는 흐릿하고 불확실하다. 점차 코드를 넘어 바이너리를 생산하게 된다면 AI가 만든 코드는 왜 그렇게 동작하는지 알 수 조차 없을 것이다.

그렇기에 많은 개발자들은 혼란을 느낀다. AI가 생산해낸 유지보수하기 힘든 코드는 고치는 것도 어렵고, 신뢰하기도 어렵다. 이런 혼란스러운 상황은 개발자의 AI에 대한 태도를 바꿔놓아 결과적으로 염세주의적 태도, 경직된 사고, 더 나아가 패배주의까지 초래할 수 있다. 하지만 AI를 배척하던, AI에 굴복던 좋은 태도는 아니다.

“AI는 쓰레기야 쓸 필요가 없어”
“어차피 AI가 코드를 짜주는 데 뭐하러 공부하지?”

이러한 태도는 앞서 ‘소프트웨어 파괴의 미학’에서 언급했던 것처럼, 디오니소스적인 힘에 굴복하는 것이다. AI는 새로운 디오니소스라고 할 수 있다. 파괴적이고 예측할 수 없으며, 그로 인해 우리는 혼돈 속에 놓인다. 그러나 이 혼돈은 처음 있는 일이 아니다. 불확실성, 비즈니스, 사람 등 과거에도 우리는 수많은 디오니소스적 힘과 마주해왔다. 그리고 그때마다 우리는 맞서 싸웠다. 포기하지 않고, 이해하려 애쓰고, 더 나은 방법을 고민했다.

이번에도 크게 다른 것은 없다. AI라는 새로운 혼돈에 맞서야 한다. 단순히 굴복하는 것이 아니라, 그 힘을 인정하고 받아들인 뒤, 어떻게 더 잘 활용할 수 있을지 고민해야 하며 이 시대 개발자가 가져야 할 새로운 자세다.

바이브 코딩이라는 새로운 흐름

바이브 코딩은 개발자가 직접 코드를 작성하지 않고, AI와의 대화만으로 코드가 생성되는 새로운 방식의 개발 행위다. 최근 SNS에서는 바이브 코딩을 지지하는 개발자와 아직 멀었다는 개발자 사이에 묘한 신경전이 벌어졌다. AI 만으로 만드는 코드엔 아직까지 많은 문제가 있고, 그 코드가 잘 동작하지 않거나 심지어 보안적인 문제가 있는 경우도 있다. 그럼에도 불구하고 이미지 생성, 글 쓰기 등의 분야에선 이미 AI를 이용한 생산이 점차 일반화되는 것처럼 바이브 코딩은 새로운 흐름으로 자리잡고 있다.

바이브 코딩에 대한 조롱
바이브 코딩에 대한 조롱

필자는 바이브 코딩이 제대로 자리를 잡기 위해선 요구사항이 바뀔 경우 관련한 것을 전부 지우고 AI가 요구사항에 따라 새롭게 다시 만들 수 있는 수준이 되어야 한다고 생각한다. 이미 다른 직군에선 이런 방식으로 AI를 사용하고 있다. 즉, AI가 생성한 콘텐츠를 수정하기보다는 결과를 보고 평가한 후 다시 만드는 것이다.

이런 방식은 본질적으로 기존의 개발 문화와 충돌한다. 한 번 만들고 버려질 코드는 당연히 코드 오너십이 약해지고, 설계에 대한 통제가 흐려진다. 당연히 재사용 측면에선 고려조차 되지 못한다. 이러한 점이 바이브 코딩의 단점이 되어 많은 비판을 받는다. 그러나 바이브 코딩의 본질은 필요한 것을 빠르게 만들고 빠르게 버리는 것이다. 그리고 그것은 후술할 파괴 지향 개발의 철학과 맞닿아 있다. 역설적으로 우리가 직접 만들지 않았기에, 더욱 쉽게 파괴할 수 있다. 그리고 다시 만들 수 있기에, 설계에 집착하지 않아도 된다. 코드란 바뀌고, 지워지고, 다시 만들어지는 것이기 때문이다.

그렇게 관점을 바꾸면 질문이 바뀐다. “AI가 만든 코드를 얼마나 신뢰할 수 있을까?”가 아닌 “AI가 만든 코드를 얼마나 쉽게 파괴할 수 있는가?”로.

파괴 지향 개발 with AI

그럼 파괴 지향 개발이란 무엇일까? 필자가 생각하는 파괴 지향 개발은 언젠가 코드가 파괴될 것이라는 사실을 받아들이고, 그것을 지향하여 개발하는 방법론이며 다음과 같은 세 가지 대원칙을 지향한다.

  • 불확실성이 있다면 가능한 만큼 불확실성을 줄인다.
  • 여러 방법을 선택할 수 있다면 파괴하기 쉬운 쪽을 선택한다.
  • 필요한 것만을 유지한다. 따라서 필요 없는 것은 전부 지운다.

대원칙에 따라 개발한다면 다음과 같은 프로세스를 따를 수 있다.

파괴 지향 개발 프로세스
파괴 지향 개발 프로세스

위와 같은 프로세스를 진행하여 내부 요인에 따른 불확실성을 줄이고 어쩔 수 없는 외부 요인으로 인한 파괴에 대비하는 것이 핵심이다.

여기서 AI를 이용한 파괴 지향 개발은 결국 파괴 가능성을 설계에 녹여내 어떻게 하면 쉽게 지우고, 쉽게 다시 만들 수 있을까라는 질문을 끊임없이 던지는 것이다. AI가 생산한 코드는 아직 신뢰할 수 없고, 유지보수하기도 어렵다. 추후 기능 변경이 발생한다면 고쳐서 쓰는 것보다 지우는 것이 경제적으로 더 효율적일 것이다. 즉, 위 프로세스에서 경계 분리를 AI가 확실하게 생산해낼 수 있는 단위로 구성하고 코드 구현은 AI가 생성한 코드를 바탕으로 파괴 가능성을 고려하여 설계하는 것이다.

먼저 불확실성에 따라 경계를 분리해야 한다. 불확실성은 변화율이며 이를 기반으로 분리하는 것이 가능하다. 기존 글에서는 이러한 불확실성을 외부 요인과 내부 요인으로 구분했다. 외부 요인은 개발자가 통제할 수 없는 것으로 고객의 요구사항, 비즈니스 환경, 기술 스택 등이다. 내부 요인은 개발자가 통제할 수 있는 것으로 코드 품질, 테스트 커버리지, 문서화 등이다. 이 두 가지 요인에 따라 변화율을 측정할 수 있다. 하지만 AI가 코드를 생성한다면 내부 요인은 통제할 수 없는 외부 요인이 된다.

따라서 개발자는 외부 요인을 고려하여 경계를 분리해야 한다. 조금 더 풀어서 설명하자면, 앞으로 무엇이 더 추가될까?보다는 어떤 기능이 가장 먼저 사라질까?로 고민해야 한다. 즉, 기술적인 것보다 비즈니스에 대한 고민이 필요하다.

실제로 분리는 어떻게 이루어져야 할까? AI를 이용한다면 최소 분리 단위는 AI가 생성할 수 있는 단위여야 한다. 그리고 그 이상은 사람이 관리하게 된다. 따라서 AI가 담당할 영역과 사람이 관여한 비즈니스 영역을 고려하여 추상화 레벨을 결정해야 한다. 어렵게 느껴진다면 다음 내용을 참고하여 분리해보자.

  • AI는 어떤 단위로 코드를 생성하는가?
  • 각 기능은 완성된 이후 시간이 지날 수록 변화율이 높아진다.
  • 사용자의 만족도가 낮을 수록 변화율이 높아진다.
  • 독립적으로 존재할 수 있는 기능이라면 바로 분리할 수 있다.
  • 불확실성을 측정할 수 없다면 억지로 분리하지 않는다.
    • 큰 단위에선 분리하지 않더라도 불확실성을 판단할 수 있는 추상화 단위에서 분리한다.

경계를 분리했다면 이제 구현에 들어가야 한다. AI를 이용한다면 대부분의 코드를 AI가 생성할 것이다. 그리고 파괴 가능성을 고려한다면 AI가 파괴하기 좋은 코드 생성할 수 있게 만드는 것이 좋다. 그러면 어떤 코드가 파괴하기 좋은 코드일까?

필자는 각각 독립성, 인지가능성, 통제가능성을 고려하여 파괴 가능성을 판단할 수 있다고 생각했다. 좀 더 풀어서 설명해보겠다.

독립성은 결합도와 응집도의 정도, 단일 책임 원칙을 어느정도로 지켰는지로 판단할 수 있다. 코드는 독립적일 수록 파괴하기 쉽다. 이는 AI가 신뢰할 수 있는 생성 단위가 어느정도인지에 따라 다르다. 필자는 아직 함수 단위를 벗어나면 신뢰하기 어렵다고 생각하지만, 향후 더 큰 단위로 생산할 수 있게된다면 그에 맞춰 독립성을 고려해야 한다.

인지가능성은 말 그대로 개발자가 이해할 수 있는 정도를 말한다. 아직까지는 파괴에 대한 결정은 개발자가 직접할 수밖에 없다. 하지만 파괴해도 된다는 확신을 받을 수 없다면 파괴하기 어렵다.

통제가능성은 개발자가 통제할 수 있는 영역인지를 말한다. 그 누구도 관리하는 사람이 없다면 통제하기 힘든 코드가 된다.

AI를 위한 아키텍처

AI 코딩, 더 나아가 바이브 코딩이 진정한 새로운 개발 방식으로 자리 잡기 위해서는 앞서 이야기한 것 처럼 새로운 요구사항이 생겼을 때 다시 만들 수 있어야 한다.

이 말은 단순히 코드 몇 줄을 지운다는 뜻이 아니다. 요구사항이 바뀌면, 관련된 코드 전체를 제거하고 새로운 요구사항에 맞게 다시 생성할 수 있어야 한다는 의미다. 이상적으로는, 애플리케이션 전체를 하나의 바이너리 단위로 통째로 다시 생성하는 것도 가능해야 한다. 기존 코드를 다듬기보다, 아예 새로운 스냅샷을 생성해버리는 방식이다.

그러나 아직은 현실적으로 어렵다. 현재 AI는 복잡한 도메인 요구사항, 모호한 흐름, 명확하지 않은 예외 처리까지 포함된 시스템 전체를 일관되게 생성해낼 수 없다. 생성된 코드가 돌아는 갈 수 있지만, 그 안에 숨겨진 맥락까지 올바르게 반영되지는 않는다. 그렇다면 현재 AI의 수준에서 안전하게 다시 생성할 수 있는 최소 단위는 무엇일까? 필자의 생각으로는 그 단위는 아직 ‘함수’에 머물러 있다. 기능적으로 분리되고, 명확한 입력과 출력을 가지며, 부작용이 적은 단위. 그것이 AI가 지금 당장 가장 잘 다룰 수 있는 범위다.

이 전제를 받아들인다면, 설계도 그에 맞춰 바뀌어야 한다. 필자는 AI 코딩과 잘 어울리는 아키텍처를 다음과 같이 생각한다.

1. 에그리거트 단위의 작은 모듈 또는 서브시스템으로 분리한다.
이 단위는 비즈니스적 완결성을 가지며, 다른 모듈과는 인터페이스를 통해 통신한다. 내부의 구현은 언제든 갈아끼울 수 있게, 외부엔 추상 인터페이스만 보여준다.

2. 각 기능은 유스케이스 단위로 절차적으로 실행되도록 만든다.
복잡한 객체지향 설계보다는, 단순하고 명확한 절차형 흐름이 바이브 코딩에 더 적합하다. 이는 AI가 구조를 유지하면서 로직을 생성하기 쉽게 만드는 장치이기도 하다.

3. 로직은 함수형 프로그래밍 스타일로 작성한다.
순수 함수, 불변성, 사이드 이펙트 최소화. 이러한 접근은 AI가 생성한 코드를 검증 가능하게 만들어준다. 그리고 작은 단위의 함수 조합은 나중에 문제가 발생해도 쉽게 교체 가능하다.

4. 예외 처리에는 모나드를 활용한다.
AI가 짠 코드는 불안정할 수밖에 없다. 예상하지 못한 값이나 상태가 자주 등장한다. 그렇기 때문에 실행 흐름을 중단하는 예외보다 모나드를 이용하여 함수를 연결하면서도 오류에 강인한 흐름을 만드는 것이 중요하다.

이러한 구조를 통해 우리는 부분의 파괴가 전체의 파괴로 이어지지 않도록 막을 수 있고, 다시 만들 때도 작은 단위부터 안전하게 재구성할 수 있다. 바이브 코딩은 결국 생성과 파괴의 빠른 순환이다. 즉, 어떻게 하면 지우고 다시 만들 수 있는가를 중심에 두고, 설계 또한 그 질문에 답할 수 있어야 한다.

마치며

사실 필자는 AI로 코딩하는 것이 그렇게 즐겁지는 않다. 한땀한땀 코드를 작성해서 멋진 것을 만들어냈을 떄의 성취감, 희열을 빼앗긴 것 같기 때문이다. 실제로 AI가 손쉽게 로직을 생산해내는 것을 보고, 이를 이용해서 일을 했을 때 지식에 대한 욕구가 줄었음을 느꼈다. 그렇지만 AI는 이제 단순한 도구가 아닌 새로운 패러다임이 되었다. 그리고 그 패러다임은 우리가 지금까지 해왔던 것과는 다른 방식으로 소프트웨어를 생산하게 만들고 있다. 우리는 이 새로운 패러다임에 맞춰 우리의 사고를 바꿔야 한다.

필자가 제안한 파괴 지향 개발은 AI가 없던 시절에도 유용한 방법론이다. 소프트웨어는 언젠가 파괴될 것이고, 우리는 그 파괴를 피할 수 없다. 그렇다면 우리는 그 파괴를 어떻게 받아들이고, 어떻게 대처할 것인가에 대한 고민이 필요하다. 그리고 그 고민은 결국 우리가 소프트웨어를 만드는 이유와도 연결된다. 소프트웨어는 단순한 코드의 집합체가 아니다. 그것은 우리의 생각과 의도를 담아내는 매개체다. 그렇기에 우리는 그 매개체를 어떻게 다룰 것인지에 대한 고민을 계속해야 한다.

그리고 이 방법론 또한 시간이 지나며 변화할 것이다. AI는 계속 발전하고 있으며, 우리는 그 발전에 맞춰 우리의 사고를 바꿔야 한다. 필자가 제안한 방법론은 현재의 상황을 반영한 것이지만, 미래에는 더 나은 방법이 등장할 것이다. 우리는 그 방법을 받아들이고, 우리의 사고를 계속 발전시켜 나가야 한다.