바이브 코딩은 일을 의사결정으로 옮긴다
에이전트끼리 주고받으며 완성도 있는 서비스에 스스로 도달할 것이라 기대했습니다. 실제로는 어떤 저장소에도 답이 들어 있지 않은 질문 앞에서 멈춥니다. 결과를 가르는 것은 그 순간을 몇 번 알아차렸고, 그때마다 얼마나 옳게 골랐는가입니다.
코딩 에이전트로 서비스를 만들기 시작했을 때, 저는 이 과정이 스스로 닫힐 것이라고 기대했습니다. 요즘 유행하는 사주 사이트 같은 것을 만들어 달라고 요청하면, 에이전트들이 서로 결과를 주고받으며 하나가 만들고 다른 하나가 검토하고 또 다른 하나가 부족한 지점을 찾아 다음 개선 방향을 제안하는 식으로, 결국 완성도 있는 서비스에 자율적으로 도달하리라고 본 것입니다.
이 순환은 실제로 돕니다. 코드가 생기고 테스트가 붙고 빈 곳이 발견되어 메워집니다. 다만 반복해서 멈추는 지점이 있습니다. 모델이 부족해서가 아니라, 그 질문의 답이 저장소 안 어디에서도 유도되지 않기 때문입니다.
에이전트가 대신 답할 수 없는 질문이 있다
순환을 멈춰 세운 질문은 한 번도 기술적인 것이 아니었습니다. 제가 실제로 운영하는 제품에서 나온 세 가지입니다.
- 결과가 얼마나 확신에 차서 말해야 하는가. Clad는 사진을 퍼스널 컬러 분석 결과로 바꿉니다. 그런데 시즌 이름만으로는 사용자가 알 수 있는 것이 없고, 조명과 카메라 보정과 편집이 결과를 흔듭니다. 그래서 근거를 설명하고, 어느 조건에서 신뢰도가 떨어지는지 말하고, 다시 촬영할 경로를 둡니다. 확정 진단이 아니라 출발점을 주는 쪽을 택한 것입니다. 코드 어디에도 그렇게 하라는 근거는 없고, 오히려 더 단호하게 말하는 버전이 시연에는 좋았을 것입니다.
- 무엇을 팔지 않을 것인가. 해피버스타운은 친구와 가족이 소중한 사람의 생일에 모이는 픽셀 타운입니다. 이곳의 꾸미기 아이템은 참여로만 해금되고 결제로는 아예 살 수 없습니다. 가장 뻔한 수익 모델을 의도적으로 지운 것이고, 그 대신 보상의 순환이 "그 자리에 나타나는 것"에서 나오게 됩니다. 에이전트는 주어진 목표를 향해 최적화합니다. 어떤 목표를 스스로 버릴지는 정하지 않습니다.
- 모델의 상한을 어디에 둘 것인가. 결과가 나아지니 상위 모델로 올릴 것인가, 아니면 지금 수준으로도 충분히 정확하니 단가를 지키며 현재 모델을 유지할 것인가. 모든 AI 기능이 이 질문을 안고 있고, 그중 어느 것도 스스로 답하지 않습니다.
이것은 모델의 역량 공백이 아닙니다. 답이 "내가 이 제품을 무엇으로 만들고 싶은가"에 달려 있는 질문이고, 그 의도는 에이전트가 읽을 수 있는 어디에도 적혀 있지 않습니다.
자동 검증은 코드를 확인할 뿐 제품을 확인하지 않는다
지난주에 제 사이트의 소개 페이지 인물 사진이 잘못 나오고 있었습니다. 1200×1600 사진인데 496×1847로 그려지고 있었습니다. CSS 클래스 하나가 비율 지정을 덮어써서, 얼굴이 세로로 길게 잘린 조각으로 표시된 것입니다.
그런데 모든 검사가 통과했습니다. 린트, 타입 체크, 단위 테스트, 접근성 검사와 시각 스냅샷을 포함한 e2e, 프로덕션 빌드, 라우트와 메타데이터를 확인하는 빌드 후 검증까지 전부 초록불이었습니다. 각자의 기준으로는 틀린 것이 없었기 때문입니다. 마크업은 유효했고 테스트는 작성된 대로 검증했으며, 그 어떤 것도 사진이 어떻게 보여야 하는지는 알지 못합니다.
사람이 페이지를 열고 "이 사진이 잘려서 나온다"고 말했습니다. 그 한 문장에 담긴 제품 정보가 테스트 전체보다 많았습니다.
한계의 모양이 여기에 있습니다. 에이전트는 코드가 동작하는지, 주어진 명세와 맞는지 검증할 수 있습니다. 그러나 그 명세가 옳았는지는 검증하지 못합니다. 제품의 좋고 나쁨을 가르는 것은 두 번째 질문입니다.
트리, 그리고 레버리지가 옮겨간 자리
저는 이것을 의사결정 트리로 생각하게 되었습니다. 생성되는 결과 하나하나가 분기점입니다. 에이전트가 바꾼 것은 분기를 만들어 내는 비용입니다. 제가 검토할 수 있는 속도보다 빠르게 도착하고, 그 속도 자체는 분명한 이득입니다.
바뀌지 않은 것은 그 트리에 이름표가 없다는 사실입니다. 어느 가지가 내가 가려는 곳으로 이어지는지 에이전트는 알려주지 못합니다. 내가 가려는 곳은 코드 안에 없기 때문입니다. 그래서 일의 성격이 옮겨 갔습니다. 타이핑하는 시간은 줄고 고르는 순간은 늘었으며, 그 순간은 예전보다 훨씬 자주 찾아옵니다.
그대로 적어 보면, 결과물의 품질은 제가 실제로 붙잡은 의사결정 지점의 수에, 그때마다 옳게 고른 비율을 곱한 값에 가깝습니다. 두 항 모두 중요하지만 사람들이 놓치는 쪽은 앞의 항입니다.
진짜 실패는 잘못 고르는 것이 아니기 때문입니다. 거기에 결정이 있었다는 사실 자체를 알아차리지 못하는 것입니다. 생성된 코드는 빌드되고 화면은 그려지고 테스트는 초록불이며, 분기는 기본값으로 선택됩니다. 아무도 결정하지 않았는데 무언가는 결정되어 있습니다.
애정은 감정이 아니라 운영 속성이다
계속 돌아오게 되는 단어는 애정입니다. 이 제품이 정말로 좋아지기를 바라는 정도입니다. 감상적으로 들리지만 실제로는 기계적으로 작동합니다. 애정은 테스트 출력 대신 페이지를 직접 열어 보게 만드는 힘이고, 생성된 플로우를 그대로 받아들이는 편이 훨씬 빠르고 아무도 문제 삼지 않을 상황에서 결제 시점을 다시 묻게 만드는 힘입니다.
제품에 애정을 가진 사람은 기능 하나당 더 많은 분기점을 붙잡고, 그중 더 많이 맞힙니다. 추상적인 실력이 더 좋아서가 아니라 들여다봤기 때문입니다. 주의가 입력이고 적중률이 출력입니다.
그래서 저는 프롬프트에서 완성된 서비스까지 완전히 자율적으로 가는 길이 목표라거나 가까이 있다고 더는 생각하지 않습니다. 생성은 흔해졌고 판단이 병목입니다. 어떤 엔지니어의 제품과 다른 엔지니어의 제품을 가르는 것은 코드를 얼마나 빨리 만들어 내는가가 아니라, 결정을 몇 개나 알아차리고 그중 몇 개를 옳게 고르는가에 점점 더 가까워지고 있습니다.