brunch

How I met vibe coding

보지도 않은 드라마 How I met your mother의 제목

by 강한별
Vibe coding is a software development approach where a user provides natural language prompts to an AI, which generates the functional code. - google search result


바이브 코딩은 사용자가 AI에 자연어 프롬프트를 제공하고 AI가 기능적 코드를 생성하는 소프트웨어 개발 접근 방식이라고 한다. 나는 현재 Cursor로 업무와 토이 프로젝트를 하고 있는데, 자연어 프롬프트를 제공하고 AI가 코드를 생성하는-이른바 바이브 코딩이라고 하는- 과정을 시도해보면서 이런 것들을 배웠다.


1. 완벽한 영어 프롬프트를 쓰는 게 아니라, 나의 모국어로 명확하게 요구사항을 작성하기


Cursor에 대한 이야기는 꽤 오래 전부터 알고 있었다. 웹에서 Cursor가 좋다는 이야기를 자주 접했는데 나는 개발자가 아니기 때문에 내가 Cursor를 어떤 방식으로 쓰게 될지가 잘 상상이 되지 않았다. 나는 스키를 내 평생에 한 번도 타본 적이 없는데(나는 스키장에 가서도 젤다의 전설을 하고 온 사람이다) 스키를 타면 재밌다고 하는데 나는 타본 적이 없으니 체감이 안 되는 그런 느낌이었다고나 할까. 그 당시 왜인지는 모르겠는데, 프롬프트는 영어로 써야할 것 같은 이상하고 잘못된 강박이 있어서 더더욱 그랬던 것 같다. 애초에 프롬프트를 영어로 작성하지 않아도 되고, 프롬프트의 내용 자체가 명확하면 된다는 것을 깨달았을 때 “어 나도 사용할 수 있을 것 같아” 라고 비로소 생각하게 되었다.


2. 그럼 내가 하는 업무를 agent가 하게 하려면 무엇을 가르쳐야 하는가?


업무에서 사용할 때와 토이 프로젝트에서 사용할 때의 방식은 약간 차이가 있는데 우선 업무에서의 사용 방식을 먼저 이야기하려고 한다. 내가 주로 하는 업무는 “프로덕트 실험”과 관련된 것이다. 실험 전 기회 요인 분석부터 실험 전에 필요한 데이터를 분석하기, 웹로그를 설계하기, 어떻게 어떤 기준으로 실험을 할 것인가에 대한 개발적인 커뮤니케이션이 주를 이룬다.


이 중 웹로그 설계, 커뮤니케이션을 제외한 업무들이 오히려 추상화, 규격화를 하기 쉬운 부분이라고 생각했다. 웹로그 정의 및 개발은 개발자와의 커뮤니케이션이 중요하고, 커뮤니케이션은 커뮤니케이션 대상자와 상황의 변동 요인이 크다. 그에 반해 나머지 업무의 경우 목표와 목적, 산출물이 비교적 “명확”하기 때문이다. 이 분석은 어떤 배경이 있는가? 즉 왜 해야 하는가? 어떤 데이터를 기반으로 해야 하는가? 어떻게 집계해야 하는가? 가 정해지면 나머지의 해석의 영역이라고 생각한다.


그래서 이전에는 내가 분석에 사용하는 쿼리를 100% 수제로 작성했다면, 점차 자연어로 분석 설계를 지시하고 Cursor agent가 분석 코드를 작성하고 실행하도록 했다. 그래서 현재는 내가 작성하는 분석 코드는 10~20% 이하가 되게 하고 나는 agent가 쿼리를 작성하고 실행하는 동안 현재로서는 자동화하기 어려운 커뮤니케이션 관련 업무에 더 시간을 쏟고 있다.

이렇게 전환하는 과정에서 내가 느낀 점은 다음과 같다.


2.1. 내가 정보를 충분히 주지 않았는데 agent가 정답을 맞출 수 있을 리가 없다

결국 Context Engineering이라고 하는 건데, 인간도 비슷하다. 맥락에 대한 정보가 없으면 고려할 수 있는 정보가 없으므로 내가 원했던 결과가 다른 것이 나올 수 있다. 하다 못해 사내 쿼리 엔진과 버전을 알려주는 것도 아주 중요한 정보이다. 이것을 알려주지 않았을 때는 agent가 현재 사내 쿼리 엔진과 맞지 않는 쿼리를 작성했었다. 이런 부분은 코드 실행 환경이 구체적으로 어떠하다는 것을 알려주자 바로 해결되었다.

그래서 지시를 할 때 맥락에 대한 정보를 아주 풍부하게 줬다. 이 일은 왜 해야 하는가?(돈 벌기 위해서 이런 거 말고..) 이 분석은 왜 해야 하는 것인지를 agent에게 알려줬다. 그리고 분석은 기준이 중요하기 때문에 기준에 대해서도 아주 구체적으로 알려주었다. 데이터 추출 기간부터 플랫폼, 집계 기준 등 디테일하게 요구사항을 작성한다. 당연히 사용해야 하는 테이블 정보도 agent에게 알려준다.


프롬프트 예시 (어디까지나 예시임을 참고):

이 분석의 배경: 이 분석 결과의 독자는 이 UI를 계속 개발 리소스를 투자해서 개선할 필요가 있는지 의사 결정을 하고 싶어한다.
이 분석에서 살펴볼 데이터들:
1) 해당 UI에 대한 사용율
2) 사용율이 높다는 것에 대한 기준점을 어떻게 잡을 것인가?
2.1) 높다면, 혹은 낮다면 이유는 무엇 때문일까?
2.2) 사용율이 높은 유저들이 정말 우리 제품 성장에 비지니스적으로 도움이 되는가?
3) 이 데이터들을 살펴볼 때 사용해야 하는 데이터 출처들:
3.1) 사용율 데이터: 웹로그 테이블 A를 사용한다. 해당 UI에 대한 웹로그는 event_name = 'new ui'로 필터링하여 집계한다
3.2) 사용율의 집계 기준: distinct user_id를 사용하되, 비율뿐만 아니라 사용횟수의 분포도 살펴본다
3.3) 이 유저들이 실제로 비지니스적으로 도움이 되는지 판단하기 위해 매출 테이블 A를 프록시로 사용한다. 이때 gmv, asp, aov, orders per customer를 고려하고 각각은 이렇게 집계한다


여기까지 보면 대체 자연어로 지시하는 거랑 코드를 작성하게 시키는 거랑 작업 시간의 소요가 뭐가 달라지나 싶을 수도 있는데, 이것은 “내가 사용할 툴을 개발하기 위해 투자하는 시간”이라고 생각했다. 도끼의 날을 가는 시간인 것이다. 작업을 하면서 작업 방식에 대한 “rule”을 점진적으로 업데이트 하고 “memory”를 업데이트 했다. 즉 한 번 배우면 그것을 활용해서 다음 태스크를 할 수 있도록 했다. 즉 내 지식과 업무 방식을 agent에게 이관하는 작업을 거치고, 작업을 완료한 후에는 회고를 통해 룰과 메모리를 recursive하게 업데이트 하도록 했다. 이것 역시 workflow로 구현했다. Cursor의 custom slash command로 meta-learning을 구현하여 이 커맨드를 실행하면 agent가 학습할 수 있도록 만들었다.


그래서 내가 체감하기에는 할루시네이션(없는 테이블, 없는 컬럼 생성, 혹은 잘못된 기준 사용)은 발생 비율이 낮았다. 없는 테이블과 컬럼을 출력하는 경우는 아주 단순하게 해결했다. 결국 원인은 임의 추론을 하기 때문이므로, 쿼리를 실행할 수 있도록 환경을 조성하고 쿼리 작성 전에 describe를 하도록 강제하는 rule를 명시했다. 그러면 없는 테이블이나 컬럼이 나오지 않는다. 없는 테이블이나 컬럼을 추가한다 하더라도 describe 혹은 쿼리 실행을 해보고 agent가 스스로의 실패를 확인한 후 재조정을 하기 때문이다. 집계 기준에 대해서도 디폴트 값을 명시하고 명시된 기준으로 작업을 하게 했다.


.Cursorrules 파일 예시:
SQL 쿼리 작성 전 반드시:
1. 사용할 테이블 DESCRIBE 실행
2. 결과를 보고 컬럼명 확인 후 이 컬럼을 사용하는 게 맞는지 사용자에게 확인하기
3. 존재하지 않는 컬럼 추측 금지 실행
예: Agent: "customers 테이블 구조 확인하겠습니다"
> DESCRIBE customers; Agent: "birth_date는 있지만 age는 없네요. 이 컬럼을 사용해서 계산하는 게 맞나요?"


2.2. 이 모든 과정들은 서로의 암묵지를 확인하고 서로가 합의하고 공유하는 지식을 만들어나가는 과정이다

사람마다도 암묵지가 다르다. 사람과 AI도 다를 바 없고, 개인적으로는 AI 모델들 간에도 암묵지가 다를 것이라고 생각한다. gemini가 생각하는 빨강과 gpt가 생각하는 빨강, claude가 생각하는 빨강의 범위가 다를 거라는 거다. 여기서의 빨강은 임의의 예시이고 어떤 단어를 넣든, 어떤 문장을 넣든 상관 없다.


그러므로 나의 암묵지가 무엇인지를 분명히 알고 그것을 AI든 사람에게든 전달하는 것이 중요하다고 생각하게 되었다. 그래서 수동으로 많이 썼던 프롬프트 중 하나가 “여기까지 내 지시에서 이해되지 않는 것, 분명하지 않은 것, 더 필요한 정보가 있으면 반드시 질문해” 였는데 이것도 나중에 rule로 추가했다. 요컨대 system instruction에 얼마나 투자하느냐에 따라 프롬프트의 효율성도 달라진다(너무 당연한 이야기인가?)


2.3. 이 모든 것은 동적으로 자동화 되는 것이 중요하다

상황은 계속해서 변하고, 완벽한 system instruction이나 프롬프트가 존재한다고 생각하지 않는다. 심지어 foundation model도 변하고, 매일 매일 새로운 모델이 나오기 때문이다. 그러므로 동적으로 변하는 상황 속에서 어떻게 지속 가능한 방식을 지향할 수 있을까를 생각하게 되었는데, 결국 이 부분을 최대한 손을 덜 타도록 해야 한다는 결론을 내렸다. 그래야 실행하게 되기 때문이다(넛지를 생각해보자). 아주 복잡하게 쓴 것 같지만 내가 실행한 방식 자체는 단순하다. 이전에 언급한 것처럼 meta-learning workflow를 만들어서 agent도 인간처럼 회고하게끔 했다. 이때 회고한 결과물이 지엽적이어서는 안 된다. 그럼 범용적으로 활용하기가 어렵기 때문이다. 나는 다음과 같은 요소를 고려했다.


meta-learning은 결국 사고 방식, 행동 지침, 그리고 행동 지침이 참고할 기억을 점진적으로 개선하기 위한 것이다.

태스크를 완료했을 때, 다음과 같은 관점에서 회고해본다. agent가 어떻게 이 문제에 접근했다면(사고 방식), 그리고 어떻게 실제로 태스크를 수행했다면(행동 지침), 그리고 어떤 정보를 알고 있었다면(참고할 기억) 더 효율적으로 태스크를 완료할 수 있었을까? 혹은 사용자가 업데이트 되어야 할 수도 있다. 즉, AI가 인간에게 피드백을 줄 수도 있는 것이다. AI만 개선되라는 법은 없잖아요?

2를 통해 회고한 내용을 바탕으로, 이 내용이 정말 rule과 memory에 없었는지를 다시 판단한다. 없었다면 적절한 위치에 추가하고, 있었다면 왜 rule과 메모리에 있었는데 사용하지 않았는지를 다시 회고(…) 하게 하여 rule과 memory를 업데이트하고, work flow로 만들 수 있는 것은 workflow로 업데이트 한다.


이 커맨드를 통해서 agent는 agent의 실수를 복기하고, 어떻게 하면 더 효율적으로 작업할 수 있을지를 본인의 명세서에 적게 된다. 이런 work flow를 반복하면 결국 인간이 할루시네이션이라고 판단하는 것들을 어느 정도 낮출 수 있는 것 같다.


agent : 집계 기준에 대해서 물어보지 않고 작성했기 때문에 이 부분을 재작성해야 했습니다. 앞으로는 집계 기준에 대해서 사전에 사용자에게 물어보는 과정을 rule에 추가해야겠습니다. 그리고 디폴트로 사용하는 기준이 있으면 그것을 메모리에 추가해야겠습니다.


이렇게 되는 것이다.


3. 춤추는 것 자체를 즐기기


이런 방식으로 작업을 했는데 나에게는 꽤 효과적으로 잘 작동했고, 심지어 나는 재미있었다! 나는 LLM의 출력과 사고과정을 읽는 것을 굉장히 좋아하기 때문에 이 과정 자체도 재미있었다. 나는 추론 과정을 일일히 열어보는 걸 굉장히 좋아한다.


나의 생각을 어떻게 더 간명한 언어로 표현할 것인가? 언어는 결코 실재를 그대로 반영하지 못한다. “의자”라고 표현한들 단어는 세상에 존재하는 수많은 형태의 실제 의자들의 그림자에 불과하다(chairness). 그럼 어떻게 해야 그 갭을 줄일 수 있을까?에 대해 것이 재밌다.


그리고 gemini도, gpt도 claude도 사고 과정을 열어볼 수 있기 때문에 사고 과정을 열어보면서 내 프롬프트를 이렇게 이해하고 이렇게 구체화하려고 하는구나를 알게 되면 “이 멍청한 놈!” 아니라 “멍청한 건 나였군” 이라는 생각을 하게 될 때도 있다. 서로의 언어를 배워나가는 과정인 것이다.


아직도 더 개선할 수 있는 영역이 많다고 느낀다. 아직 내가 자동화하지 못한 영역들도 내가 업무 시에 사용하는 사고 방식이나 대응 방법, 지식을 충분히 전수하여 나, 혹은 나보다 나은(..) agent를 만든다면 그것도 가능하리라는 생각이 들기 때문이다. 특히 Cursor도 거의 주에 1번 이상, 많으면 2~3번도 업데이트를 하고 있고 워낙 기술이 점점 빠르게 발전하고 있다보니 낙관적인 생각을 하게 된다. 결국은 많은 테크 아티클들이 말하듯이 agent를 매니징 하는 것이고, 내가 해야 하는 업무의 속성을 잘 파악하여 그에 맞는 agent를 꾸리고, 감독하고, 교육하는 게 현재와 근미래의 방식일 거라고 생각한다. 포켓몬 트레이너가 되거나, 하스스톤 덱을 짜는 것 같은 이치 아닐까?


이러쿵 저러쿵 길게 쓰긴 했지만 모두가 같은 방식으로 춤을 춰야 하는 것은 아니다. 그래도 이 글을 읽고 이 바이브가 마음에 든다면, 이렇게 시작해볼 수 있다. 나의 업무를 아무것도 모르는 사람이 나처럼 할 수 있게 만드려면 어떻게 해야할까? 를 염두에 두면서 agent가 완벽하지 않아도 하나의 태스크를 완료해보게 하고 그것을 되풀이하게 해볼 수 있다. 그리고 실패할 수도 된다. 실패가 0일 것으로 전제하면 더 위험하다고 생각한다. 실패했을 때 어떻게 ‘알아차리게’ 하고 다음 접근을 할 것인지를 유도해보자. 작은 실패에서 배우고, 배운 것을 다음 작업, 다른 유형의 작업에서도 적용할 수 있도록. 그것이 학습의 복리를 적용하는 방법이라고 생각한다.

매거진의 이전글LLM은 시인의 꿈을 꾸는가?