10년 차 엔지니어가 '바이브 코더'들에게 가장 먼저 가르치고 싶은 것: 토큰 비용이 들지 않는 도구를 만들어라
After 10 years as an engineer, the thing I'd teach new vibe coders first: build tools that cost zero tokens to run
핵심 요약
LLM에만 의존하지 말고, LLM을 활용해 토큰 비용 없이 영구적으로 실행 가능한 결정론적 코드를 구축하라는 조언입니다.
- 결정론적 코드 — 입력값이 같으면 항상 동일한 결과를 출력하는 효율적인 코드임
- 비결정론적 LLM — 매번 결과가 달라질 수 있어 모든 문제 해결에 최적은 아님
- 토큰 최적화 — LLM으로 코드를 작성한 뒤, 이후 실행 시에는 토큰 소모 없이 운영함
- 기술의 공생 — LLM의 유연함과 결정론적 코드의 효율성을 결합하여 시너지를 냄
이런 말이 있지. 손에 망치 하나 들고 있으면 세상 모든 게 못으로 보인다고. 소프트웨어 만들 때 LLM 에이전트만 써본 사람들은 토큰 몇 개 던져서 문제 해결하는 게 세상에서 제일 쉽고 편하겠지. 근데 그게 항상 최고거나 효율적인 방법은 아닐 수도 있어. 뭐, 딱히 잘못된 건 아니야. 이 글을 쓰는 목적은 네 연장에 새로운 도구 하나 더 얹어주려는 거니까.
자, 그럼 LLM이랑 AI 에이전트 나오기 전 코딩을 한번 생각해보자고. 그땐 뭐였냐? 컴퓨터가 그대로 따라 할 명령어를 짜는 거였지. 사실상 자동화야. 데이터를 저장하고, 옮기고, 장비나 기계를 자동으로 돌리는 거. 이걸 "결정론적(deterministic)"이라고 불렀어. 같은 입력값을 넣으면 (대부분의 경우) 항상 같은 결과가 나온다는 뜻이지. 그러니까 어떤 작업을 하는 스크립트를 짰다면, 같은 데이터를 넣었을 때 똑같은 결과가 나와야 정상인 거야. 좀 까다로울 순 있어도 진짜 대단한 거였지. 내가 예전에 썼던 간단한 예시를 들어볼게.
네가 계산기 앱을 만든다고 치자. 숫자 두 개를 더하는 기능이 필요해. a랑 b를 받아서 a + b를 돌려주는 add()라는 함수가 있겠지. 이걸 백만 번 연속으로 호출해도 결과는 항상 정확히 3이 나올 거야. 매번 똑같이. 이게 바로 결정론적이라는 거지.
이제 지금으로 넘어와 보자. LLM이랑 AI 에이전트가 있잖아. 얘네는 코딩의 그 결정론적인 측면을 완전히 뒤집어버렸어. LLM한테 프롬프트를 던지면 매번 똑같은 결과가 나올 거라는 보장이 전혀 없거든. 재밌는 건, "1이랑 2를 더해서 결과 알려줘"라는 프롬프트로 LLM을 백만 번 호출한다고 쳐보자. 매번 똑같은 응답이 나올 거라고 얼마나 확신할 수 있어? 대부분은 3이라는 숫자를 주겠지. 어쩌면 매번 그럴 수도 있고. 근데 숫자만 나올까? "네! 알겠습니다! 숫자 더해드릴게요: 정답은 3입니다"라고 하거나, 그냥 "3"만 띡 던져줄 수도 있겠지 (사실 LLM은 말이 너무 많아서 후자는 좀 힘들겠지만). 그리고 프롬프트에 "결과값만 출력해"라거나 "간결하게 말해"라고 적어본 적 다들 있지? 그게 어느 정도는 먹히는데, 항상 그런 건 아니잖아. 이미 지겹도록 들은 얘기겠지만, 확실히 해두자고. LLM은 **비결정론적(non-deterministic)**이야.
근데 한 가지 짚고 넘어가자. 비결정론적인 게 나쁜 건 아니야! 오히려 정반대지! 그게 바로 LLM이랑 AI 에이전트를 마법처럼 만드는 핵심이니까. 오타가 나거나, 문법이 틀리거나, 말이 좀 애매해도 프롬프트만 잘 던지면 알아서 찰떡같이 알아듣고 원하는 결과를 내주잖아. 결정론적인 코드로는 보통 꿈도 못 꿀 일이지. 근데 이 둘 사이엔 공생 관계가 있어. 음과 양 같은 거지. 서로 엄청나게 보완해주거든.
이 글의 주제가 바로 그거야. 그 관계를 짚어주고 말로 풀어내는 거. 내 가설은 이거야 (틀릴 수도 있지만, 뭐 쓰는 동안은 재밌으니까): 코딩을 처음 시작하면서 '바이브 코딩(vibe coding)'으로 입문한 사람들은 아마 LLM 쪽 코딩만 경험해봤을 거야. 비결정론적인 쪽만 말이지. 만약 이 말이 공감된다면, 코딩의 결정론적인 면도 좀 알려주고 싶어. 이 둘이 어떻게 서로를 보완하는지 보여줄게.
말만 하지 말고 보여줄게
좋아, 너무 뜬구름 잡는 소리만 했네. 구체적인 예시를 들어보자. 흔한 사용 사례 하나를 잡아서 결정론적인 방식이랑 비결정론적인 방식 둘 다 보여줄게. 네가 '던전 크롤러 칼(Dungeon Crawler Carl)' 시리즈에 엄청 빠져 있다고 치자 (나 그 시리즈 진짜 좋아해... 아니, 오디오북이 대박이지. 다 들어버렸어 :D). 다음 책 언제 나오는지 새로운 정보가 뜨면 바로 알고 싶고, 이 과정을 자동화하고 싶은 거야.
비결정론적인 방식
가장 먼저 떠오르는 건 이 방식일 거야. 그게 뭐냐고? LLM한테 매일 웹사이트 검색 시켜서 뭐 바뀐 거 있으면 알려달라고 하는 거지. 이것도 완전히 유효한 접근법이고, 확실한 장점들도 있어:
- 웹사이트가 바뀌어도 매번 잘 작동함
- 아주 맞춤화된 응답을 받을 수 있고, 변경 사항을 요약해 줌
근데 단점은 뭘까?
- 매번 토큰을 잡아먹음 (꽤 비쌈)
- 좀 느릴 수 있음 (근데 솔직히 그렇게 나쁘진 않을 듯)

