본문으로 건너뛰기
피드

7개월 바이브코딩 후 손코딩으로 돌아간 개발자의 결론

ai-ml 약 11분

한 개발자가 GPU 특화 쿠버네티스 TUI 도구 k10s를 7개월 동안 Claude 기반 바이브코딩으로 만들고, 결국 코드를 폐기한 뒤 처음부터 다시 쓰기로 했다. 빠른 기능 추가는 가능했지만 구조 설계, 상태 격리, 동시성, 타입 안전성에서 누적된 문제가 한꺼번에 터졌다는 경험담이다.

  • 1

    k10s는 234커밋, 약 30주말 동안 Claude 세션으로 만들어졌지만 1690줄짜리 model.go와 500줄 Update 함수, 110개 switch/case를 가진 거대한 상태 객체로 커짐

  • 2

    AI는 기능을 빠르게 만들었지만 아키텍처를 스스로 잡지 못했고, 새 기능마다 기존 전역 상태와 키 핸들러에 조건문이 추가됨

  • 3

    저자는 CLAUDE.md나 AGENTS.md에 아키텍처 불변식, 상태 소유권, 범위 제한, 타입 기반 데이터 표현, 동시성 규칙을 명시해야 한다고 정리함

7개월 바이브코딩의 결론

  • 이 글의 결론은 꽤 직설적임. “AI는 기능은 잘 만들지만, 아키텍처는 안 만든다”는 것

    • 저자는 GPU 특화 Kubernetes TUI 도구인 k10s를 7개월 동안 Claude와 바이브코딩으로 만들었음
    • 총 234커밋, 약 30번의 주말, Claude 토큰이 버티는 만큼 세션을 돌려가며 만든 프로젝트였음
    • 결과적으로 이 도구를 아카이브하고 처음부터 다시 쓰기로 함
  • k10s는 원래 “GPU 클러스터 운영자를 위한 k9s” 같은 도구였음

    • NVIDIA 클러스터를 운영하는 사람이 GPU 사용률, DCGM 메트릭, 유휴 노드, 전력 사용량, 메모리 사용량을 터미널에서 바로 보게 하는 게 목표였음
    • 특히 시간당 32달러를 태우는 유휴 GPU 노드를 찾는 것처럼 꽤 실전적인 문제를 겨냥했음
    • Go와 Bubble Tea로 만들었고, 초반에는 실제로 잘 돌아갔다고 함
  • 초반 바이브코딩은 말 그대로 마법처럼 느껴졌다고 함

    • “파드 뷰에 라이브 업데이트 추가해줘”라고 하면 Claude가 바로 구현함
    • 리소스 목록, 네임스페이스 필터, 로그 스트리밍, describe 패널, Vim 키바인딩까지 몇 주말 만에 붙었음
    • 기본적인 k9s 클론은 3주말 정도에 나왔고, 저자는 평소보다 10배 빠르게 만드는 느낌을 받음
  • 문제는 핵심 기능인 GPU fleet view를 붙인 뒤 터짐

    • fleet view는 모든 노드의 GPU 할당량, 사용률, 온도, 전력, 메모리를 한 화면에 보여주는 전용 뷰였음
    • Claude는 이 기능도 한 번에 그럴듯하게 만들었음. GPU/CPU/All 탭, 할당 바, 색상 상태 표시까지 나옴
    • 그런데 다시 pods 뷰로 돌아가자 테이블이 비고, 라이브 업데이트가 멈추고, 노드 뷰에는 fleet 필터의 오래된 데이터가 남았음

중요

> 저자가 폐기하기로 한 코드의 상징은 1690줄짜리 model.go였음. 하나의 Model 구조체가 UI, Kubernetes 클라이언트, 로그, describe, fleet, 캐시, 마우스 처리까지 전부 들고 있었음.

무너진 구조에서 나온 5가지 교훈

  • 첫 번째 교훈은 “AI는 기능을 만들지, 구조를 만들지 않는다”임

    • k10s의 리소스 로딩 핸들러에는 fleet view만을 위한 특수 조건문이 generic path 안에 들어가 있었음
    • 새 뷰가 커스텀 동작을 필요로 할 때마다 기존 핸들러에 분기가 하나씩 추가되는 구조였음
    • 이전 뷰의 데이터가 새 뷰에 새는 걸 막기 위해 m.logLines = nil, m.resources = nil 같은 수동 초기화가 9곳이나 흩어져 있었음
  • 저자가 제안한 대응은 AI에게 맡기기 전에 사람이 아키텍처 불변식을 직접 쓰라는 것임

    • 각 뷰는 독립된 View 인터페이스를 구현하고 다른 뷰의 상태에 접근하지 못하게 해야 함
    • 비동기 데이터는 AppMsg 같은 타입화된 메시지로만 들어오게 해야 함
    • 새 뷰 추가가 기존 뷰 수정을 요구하면 설계가 잘못됐다는 규칙을 CLAUDE.md나 AGENTS.md에 넣으라고 함
  • 두 번째 교훈은 “AI의 기본 산출물은 god object”라는 것

    • 하나의 Model 구조체가 모든 상태를 들고, 500줄짜리 Update 함수가 110개 switch/case로 이벤트를 처리하고 있었음
    • s 키 하나도 로그 뷰에서는 autoscroll, pods 뷰에서는 shell, containers 뷰에서는 container shell로 동작함
    • Enter 키 처리도 contexts, namespaces, logs, generic drill-down이 전부 같은 flat switch 안에서 m.currentGVR.Resource 문자열 비교로 갈라짐
  • 이 구조에서는 키 하나가 무슨 일을 하는지 지역적으로 알 수 없음

    • keyMap에는 로그 전용, describe 전용, fleet 전용, pods 전용 키가 한 구조체에 섞여 있었음
    • Autoscroll과 Shell이 둘 다 s 키를 쓰는 충돌도 “현재 리소스가 뭐냐” 조건문으로 버티는 식이었음
    • 새 기능을 붙이는 가장 쉬운 방법이 기존 전역 키 핸들러에 if문을 더하는 것이었고, AI는 당연히 그 길을 택함
  • 세 번째 교훈은 “속도감이 스코프를 망가뜨린다”는 것

    • 원래 목표는 GPU 클러스터 운영자를 위한 좁은 도구였음
    • 그런데 AI가 pods, deployments, services, command palette, mouse support, contexts, namespaces를 쉽게 붙여주니 범용 Kubernetes TUI가 되어버림
    • 기능은 공짜처럼 보였지만, 실제 비용은 전역 상태와 조건문, 키 충돌, 복잡도 증가로 누적되고 있었음

ℹ️참고

> 저자는 “AI는 무한한 구현 예산을 주는 게 아니라 무한한 라인 수 예산을 준다”고 표현함. 복잡도 예산은 여전히 사람이 관리해야 한다는 얘기임.

  • 네 번째 교훈은 positional data가 시한폭탄이라는 것

    • k10s는 Kubernetes 리소스를 OrderedResourceFields []string 형태로 납작하게 만들었음
    • fleet 정렬 로직은 ra[3]을 Alloc, ra[2]를 Compute, ra[0]을 Name으로 가정했음
    • 컬럼 순서가 JSON 설정에서 하나만 바뀌어도 컴파일러는 아무 말 안 하는데 정렬과 렌더링은 조용히 틀어질 수 있음
  • 저자는 구조화된 데이터는 render 직전까지 typed struct로 유지해야 한다고 말함

    • FleetNode라면 name, instance_type, compute_class, alloc 같은 필드가 있어야 함
    • 정렬은 row[3] 같은 인덱스가 아니라 node.alloc 같은 이름 있는 필드로 해야 함
    • AI는 []string이 테이블 렌더링에 바로 들어가니까 자주 선택하지만, 장기 유지보수에는 타입이 훨씬 강한 안전장치가 됨
  • 다섯 번째 교훈은 “AI는 상태 전이를 소유하지 않는다”임

    • Bubble Tea의 기본 아이디어는 Update가 메시지를 받아 상태를 바꾸는 구조인데, k10s는 tea.Cmd 안의 goroutine에서 Model 필드를 직접 만졌음
    • 그 closure는 m.resources, m.table, m.viewWidth를 읽고 쓰는데 View도 메인 goroutine에서 같은 필드를 읽음
    • 락도 없고 mutex도 없으니 전형적인 data race가 생길 수 있는 구조였음
  • 올바른 방식은 배경 작업이 UI 상태를 직접 바꾸지 않고 메시지만 보내는 것임

    • watcher, scraper, API call은 데이터를 가져와 typed message로 main loop에 넘겨야 함
    • 실제 상태 변경은 main event loop에서만 일어나야 함
    • render나 view 함수는 부작용 없이 순수하게 현재 상태를 그리기만 해야 함

그래서 저자는 뭘 바꾸나

  • 저자는 k10s를 Rust로 다시 쓰기로 함

    • Rust가 무조건 더 좋아서라기보다, 본인이 Rust에서는 코드 냄새를 더 빨리 알아차릴 수 있기 때문이라고 설명함
    • AI가 그럴듯한 코드를 내놓을 때 사람이 “이거 이상한데?”라고 느끼는 감각이 여전히 필요하다는 얘기임
  • 가장 큰 변화는 설계를 사람이 먼저 한다는 점임

    • 첫 프롬프트 전에 인터페이스, 메시지 타입, 소유권 규칙, 범위 제한을 문서로 적겠다고 함
    • AI가 잘못 결정하던 아키텍처 판단을 더 이상 즉석에서 맡기지 않겠다는 것
    • 바이브코딩을 버린다기보다, AI가 들어올 수 있는 경계와 규칙을 사람이 먼저 잡는 쪽으로 바뀐 셈임
sequenceDiagram
    participant 개발자
    participant Claude
    participant 전역Model
    participant UI뷰
    participant 배경작업
    개발자->>Claude: 새 기능 추가 요청
    Claude->>전역Model: 필드와 조건문 추가
    UI뷰->>전역Model: 같은 상태를 읽고 렌더링
    배경작업->>전역Model: goroutine에서 상태 직접 변경
    전역Model-->>UI뷰: 이전 뷰 데이터와 상태가 섞임
    개발자->>개발자: 구조를 읽고 재작성 결정

기술 맥락

  • 이 글의 핵심 선택은 AI에게 기능 구현을 맡기더라도 아키텍처 결정은 사람이 먼저 고정해야 한다는 거예요. 왜냐하면 LLM은 보통 지금 프롬프트를 만족시키는 가장 짧은 경로를 찾고, 장기적으로 상태 소유권이 어떻게 썩어가는지는 직접 책임지지 않거든요.

  • k10s에서 특히 위험했던 건 뷰별 상태가 분리되지 않았다는 점이에요. 로그, describe, fleet, 리소스 테이블이 하나의 Model 안에 있으면 새 기능을 붙일 때마다 기존 상태를 수동으로 비워야 해요. 이런 구조는 한 번만 초기화를 빼먹어도 이전 화면 데이터가 다음 화면에 섞이는 식으로 터져요.

  • typed struct를 쓰라는 조언도 단순한 취향 문제가 아니에요. []string으로 테이블 데이터를 들고 있으면 row[3]이 정말 GPU 할당량인지 컴파일러가 확인해줄 방법이 없어요. 반대로 FleetNode.alloc처럼 이름 있는 필드를 쓰면 컬럼 순서가 바뀌어도 비즈니스 로직이 조용히 깨질 가능성이 줄어요.

  • 동시성 규칙은 더 빡세게 봐야 해요. 배경 goroutine이 UI 상태를 직접 바꾸면 99%는 멀쩡해 보여도 1%에서 이상한 화면 깨짐이나 레이스가 나올 수 있어요. 그래서 배경 작업은 메시지만 보내고, 메인 루프만 상태를 바꾸게 하는 게 TUI든 GUI든 오래 버티는 구조예요.

이 글은 ‘AI 코딩 별로임’이 아니라 ‘AI가 잘하는 영역과 사람이 절대 놓치면 안 되는 영역’을 꽤 구체적으로 보여줌. 특히 장기 프로젝트에서 속도 지표가 복잡도 예산을 가려버린다는 대목은 팀 단위 AI 도입에도 그대로 적용됨.

댓글

댓글

댓글을 불러오는 중...

ai-ml

제미나이 도구 호출 능력을 2,600만 파라미터 모델로 증류한 니들 공개

Cactus Compute가 Gemini 3.1의 도구 호출 능력을 2,600만 파라미터짜리 초소형 모델 Needle로 증류해 공개했다. 맥이나 PC에서 로컬 파인튜닝까지 가능하고, 프로덕션 환경에서는 프리필 6,000 토큰/초, 디코드 1,200 토큰/초를 낸다고 주장한다. 개인용 AI 기기에서 함수 호출만 빠르게 처리하는 작은 모델 실험으로 보면 꽤 흥미로운 공개다.

ai-ml

딥시크 V4 인덱서, 6기가바이트 메모리로 백만 토큰까지 밀어붙인 논문

딥시크 V3.2와 V4의 압축 희소 어텐션에서 병목이 되는 인덱서 단계를 스트리밍 방식으로 바꿔, 기존 구현이 6만5536 토큰에서 메모리 부족으로 죽던 문제를 104만8576 토큰까지 확장했다. 핵심은 전체 점수 텐서를 만들지 않고 청크 단위로 top-k를 나눠 계산한 뒤 병합하는 방식이며, 단일 엔비디아 H200에서 피크 메모리 6.21기가바이트를 기록했다. 다만 논문은 인덱서 단계만 다루며, 실제 체크포인트 기반 종단간 성능이나 더 빠른 어텐션 커널을 주장하진 않는다.

ai-ml

챗지피티가 학습에 좋다던 유명 논문, 결국 철회됨

챗지피티가 학생 학습 성과에 큰 도움이 된다고 주장했던 논문이 출판 약 1년 만에 철회됐어. 스프링거 네이처는 분석의 불일치와 결론 신뢰 부족을 이유로 들었고, 문제의 논문은 이미 500회 넘게 인용된 뒤였어.

ai-ml

샘 올트먼, 법정에서 “머스크가 오픈AI 지배권을 자녀에게 넘기려 했다”고 증언

샘 올트먼이 캘리포니아 오클랜드 연방법원 배심원 앞에서 일론 머스크가 오픈AI의 장기 지배권을 원했고, 사망 후엔 자녀에게 넘기는 방안까지 언급했다고 증언했다. 머스크는 오픈AI가 비영리로 출발했는데도 영리화됐다고 소송을 제기했지만, 올트먼은 오히려 머스크가 영리 전환과 테슬라 편입을 밀었다는 취지로 반박했다.

ai-ml

혜전대, AI로 스마트팜 생산·가공·유통 교육 모델 만든다

혜전대가 2026년 교육부·한국연구재단의 AID 전환 중점 전문대학 지원사업에 충남 지역 연합형 사업단으로 선정됐다. 연암대와 역할을 나눠 스마트팜 생산부터 가공·유통까지 전주기를 디지털화하는 교육 모델을 만들겠다는 내용이다.