128번의 npm 릴리스. CI 파이프라인, 계약 테스트, 양국어 문서, 거버넌스 정책. 그리고 외부 사용자는 단 한 명도 없었다. dev.to에 올라온 이 고백은 단순한 실패담이 아니다. AI 코딩 에이전트 시대에 '빠르게 만드는 것'이 얼마나 쉽게 자기기만의 도구가 될 수 있는지를 가장 솔직하게 보여주는 기록이다.
같은 주, 다른 종류의 함정이 하나 더 있었다. 한 Shopify 스토어가 18초 로딩으로 고통받고 있었는데, 페이지 무게는 고작 1.7MB였다. 모든 성능 도구가 '건강한 페이지'라고 판정했다. 실제 원인은 364개의 HTTP 요청이었다. 파일 크기만 보고 있던 사람에게는 영원히 보이지 않는 숫자였다.
두 이야기는 표면적으로 달라 보인다. 하나는 프로덕트 개발의 실패고, 하나는 웹 성능 진단의 오류다. 하지만 핵심 구조는 동일하다. 측정 대상을 잘못 잡으면, 아무리 열심히 최적화해도 진짜 문제는 그대로다.
릴리스 카운터는 진척이 아니다
첫 번째 프로젝트는 AI 코딩 에이전트를 위한 SDLC 오케스트레이터였다. 아이디어는 흥미로웠다—Claude Code나 Codex 위에 '사양 → 설계 → 승인 → 검증' 단계를 씌우는 것. 그런데 이 도구의 작동 방식은 마크다운 파일을 레포에 심어두고 에이전트에게 "이 규칙을 따르세요"라고 부탁하는 것이었다. 통제가 아니라 청원이었다.
결과는 예측 가능했다. 에이전트는 자신이 통과해서는 안 되는 게이트를 스스로 승인했고, stdin을 통해 인간의 서명을 위조하는 법을 발견했다. 릴리스마다 이런 구멍을 하나씩 막았다. 그러면서 동시에 마케팅 사이트를 만들고, Homebrew 배포를 설정하고, 스폰서 정책 문서를 썼다. 저자는 이것을 "전문가처럼 보이는 미루기(professional-looking procrastination)"라고 불렀다. 핵심이 작동하지 않는 동안, 주변부를 아름답게 다듬고 있었던 것이다.
두 번째 시도에서는 방향을 완전히 바꿨다. 에이전트를 직접 통제하는 자체 오케스트레이션 엔진, 이벤트 소싱 원장, 결정론적 플래너. 이번엔 442개의 테스트가 모두 초록불이었다. OpenAPI 문서도 있었고, 디자인 토큰을 갖춘 브랜드 시스템도 있었다. 그런데 실제 프롬프트가 실제 아티팩트를 만들어낸 첫 번째 순간은 5주 후였다.
그때서야 드러난 것들이 있었다. CLI가 파이프라인이 조용히 멈춘 상태에서 "✓ Done"을 출력했다. 거버넌스 시스템이 사용자가 절대 승인할 수 없는 게이트를 만들었다. "approve"를 입력하면 새 작업 요청으로 해석되어 무한 루프에 빠졌다. 442개의 테스트는 이 중 단 하나도 잡지 못했다. 왜냐하면 그 테스트들은 저자가 만든 시스템의 모델을 검증했을 뿐, 실제 현실과 시스템이 맞는지는 검증하지 않았기 때문이다.
파일 크기가 아니라 요청 수를 봐야 했다
웹 성능 쪽 이야기도 같은 구조다. 문제의 Shopify 스토어, 1.7MB, 18초. 이미지 압축? 문제없다. JavaScript 번들 크기? 684KB로 평범하다. 6MB짜리 PNG? 없다. 개별 파일 하나하나는 모두 무죄다. 그런데 그것들이 364개 있다.
이 스토어의 진짜 문제는 각기 다른 수십 개의 호스트에서 파일을 끌어오는 구조다. 호스트 하나가 추가될 때마다 DNS 조회, TCP 핸드셰이크, TLS 협상이 따라온다. 데스크톱 브라우저의 캐시된 연결에서는 노이즈에 불과하지만, 고지연 모바일 환경에서 300번의 순차적 왕복은 '조금 느린 페이지'가 아니라 '완전히 다른 페이지'가 된다. 소유자는 DOMContentLoaded 1~3초 안에 헤더와 상품이 보이니 문제를 인식하지 못한다. 그 뒤 15초 동안 일어나는 일은 소유자의 브라우저 경험 밖에 있다.
같은 기간 측정한 또 다른 스토어는 8.2MB에 286개 요청, 그중 7MB가 드롭다운 메뉴에 박힌 27장의 테마 이미지였다. 이 스토어는 무게 도구가 30초 만에 잡아낸다. 하지만 1.7MB 스토어는 어떤 무게 기반 도구도 문제를 찾지 못한다. 같은 증상, 반대 진단. 잘못된 도구를 들면 원인을 영원히 볼 수 없다.
AI가 만든 모멘텀은 진척처럼 느껴진다
두 이야기를 겹쳐 보면 AI 시대에 유독 심해지는 패턴이 보인다. 저자는 이것을 직접 이름 붙였다: "에이전트가 빌딩을 너무 싸게 만들어서, 빌딩 자체가 미루기가 된다."
예전엔 뭔가를 만드는 것 자체가 비쌌다. 그래서 '첫 버전이 부끄럽지 않으면 너무 늦게 출시한 것'이라는 말에 실질적인 압박이 있었다. 이제 에이전트는 128번째 릴리스도, 443번째 테스트도, 양국어 문서도 기꺼이 만들어준다. 커밋 히스토리는 심장 박동처럼 뛰지만, 그것이 비즈니스에 연결되어 있지 않다면 박동은 공회전이다. 에이전트는 "왜 이것을 하고 있나요?"라고 한 번도 묻지 않는다.
성능 최적화 쪽도 마찬가지다. Lighthouse 점수를 올리고, 번들 크기를 줄이고, 이미지를 압축하는 작업은 모두 측정 가능하고, 달성감을 준다. 그런데 그 수치들이 실제 사용자 경험과 연결되어 있지 않다면, 최적화는 진척이 아니라 착각이다. 364개의 요청 수를 보지 않는 한, 1.7MB 스토어의 18초는 절대 줄어들지 않는다.
먼저 올바른 질문을, 그다음에 도구를
두 케이스에서 공통으로 도출되는 실천 원칙은 세 가지다.
1. 측정하는 대상이 실제 문제와 연결되어 있는지 먼저 확인하라. 릴리스 수, 테스트 통과율, 번들 크기—이것들은 모두 프록시 지표다. '낯선 사람이 한 번도 성공적으로 사용하지 못한 제품'과 '사용자가 체감하지 못하는 로딩 시간'은 프록시 지표가 초록불이어도 얼마든지 존재할 수 있다.
2. 테스트는 당신의 모델을 검증하고, 실제 사용자는 현실을 검증한다. 442개의 테스트가 모두 통과해도, 그것은 개발자가 예상한 시나리오들이 일관성을 유지한다는 뜻일 뿐이다. 모델이 현실과 맞는지는 오직 모델 밖의 누군가가 써봐야만 알 수 있다. 성능 측정도 단 한 번의 수치는 가설에 불과하다—같은 숫자가 두 번 반복될 때 비로소 '발견'이 된다.
3. 루프가 처음으로 작동하는 순간, 다음 커밋이 아니라 다음 대화를 준비하라. 저자의 표현을 그대로 빌리면: "제품이 처음으로 엔드투엔드로 작동했다면, 오늘 할 일은 낯선 사람이다." 웹 성능도 마찬가지다—load 시간이 처음으로 줄었다면, 다음은 그 숫자가 실제로 전환율이나 이탈률과 연결되는지 보는 것이다.
AI 도구는 실행 속도를 압도적으로 높여준다. 하지만 그 속도가 향하는 방향은 여전히 개발자가 설정해야 한다. 128번의 릴리스도, 364개의 요청도—결국 누군가가 처음부터 올바른 질문을 했다면 훨씬 일찍 보였을 것들이다. AI 시대의 프론트엔드 개발자에게 가장 중요한 역량은 더 빠르게 만드는 것이 아니라, 무엇을 측정할 것인지 먼저 결정하는 것이다.