학생으로서 바라본 Vibe Coding

White Piano·어제
0

좌우충돌 사색

목록 보기
7/7
post-thumbnail

Chat GPT는 혁명이었다. 흥분되면서도 두려운 사실은, 아직 혁명이 마무리에 다다르지 않았다는 점이다.

"GPT 없던 시절에는 이걸 어떻게 했대?"

개발자를 꿈꾸며 공부하다 보면 간간이 떠올리는, 그리고 옆자리에서 들려오는 말이다. 처음 저 말을 들었을 때는 상당히 배타적이었다.

"AI는 내가 할 수 있는 일을 더 빠르게 할 뿐, 내가 할 수 없는 일은 하지 못한다."

옳은 말이면서, 동시에 그른 말이다. 되돌아보면 오묘한 감정이 살며시 피어오른다. 나의 어휘로는 표현하기엔 부족한 복잡한 감정이다.

처음 GPT의 소식을 들었을 때, 나는 군 복무 중이었고, 전역 후 사회에 돌아왔을 때, GPT는 나의 미래를 망칠 각성제라 생각했다. 스타크래프트 세계관의 스팀팩이랄까?

22년 12월 전역했으니, 벌써 2년 하고도 6개월 가까이 흘렀다. 언젠가부터 LLM은 나의 삶 속에 스며들었고, 내가 작성하는 테스트 코드 대부분은 Copilot의 손에서 탄생했다.

사용하면 할수록, LLM이 참 다루기 어렵다고 느낀다. 동시에 멍청하다고도 느낀다. 무언가 궁금해 물어보면, 그럴듯한 헛소리에 오히려 혼란스러워지곤 한다. 특히, 컴퓨터 그래픽스 과목을 수강하며 OpenGL로 과제를 수행할 때가 떠오른다. 내용이 흔함에서 멀어질수록, LLM은 창작을 시작한다. 어느 교수님께서는 GPT를 "책을 100만 권 읽은 술 취한 초등학생"에 비유하셨다 ㅋㅋ

어느샌가 Cursor IDE 이야기가 많이 들려오기 시작했다. 그리고 Vibe Coding이라는, 유래부터 비범한 용어가 개발 생태계를 강타했다. 여러 스타트업에서 AI 활용 능력에 주목하기 시작했다.

아무리 LLM을 받아들인 상태였더라도, AI에 깊이 의존하는 개발 방법론(?)에는 거부감이 컸다. 하지만 트랜드를 쫓지 못하는 엔지니어의 말로란 도태뿐일지도 모른다. 이러지도 저러지도 못하며 시간이 흐르던 차, 놀라운 경험을 하게 되었다.

Vibe Coding?

학부 마지막 학기를 장식할 프로젝트를 진행하고 있다. 함께 작업하는 친구는 Vibe Coding에 관심도 많고 굉장히 능숙해 보인다. 나에게도 늘 AI에 적응해야 한다고 조언하던 친구다.

처음 PR을 리뷰하며, 생각보다 나의 코드 퀄리티가 친구에 비해 나쁘지 않다는 인상을 받았다. 처음에는 기분이 좋았다. 내 코드가 그래도 아름다운 편에 속하리라는 기대가 생겼기 때문이다. 하지만 친구의 작업을 지켜보며 충격에 빠졌다.

우리는 주에 한 번 정기 회의 및 진행 상황 공유를 진행하고 있다. 때문에, 내가 올렸던 PR들은 한 주를 고민하고 작업한 내용들이다. 친구의 PR도 그러하리라고 은연중에 생각했었다. 하지만 친구의 PR이 만들어지는 데에는 2시간이 채 걸리지 않았다.

그때 비로소 Vibe Coding을 연습해야 함을 느꼈다. 구운 고기를 먹은 사람이 날고기를 먹은 사람보다 건강하다면, 난 불의 사용법을 익혀야만 했다.

"LLM이 생성한 코드가 마음에 들지 않아 손으로 직접 수정했다면 반성이 필요하다. 어떻게 프롬포트를 입력해야 그러한 수정을 AI에게 대신 시킬 수 있을지 끊임없이 고민해야 한다."

정말 많은 생각을 하게 되었다...

한번 경험해 볼까요?

마침, 새로운 사이드 프로젝트를 계획하고 있었다. 이번을 기회 삼아 Vibe Coding을 체험해 보자고 마음먹었다.

무거운 IDE를 싫어해 VS Code라는 Code Editor를 선호했었던 만큼, 처음에는 Cursor IDE를 사용하지 않으려 했다. Claude Desktop과 MCP를 통해 Intellij IDE와 연계하여 작업했다. Claude에 web searching이 지원되기 전까지는 Playwright MCP를 활용해서 web을 LLM에 주입했다. 결국 지금은 Cursor 쓴다...

그렇게 지금에 이르러, Seoul Mate 프로젝트는 마무리 단계에 접어들었다.

작업하며 공유했던 관련 아티클들...

그렇게 경험한 Vibe Coding은...

시작은 "LLM이 얼마나 멍청한지"에서부터다. 프로젝트 전역으로 컨텍스트를 이해시키는 작업이 불편했다. 작업 당 하나의 '대화'를 진행한다면, 모든 '대화'의 시작에 프로젝트에 관한 컨텍스트를 주입해야 했다. 토큰 잡아먹는 하마라는 말을 괜히 하던게 아니더라. 그렇게 주입했다고 해서 늘 제대로 동작하는 것도 아니었다. 코드 컨벤션은 다양하고 답이 정해져 있지는 않다. 하지만 최소한 하나의 모듈에서 통일된 컨벤션을 적용해야 하지 않겠는가? 서로 다른 '대화'에서 생성된 결과물은 제각각의 indent, 문서화 정도, lib 사용 패턴을 보였다.

또한, 그럴듯한 엉터리 코드가 많이 나왔다. Google OIDC 로그인을 진행하는 과정에서, id token 검증을 단순히 jwt parsing만으로 퉁치려고 하더라. Google의 public key를 가져와서 검증하는 부분은 내가 직접 지시해야 했다. 또한, 웹 스크래핑을 비동기로 작성하기에 기대를 많이 했는데, 무늬만 비동기인 동기 코드였다. 어쩌면 내가 Java에서의 비동기를 잘 몰라서 그렇게 느꼈던 걸까? JS에서의 Promise.allSettled()와 같은 인터페이스가 불필요한 걸까? 그러진 않을 것 같다.

동시에 감탄스러운 부분도 있었다. 이번 프로젝트의 핵심 중 하나는 웹 스크래핑이었다. 웹 스크래핑을 진행하는 데 있어서 다양한 기술 관문이 있다. Rate Limit도 신경 써야 하고, Data의 실시간성을 위한 갱신 주기도 고민해야 한다. 하지만 그 이전에, 도덕성에 주목하고 싶다. LLM에게 웹사이트 정보를 수집하는 과정에서의 도덕성 확인을 요청하니, robots.txt뿐만 아니라 해당 웹사이트의 약관 페이지를 탐색하고, 문제가 되지 않음을 확인해 주었다. 사이트 약관을 찾아볼 생각까지는 하지 못했는데 내가 놓쳤던 부분을 고려하여 굉장히 놀랐다.

생산성? 생산성?! 생산성!!!

우리는 '무엇'을 만들어야 하는가?

기업은 고객이 뭘 원하는지 모른다. 사실 고객도 모른다. 그렇기에 우리는 통계를 사용한다. 빠르게 실험하고 사용자를 관찰한다. AB 테스트가 빈번하게 수행되며, 다양한 시도 속에 치열한 시장 속에 살아남는다. 결국, 좋은 서비스를 기획하기 위해서는 높은 생산성이 필요하다.

개발자는 무엇으로 성장하는가?

"개발자는 이론만이 아니라 실험을 통해 성장해요."

한 때, 이론에 지나치게 집중했던 시절이 있었다. 코드를 작성하는 일은 보다 쉬운 일이며, 문서를 탐독하고 기반 기술을 이해하는 것이 훨씬 중요하다고 믿었다. 사실 이러한 가치관은 지금도 그리 크게 변하진 않았지만, 책 속에만 존재하는 지식은 죽은 지식이란 사실을 지금은 알고 있다.

필요한 데이터가 전체의 20%를 넘어선다면 Index를 타는게 불리하다는 말이 있다. 처음 공부할 땐 위 말을 맹신했다. 하지만 돌아서서 떠올려보면, 내가 만났던 수많은 선배분께선 늘 "상황에 따라 다름"에 주의 주셨다. 과연 직접 실행해 보기 전에는 제대로 알 수 있을 것인가?

SW는 결국 HW 위에서 돌아간다. 그렇기에 최전선에서 고군분투하시는 분들은 HW에도 깊은 조예를 가지고 계시다. 흔히 Array와 List를 비교하며 Space Locality를 이야기하곤 한다. 더 나아가면 SIMT와 같은 프로세서 아키텍쳐를 잘 활용하기 위한 Tiling을 고려해야 하는 순간이 올지도 모른다.

우리는 개발자이기 이전에, 공학자이기 이전에 문제를 해결하는 사람이다. 우리가 해결하고자 하는 문제는 삶 속에 있고, 그렇기에 이론과는 괴리가 있다. 늘 실험하고, 동작을 관찰하며 그 속에서 깨달아야 한다. 그리고 그러한 실험을 한정된 시간 안에 얼마나 밀도 있게 할 수 있느냐는 생산성과 깊은 관계가 있다. 일단 많이 짜봐야 그만큼 배울 것이 아닌가?

코더를 넘어서기 위해서

결국 AI는 내가 하지 못하는 일은 하지 못한다. 다른 말로 표현하면, 내가 이미 할 수 있는 일을 굉장히 빠른 시간 내에 할 수 있도록 돕는다. 이제 우리는 "할 수 있는 일"을 늘려나가야 한다고 생각한다.

LLM과 작업하며 코드 리딩 속도에 아쉬움을 느꼈다. 생성된 코드는 엉터리일 확률이 높고, 이는 아무리 프롬포트(like cursor's MDC files)를 가다듬는다고 하더라도 변하지 않을 것이다. 문제가 있다면, 파악하고, 원인을 빠르게 이해해야 다음 지시를 전달할 수 있다. 결국 LLM을 온전히 사용하려면, 코드 리딩 속도가 이를 뒷받침해야 한다.

물론 "Vibe Coding은 원래 이해 못 하고 짜는건데~"라고 생각할 수 있다. 하지만 정말 거기에 만족할 것인가? 사회에 통용되는 용어로서 Vibe Coding을 선택했지만, 나는 개발자를 꿈꾼다. LLM은 나의 하인이어야 하며, 절대 나의 상관 내지는 동료가 될 순 없다.

코드를 읽고, 구조를 이해하고, 문제를 발견하고, 더 좋은 지시를 생각하기 위해서 공부해야 한다. 이 과정은 이전과는 조금 다를지도 모르겠다. 가령 '디자인 패턴'이 있다. 이제까지 나는 디자인 패턴을 시간을 들여 공부하려고 하지는 않았다. 다양한 아티클, 그리고 친구들과의 대화, 코드 리뷰를 통해 '아름다운 코드'를 경험하다 보면 자연스럽게 좋은 패턴을 사용하게 되리라고 생각했다. 하지만 LLM은 그렇지 못하다. 내가 생각하는 구조를 LLM에 정확하게 전달하려면 정해진 명칭이 있어야 하며, 디자인 패턴은 아주 강력한 도구가 될 수 있다.

그래서 결론은요?

Cursor Pro를 사용 중이다. :)

0개의 댓글