빚더미 위에 지어진 소프트웨어, AI 시대의 개발자에 대하여
AI가 코드를 대신 짜주는 시대, 우리는 어떤 개발자가 되어야 할까요? Cursor를 써보며 느낀 실사용 경험과 함께, 코드가 가진 부채에 대해 성찰해본 글입니다.
1/19/2025, 1:37:00 AM
개요
지난 1월, 처음으로 Cursor 를 사용해서 프로젝트를 진행해보았습니다.
그동안 여러 방식으로 코딩에 AI 를 접목해 보았는데, copilot 같은 자동완성 플러그인 같은 경우 조금 모자란 녀석이 지나치게 적극적으로 참견하는 꼴이라 그다지 만족스럽지 않았고, chat 으로 질의하는 방식은 코드를 복사하고 붙여넣는 그 과정이 불편하다는 문제가 있었습니다.
반면에 Cursor 는, 특히 composer 기능은 적당한 거리감을 유지하면서도 정말 필요할 때 알맞은 도움을 주어서 상당히 만족스러웠습니다.
결론적으로 Cursor와 함께 한 달이 조금 넘는 기간만에 토이 프로젝트를 완성하고 출시할 수 있었습니다. ( 다운로드 링크 )
해당 프로젝트는 tauri 라는 rust 기반의 크로스 플랫폼 앱 프레임워크로 만들어졌는데, 백엔드 개발자인데다가 rust 조차도 처음이었던 제가 한 달만에 처음 사용하는 프레임워크로 데스크탑 앱을 만들어 앱스토어에 출시까지 할 수 있었으니 Cursor가 상당한 생산성을 제공했다는 것은 명백합니다.
돌이켜보았을때 이 프로젝트를 진행하는 동안 작성된 코드의 90% 정도는 AI 가 작성해준 것 같습니다. 그러나 저는 여전히 제가 모든 코드를 작성했다고 생각합니다. 그저 제가 한 땀 한 땀 타이핑을 한 건지 AI가 순식간에 써준 건지의 차이가 있을 뿐, 제가 코드를 인지하는 방식은 조금도 달라지지 않았습니다. 그 이유는 제가 AI 와 함께 코딩을 하면서 정한 한 가지 대원칙 때문입니다.
“AI 가 작성한 코드는 절대 믿지 않는다”
이 대원칙은 세운 이유는, 물론 아직 AI 가 미흡하기 때문이기도 하지만, 그보다는 제가 개발자를 업으로 삼으면서 중요하게 생각하는 철학 때문입니다.
Code is a Liability
Code is a Liability. 즉, 모든 코드는 부채다.
개발자로 일하다 보면 본인이 작성한 코드에 애정이 생기기 마련이지만, 사실 그 코드 자체는 소프트웨어를 만들기 위해 필요했던 부산물 정도에 지나지 않습니다. 그리고 안타깝게도 그 부산물은 소프트웨어의 진화를 매우 적극적으로 방해하는 걸림돌일 뿐입니다.
코드는 만들어질 당시에 존재했던 요구사항들을 바탕으로 작성되면서 그 안에 세상을 바라보는 어떤 시선(== 설계, 도메인, 바운디드 컨텍스트 .. )이 함께 담기게 됩니다.
그러나 우리의 가설은 항상 참으로 귀결되지는 않습니다.
그 가설은 프로덕트의 기획으로부터 나온 것일 수도 있고, 개발자가 구현하는 방식에서 나온 것일 수도 있으며, 더 현실적으로는 반드시 지켜야 하는 법리의 해석에 의한 것일 수도 있으나 어쨌든 자주 바뀌고 틀립니다.
특히 소프트웨어는 물리적인 제약사항이 없기 때문에 더 과감하게 가설을 세우고 빠르게 시도하기를 반복합니다. 그로 인해 프로덕트의 방향성이 달라질 때, 그 방향이 코드가 바라보는 시선과 다를수록 변경을 위해 큰 비용을 지불해야 하며, 경우에 따라서는 그 비용이 너무 커서 방향성을 포기하게 될 때도 있습니다.
지나치게 큰 부채를 지게 된 것입니다.
심지어 코드는 저절로 썩기도 합니다. 업데이트를 하지 않으면 사용할 수 없는 어플처럼 세상은 오래된 소프트웨어에 그리 관대하지 않습니다.
하루도 빠짐없이 새로운 취약점이 발견되고 있어서 꾸준히 보안 패치를 해주어야 하며, 오늘날의 소프트웨어는 오픈 소스를 기반으로 거미줄처럼 의존성이 엮여 있기 때문에 이 또한 잠재적인 변경 가능성을 내포합니다.
코드가 작성되는 순간부터 특정 시점에는 반드시 변경이 필요하다는 채무가 발생하므로, 모든 코드는 부채라는 말은 정말로 참입니다.
변화에 대응하라
소프트웨어의 가장 큰 특징은 빠르게 변화한다는 점이고, 소프트웨어 공학의 핵심 중 하나는 변화에 대응하는 방법론과 기술이며, 개발자의 역할은 가장 적은 비용으로 변화에 대응할 수 있도록 설계하는 것입니다.
이것이 제가 AI 가 작성한 코드는 절대로 믿지 않는 이유입니다. 코드란 것은 결국 장황하게 적힌 빚 문서인 것입니다. 거기에는 이렇게 적혀있습니다.
“이 코드에서는 이러한 선택을 했으며 이것은 잠재적으로 이러한 채무를 지게 됨”
이런 관점에서 보면, AI 는 빠르게 소프트웨어라는 자산을 안겨주는 마법 같은 존재임과 동시에 뒤로는 거대한 부채를 만드는 사채업자 같은 것입니다. 이 부채를 생각하지 않고 AI 에게 계속해서 일을 시키다보면, 어느 순간 AI 가 제가 생각한대로 기능을 잘 구현하지 못하는 순간이 옵니다.
이때 코드를 보면 이미 자신의 인지에서 한참 벗어난 복잡한 코드 뭉치가 작성되어 있으며 결국 어찌할 수 없이 죽은 소프트웨어를 마주치게 됩니다.
파산한 것입니다.
AI의 마법에 홀려 빚쟁이가 되지 않으려면 AI 가 만들어낸 코드를 꼼꼼히 읽고 채무를 인지해야 합니다. 그리고 매순간 적극적으로 채무 청산에 힘써야합니다.
클린 아키텍처 책의 초반부에 저자는 변경이 쉬운 설계의 중요성에 대해 어필하기 위해 이렇게까지 이야기합니다.
- 완벽하게 동작하지만 더 이상 손댈 수 없을 만큼 복잡하게 작성된 코드
- 거의 다 버그이지만 어쨋든 고칠 수 있는 코드
이 벨런스 게임에서 더 가치 있는 코드는 후자라고.
AI 로 인해 이제 개발자가 아닌 사람들도 손쉽게 소프트웨어를 만들 수 있게 되었습니다. 수많은 사람들이 각자의 생각으로 만들어내는 창의적인 소프트웨어가 쏟아지는 세상은, 이 컴퓨터 월드를 좋아하는 저에게는 매우 기쁜 일이면서도 직업의 측면에서 개발자의 고유 영역이라고 여겨지던 것이 일부 무너짐은 틀림없습니다.
하지만 소프트웨어라는 자산 뒤에 숨겨진 코드라는 부채는 사라지지 않을 것이며 부채가 적은 소프트웨어는 이 시장에서 항상 우월한 지위를 차지할 것입니다.
Win-Win
재미있는 것은 LLM이 만든 코드를 그대로 수용하지 않고, 적극적으로 나서서 부채를 청산해 줄 때 LLM이 더 잘 작동한다는 것입니다.
LLM 에게 단계적으로 시키되, 다음 단계로 넘어가기 전에 매번 지금의 설계를 한번 정리하는 단계를 추가하는 것입니다. 작은 단계로 할 일을 나눈 뒤 RED - GREEN - REFACTORING 을 반복적으로 수행하는 테스트 주도 개발이 떠오르네요.
변경하기 쉬운 코드는 이해하기 쉬운 코드 ( 가독성이 좋은 ) 라는 개념을 포괄하고 있으며 이해하기 쉽다는 건 LLM 이 인지하는 맥락과도 어느 지점에서 맞닿는 부분이 있는 것 같습니다.
어쩌면 좋은 설계는 LLM의 능력을 끌어올리는 핵심 요소일지도 모르겠습니다. LLM을 가장 효과적으로 활용할 수 있는 사람은 결국 훌륭한 개발자일 것입니다.
결론
LLM과 함께 코딩을 해봤고, 많은 도움을 받았고, 놀라웠지만 이 직업에 대한 저의 철학은 아직 변하지 않은 것 같습니다. AI 가 아무리 코딩을 잘한다고 하더라도 개발자는 코드가 가지고 있는 부채를 직접적으로 책임지는 자연인으로서 여전히 가치 있습니다. 소프트웨어 장인 정신은 여전히 유효한 것 같습니다.
댓글
* 작성 이후에 수정/삭제 할 수 없어요!
아직 작성된 댓글이 없습니다.