병목 현상이 옮겨졌다. 눈치채셨나요?

발행: (2026년 6월 10일 AM 09:37 GMT+9)
11 분 소요
원문: Dev.to

출처: Dev.to

레벨 5 엔지니어 — Issue #2

서문

본격적으로 들어가기 전에 미리 밝혀두고 싶은 것이 있습니다. 이 글에 나오는 프레임워크는 전부 제 것이 아닙니다. 여기서 다루는 아이디어는 저보다 훨씬 더 오래, 그리고 더 깊게 고민해 온 두 사람에게서 온 것이며, 그들에게 먼저 충분한 크레딧을 드려야 합니다.

Dan Shapiro — Glowforge CEO이자 Wharton Research Fellow이며, 이 대화에 어휘를 부여한 사람. 그의 블로그 글 “The Five Levels: from Spicy Autocomplete to the Dark Factory”는 제가 말하려는 모든 것의 개념적 골격입니다. 원문을 읽어보세요. 짧고 날카롭으며, 가장 좋은 방식으로 불편함을 느끼게 할 것입니다. danshapiro.com

Nate B. Jones — AI 전략가, 무과대비 실천가, 그리고 그의 유튜브 채널을 보고 제가 이 사다리에서 실제로 어느 위치에 있었는지 스스로 속이고 있었다는 것을 깨달은 사람. 그의 영상 “The 5 Levels of AI Coding (Why Most of You Won’t Make It Past Level 2)”가 이번 뉴스레터 전체를 촉발했습니다. natebjones.com영상 보기

이 뉴스레터 — The Level 5 Engineer — 는 저의 공개 학습 로그입니다. 저는 시니어 소프트웨어 엔지니어이자 테크 리드이며, 좋은 날엔 이 뉴스레터 제목의 맥락에서 레벨 2와 레벨 3 사이 어딘가에 있습니다. 목표는 레벨 5. 저는 그 여정을 실시간으로 기록하고 있습니다 — 프레임워크, 도구, 사고방식의 전환, 그리고 내가 잘못하고 있었다는 걸 깨달은 순간들. 비슷한 여정을 걷고 있다면, 자리를 잡으세요.

Issue 1을 읽었다면, 지도를 얻었을 겁니다. 6개의 레벨, 대부분의 엔지니어가 탈출하지 못하는 고원, 그리고 소수의 팀이 조용히 프로덕션에서 운영하고 있는 다크 팩토리. 놓쳤다면 먼저 읽어보세요 — 이번 호는 바로 그 위에 직접 얹혀 있습니다.

이번 호는 레벨 3에서 레벨 4로 이동하려 할 때 일어나는 가장 중요한 전환에 관한 것입니다. 도구가 아니라, 사고방식이 아니라, 병목입니다.

왜냐하면 그 병목이 움직였고, 대부분은 눈치채지 못했기 때문입니다.

속도가 문제가 되지 않을 때

우리 대부분의 커리어 동안, 소프트웨어 개발의 병목은 구현 속도였습니다. 아이디어가 있었고, 설계가 있었고, 티켓이 있었으며 — 제약은 손가락이 얼마나 빨리 코드를 짤 수 있느냐였습니다. 바로 그 세계를 최적화했죠. 그래서 우리는 벨로시티를 측정했고, 스탠드업을 만들었으며, “10배 엔지니어”라는 표현이 부끄러움 없이 입에 오르내렸습니다.

AI가 그 병목을 완전히 열어버렸습니다.

레벨 2에서는 구현이 거의 하룻밤 사이에 제약이 사라집니다. 에이전트와 페어링을 하면 코드가 그냥… 나타납니다. 며칠 걸리던 기능이 몇 시간, 몇 분이면 완성됩니다. 문제가 해결된 듯 보이죠.

하지만 실제로는 해결되지 않았습니다. 숨겨져 있던 다른 병목을 드러낸 것뿐입니다.

새로운 병목은 명세 품질입니다.

에이전트는 여러분이 충분히 정확하게 설명할 수 있는 어떤 것이든 만들 수 있습니다. 여기서 핵심은 정확하게라는 단어입니다. 애매하고 반쯤 형성된 아이디어—인간 개발자가 합리적인 가정과 짧은 슬랙 메시지로 메꿔줄 수 있는 그런 아이디어—를 넘겨주려 하면, 에이전트는 설득력 있게 보이지만 원하지 않은 결과를 환각하거나, 멈추거나, 더 나쁜 경우 자신감 있게 완전히 틀린 것을 만들어 버립니다.

제약은 이제 구현 능력이 아니라 명세 능력이 됩니다.

나쁜 명세가 실제로 어떤 모습인가

불편한 진실을 말하자면, 엔지니어가 쓰는 대부분의 “요구사항”은 실제 명세가 아닙니다. Jira 티켓에 입힌 분위기일 뿐입니다.

“사용자 엔드포인트에 페이지네이션을 추가한다.”
이것은 명세가 아닙니다. 페이지당 결과 수는? 기본값은 설정 가능해야 하나? 페이지 번호가 전체를 초과하면 빈 배열을 반환할지 404를 반환할지? 정렬 순서는? 커서 기반인가 오프셋 기반인가? 아직 페이지 파라미터를 보내지 않는 기존 API 소비자는 어떻게 될까?

인간 개발자는 스탠드업에서 이런 질문을 하거나 맥락을 통해 답을 찾습니다. 레벨 4에서 자율적으로 동작하는 에이전트는 그렇게 할 수 없습니다. 조용히, 자신 있게, 그리고 일관되게 잘못된 선택을 하게 되며, 그 오류는 프로덕션에 배포될 때까지 눈에 띄지 않을 겁니다.

이 때문에 Dan Shapiro가 강조한 “명세 품질”은 단순 생산성 팁이 아니라, 사다리를 오르기 위한 전제조건입니다. 레벨 2 수준의 명세로는 레벨 4에 도달할 수 없습니다. 시스템이 허용하지 않을 것입니다.

그래서 직접 만들어 보았습니다. 결과는?

이번 호에서는 이론만 떠들기보다 구체적인 무언가를 만들고 싶었습니다. 그래서 실제 상황과 비슷한 시나리오—두 개의 외부 의존성을 가진 전자상거래 주문 관리 API—를 잡고, WireMock으로 의존성을 시뮬레이션하고, 코드 작성 전에 Gherkin 시나리오를 작성했습니다.

전체 프로젝트는 GitHub에 공개돼 있으니, 클론해서 같은 환경을 직접 실행해볼 수 있습니다. 아래 내용은 모두 재현 가능합니다.

시나리오

POST /orders 엔드포인트가 두 개의 외부 서비스와 연동됩니다:

  • 결제 게이트웨이(Stripe와 유사) – 성공, 거절, 타임아웃 가능
  • 재고 서비스 – 재고 확인, 품절 보고, 부분 가용성 보고 가능

현실감 있으면서도 오후에 끝낼 수 있을 정도로 범위가 제한된, 백엔드 엔지니어라면 흔히 마주치는 통합 복잡성입니다.

1단계 — 먼저 명세를 작성합니다. 실제로는 먼저.

아래는 구현 코드를 한 줄도 쓰기 전에 만든 5개의 Gherkin 시나리오입니다:

Feature: Order Creation

  Scenario: Order is successfully created when payment succeeds and all items are in stock
    Given a registered user with id "user-123"
    And the inventory service confirms all items are in stock
    And the payment gateway will accept the charge
    When the user submits an order for SHOE-RED-42 and BELT-BRN-M
    Then the order status is "CONFIRMED"
    And the response includes an order id
    And the payment gateway received exactly one charge request
    And the inventory service received a reservation request

  Scenario: Order is rejected when payment is declined
    Given a registered user with id "user-456"
    And the inventory service confirms all items are in stock
    And the payment gateway will decline the charge
    When the user submits an order for SHOE-RED-42 and BELT-BRN-M
    Then the order status is "PAYMENT_FAILED"
    And the response status code is 402
    And the response includes the decline reason "INSUFFICIENT_FUNDS"
    And the inventory reservation is released
    And no order id is issued

  Scenario: Order is rejected when an item is out of stock
    Given a registered user with id "user-789"
    And the inventory service reports SHOE-RED-42 is out of stock
    When the user submits an order for SHOE-RED-42
    Then the order status is "UNAVAILABLE"
    And the response status code is 409
    And the payment gateway is never called

  Scenario: Order surfaces partial unavailability without auto-confirming
    Given a registered user with id "user-321"
    And the inventory service reports SHOE-RED-42 as available but BELT-BRN-M as unavailable
    When the user submits an order for SHOE-RED-42 and BELT-BRN-M
    Then the order status is "PARTIAL_UNAVAILABLE"
    And the response status code is 207
    And the payment gateway is never called
    And
0 조회
Back to Blog

관련 글

더 보기 »

Eidentic 소개

Today we're releasing Eidentic, an open-source TypeScript SDK for building AI agents with self-improving memory and the production fundamentals built in — not b...

Typescript의 타입

Introdução Tipos são uma forma de definir a “forma” ou o contrato dos dados que estamos usando no código. Pensando em Javascript puro, ele é dinâmico: você pode...