결정론적인 일은 자동화에, 추론이 필요한 일은 AI에
바야흐로 AI의 시대입니다. 코드 리뷰도, 리팩토링도, 테스트 작성도 AI에 맡기는 것이 자연스러운 풍경이 됐습니다. 그런데 역설적이게도, AI가 만능처럼 보이는 지금이야말로 필요한 질문이 있습니다.
“이 일, 정말 AI에게 시켜야 하는 일인가?”
훌륭한 엔지니어링은 언제나 ‘목적에 맞는 가장 단순한 도구’를 선택하는 것에서 출발합니다. CSS로 가능한 것은 JavaScript가 아닌 CSS로 처리해야 합니다. 브라우저가 기본으로 제공하는 기능을 사용하는 것이 훨씬 빠르고, 안전하며, 가볍기 때문입니다. 더 강력한 도구가 항상 더 나은 선택은 아니라는 것. 이 원칙은 AI 시대에도 그대로 적용됩니다.
따라서 AI를 맹목적으로 더 많이 사용하는 것보다, 기술의 성격에 따라 명확한 경계를 나눌 때 더 효율적이고 빠른 워크플로우를 만들 수 있습니다. 따라서 이 글에서는 ‘결정론적인 일은 자동화, 추론은 AI’라는 기준을 바탕으로, 프론트엔드 API 연동 코드를 만들 때 AI 워크플로우를 더 효율적으로 만드는 방법과 이를 뒷받침할 구체적인 방법론을 소개해 보려고 합니다.

효율적인 엔지니어링 워크플로우를 구축하기 위해서는 기술적 접근법을 크게 두 가지 영역으로 분리할 수 있습니다.
결정론적 영역(Deterministic)
입력이 같으면 출력도 항상 동일해야 하는 영역입니다. 타입 생성, API 통신 보일러플레이트, 데이터 스키마 동기화, 코드 스타일 통일이 여기에 속합니다. 규칙과 규격이 명확하기 때문에 고도의 추론이 아닌, 오차 없는 ‘기계적 번역’이 핵심입니다.
확률적 영역(Probabilistic)
주어진 맥락과 컨텍스트에 따라 최선의 답이 달라지며, 복잡한 추론과 트레이드오프(Trade-off) 판단이 요구되는 영역입니다. 비즈니스 로직 설계, 레거시 코드의 의도 파악, UI 프로토타입 작성, 아키텍처 리팩토링 제안 등이 대표적입니다.
그럼 AI는 어떤 일에 더 적합할까요? 이 도구는 추론에 강점을 지니고, 그러니 확률적 영역에 투입하는 것이 더 큰 변화를 만들어냅니다.
그런데, 현실에서는 결정론적 영역에까지 AI를 투입하는 경우가 적지 않습니다. 대표적인 예가 swagger.json을 통째로 복사해 프롬프트 창에 붙여넣고 “이거 보고 API 훅이랑 타입 좀 만들어줘”라고 던지는 방식입니다. 언뜻 잘 작동하는 것처럼 보이지만, 여기에는 눈에 잘 띄지 않는 몇 가지 비용이 숨어 있습니다.
동일한 스펙에서 언제나 100% 일치하는 결과물을 보장하는 전용 도구가 이미 존재하는데도, 조금씩 다른 답을 내놓을 수 있는 AI를 고집할 이유는 없습니다. 적어도 결정론적 영역에서만큼은 전통적인 자동화가 AI보다 훨씬 정확하고, 빠르며, 비용 효율적입니다.

이 원칙이 가장 극적인 효과를 내는 영역이 바로 프론트엔드의 API 연동 코드 작성입니다.
백엔드와 프론트엔드 간의 API 통신은 철저하게 ‘약속(Specification)’에 기반한 결정론적 영역입니다. 게다가 OpenAPI 스펙은 시스템 전체를 관통하는 단일 진실 원천(Single Source of Truth)입니다. 타입도, 함수도, 훅도, 검증 스키마도 전부 이 한 파일에서 끌어낼 수 있습니다. 그러니 이 일에 AI를 쓸 이유가 없습니다.
이 격차가 실제로 어느 정도인지 숫자로 확인하기 위해, 프로젝트의 실제 OpenAPI 스펙(53개 엔드포인트 · 90개 스키마)을 두 방식으로 직접 생성해 측정했습니다. 정답 스펙이 이미 존재하는 결정론적 영역에서 코드젠과 AI의 산출물을 직접 대조하고자, 동일한 OpenAPI 스펙을 양쪽에 그대로 맡겨 진행했습니다.

AI에게는 “이 스펙으로 API 연동 코드를 생성하라”, “Orval로 코드젠을 실행하고 생성 시간·비용·결정성·타입 에러를 측정하라, 결정성 확인을 위해 2회 실행하라”와 같이 지시했습니다.
측정값 자체는 실행 로그, 산출물 diff, tsc --noEmit 결과처럼 기계적으로 검증 가능한 항목이라 측정 주체와 무관하게 동일하게 재현됩니다. 반복 횟수를 2회로 둔 이유도 있습니다. 코드젠은 정의상 몇 번을 돌려도 byte 단위로 동일해 반복 측정 자체가 무의미하고, AI 역시 “매번 다른 결과가 나온다”는 질적 대비를 보이는 데는 2회로 충분했기 때문입니다.
결국 여기서 확인하려는 명제는 “AI가 평균 몇 % 흔들리는가”가 아니라 “결정론적 도구는 항상 같고 AI는 매번 다르다”는 대비였습니다.
Orval은 엔드포인트를 약 1초 만에 생성했습니다. 비용은 $0이고, 스펙의 모든 필드를 정확히 옮겼으며, 타입 에러도 없었습니다. 몇 번을 다시 돌려도 byte 단위로 똑같은 코드가 나옵니다.
반면 AI는 같은 일을 하는 데 2~4분이 걸렸고, 실행할 때마다 약 $1.4(약 2,000원)씩 들었습니다. 두 번의 실행 결과가 서로 달랐고, 한 번은 타입 에러 4개를 남겼습니다. 더 느리고, 더 비싸고, 매번 조금씩 다른 코드를 내놓았습니다. 스펙이라는 정답지가 이미 있는 영역에서 코드젠이 속도, 비용, 정확성, 일관성 전 항목에서 압도적이었습니다.

코드젠은 ‘번역기’입니다. Orval은 스펙 JSON을 파싱해 각 스키마와 엔드포인트를 추상 구문 트리(AST)에 가까운 중간 표현으로 올립니다. 그다음 미리 정해진 변환 규칙(템플릿)에 따라 TypeScript 코드를 그대로 방출합니다. 또, 스키마 하나에서 어떤 코드가 나올지는 실행 전에 이미 규칙으로 결정되어 있습니다. 남은 일은 106KB의 JSON을 5,400여 줄의 TS로 ‘기계적으로 옮겨 적는’ 순수 CPU 문자열 변환뿐입니다. 추론도, 탐색도, GPU도, 네트워크 왕복도 없습니다. 그래서 5,400여 줄을 통째로 만들어내는 데 1초가 걸리지 않습니다.
AI는 ‘생각하면서 타이핑하는 기계’입니다. LLM은 자기회귀(autoregressive) 방식으로 동작합니다. 출력 코드를 토큰(대략 몇 글자) 단위로 하나씩, 앞선 토큰을 전부 본 뒤에야 다음 토큰을 생성합니다. 8,000토큰짜리 코드를 출력하려면 8,000번의 순차 연산이 필요하고, 이 순차성 때문에 아무리 좋은 GPU를 붙여도 초당 수십~수백 토큰이 물리적 상한입니다. 여기에 매 요청마다 40k 토큰짜리 스펙을 처음부터 다시 읽어들이는(prefill) 비용이 더해집니다. 즉 AI는 답이 이미 규칙으로 정해져 있는 코드조차 ‘한 글자씩 타이핑’해서 내놓아야 하며, 그 타이핑의 매 순간이 확률적 선택입니다.
코드젠의 또 다른 가치는 개발 경험이 구조적으로 달라지는 지점에 있습니다. 백엔드와 프론트엔드가 어긋날 틈을 컴파일 타임에 막는 런타임 안전성, 관리할 코드 자체를 레포지토리에서 걷어내는 유지보수 부담의 소멸, 그리고 스펙이 요동치는 프로젝트일수록 오히려 커지는 변화 대응력입니다. 그리고 이는 어쩌면 전통적인 자동화가 AI에 비해 가지는 가치를 그대로 보여줄 수 있습니다.

백엔드 응답 필드 이름이 userName에서 name으로 바뀌었는데 프론트엔드가 이를 모르면 사용자 화면에서 버그가 터집니다. 문제는 손으로 짠 타입이나 AI가 과거 스펙으로 만든 타입은 이를 잡아내지 못한다는 것입니다.
반면 코드 생성기를 사용하면 스펙이 바뀌는 즉시 타입이 자동 업데이트되며, 바뀐 필드를 쓰던 코드는 컴파일 에러(빨간 줄)로 즉시 드러납니다. 출력이 결정론적이기 때문에 GitHub Actions 같은 CI/CD 파이프라인에 주기적 스크립트를 걸어둘 수도 있습니다. 사람이 개입하지 않아도 변경 사항이 생기면 자동으로 PR이 올라옵니다.
코드 생성기를 도입하면 API 통신을 위한 Fetch/Axios 함수 정의, Request/Response 타입 선언, Query Key 팩토리 설계, useQuery 커스텀 훅 정의가 모두 자동 생성 영역으로 넘어갑니다. 코드 자체는 여전히 프로젝트 어딘가에 생성되지만, 개발자가 직접 수정하거나 관여할 필요가 없어집니다. 그저 생성된 훅을 import해서 쓰기만 하면 됩니다.
AI가 만든 훅은 결국 레포지토리에 남아 ‘내가 유지보수하고 관리해야 할 코드’가 됩니다. 반면 코드 생성기의 산출물은 언제든 명령어로 다시 만들어낼 수 있는 ‘파생물’이므로 코드는 존재하되 개발자의 ‘유지보수 대상’에서는 제외됩니다.
일정이 빡빡하고 스펙이 매주 바뀌는 프로젝트일수록 자동화의 가치는 극대화됩니다. 스펙이 바뀔 때마다 타입과 API 클라이언트를 고치다 보면 어딘가 누락이 생길 수 있는데, 코드젠은 명령어 한 줄로 스펙과 코드를 항상 일치시켜 이 리스크 자체를 없애줍니다. 변경이 잦을수록 이 한 줄이 아껴주는 시간과 사고 비용은 커집니다.
multipart/form-data나 바이너리 업로드처럼 번거로운 요청도 스펙만 잘 정의되어 있다면 생성기가 알아서 코드를 짜줍니다. 단순하고 기계적인 배선 작업을 자동화가 가져가 주기 때문에, 개발자는 청크 분할이나 재시도 로직 같은 고차원적인 커스텀 비즈니스 로직에 집중할 여력이 생깁니다.
방법론을 소개하는 김에 이를 실제로 구현해 줄 도구도 함께 소개하려고 합니다. 현재 웹 프론트엔드 생태계에서 백엔드의 OpenAPI 스펙을 TypeScript 코드로 변환해 주는 두 가지 도구를 비교해 보겠습니다. 하나는 완제품 훅을 통째로 뽑아주는 검증된 원조 Orval이고, 다른 하나는 유연한 옵션 객체로 최신 생태계의 방향을 이끄는 Hey API입니다.
오랫동안 프론트엔드 개발자들의 사랑을 받아온 도구입니다. 스펙을 읽어 단순한 API 호출 함수뿐만 아니라 컴포넌트에서 바로 사용할 수 있는 완제품 형태의 훅 자체를 통째로 생성해 줍니다. 특히 MSW(Mock Service Worker)와 Faker.js 연동 기능이 내장되어 있어서, 백엔드 개발이 완전히 끝나지 않았어도 목(Mock) 데이터 통신 코드를 자동으로 만들어 즉시 프론트엔드 개발에 착수할 수 있도록 돕습니다.
최신 생태계의 패러다임 변화를 잘 보여주는 도구입니다. TanStack Query v5에 도입된 queryOptions() 아키텍처 이후, 프레임워크에 종속적인 훅을 통째로 만드는 것보다 유연한 옵션 객체를 생성하는 것이 대세가 되었습니다. Hey API는 처음부터 이 철학으로 설계되었습니다. Vercel의 CEO 기예르모 라우치(Guillermo Rauch)는 Hey API를 두고 “그냥 작동하는 OpenAPI 코드젠(OpenAPI codegen that just works)”이라고 평하기도 했습니다.
무거운 커스텀 훅 대신 깔끔한 옵션 객체 형태로 코드를 뽑아주기 때문에, 하나의 생성물로 SSR Prefetch, 캐시 제어, 다양한 프레임워크(React, Vue, Svelte 등) 대응까지 유연하게 커버할 수 있습니다. Vercel, PayPal, AWS 등 글로벌 기업들이 프로덕션에 채택하고 있습니다.

개인적으로, 장기적인 아키텍처 관점에서는 생태계의 방향성과 일치하는 Hey API를 추천합니다. 다만 아직 빠르게 발전 중인 도구이므로 공식 문서에서도 정확한 버전 고정(pin)을 권장한다는 점은 알아두는 것이 좋습니다.

결정론적인 일에서 AI를 제외해야 하는 이유는, AI를 정말 필요한 곳에 훨씬 더 안전하고 강력하게 투입하기 위해서입니다. 튼튼한 자동화 뼈대를 세우고, 그 위에 가변적인 AI를 얹는 식으로 역할을 분담하는 것입니다. 이렇게 역할을 나누면, 자동화와 AI가 하나의 파이프라인으로 연결되는 다음과 같은 자동화 시나리오가 가능해집니다.
시나리오 A: 비즈니스 로직 자동 수정
백엔드 필드명이 바뀌면 코드 생성기가 돌면서 타입이 갱신되고, 바뀐 필드를 쓰던 곳에서 컴파일 에러가 발생합니다. 이때 CI 파이프라인의 AI 에이전트가 타입 에러 목록을 감지해, 컴포넌트 내부의 데이터 매핑 코드까지 자동으로 수정(패치)합니다. 즉 스펙 변경 → 코드 재생성 → 비즈니스 로직 수정까지 사람 손을 거치지 않고 이어지는 것입니다. AI가 막연히 추측하는 것이 아니라 자동화 도구가 ‘어디가 고장 났는지’를 결정론적으로 짚어줬기 때문에, AI의 수정 성공률도 비약적으로 상승합니다.
시나리오 B: UI 페이지 자동 생성
새로운 API 엔드포인트가 추가되면 코드 생성기가 타입과 API 연동 코드를 작성합니다. 여기서 멈추지 않고, CI 파이프라인에 “새 엔드포인트의 연동 코드가 생성되면 이 데이터 규격에 맞는 UI를 만들어달라”는 프롬프트를 미리 정의해두면, 코드 생성을 트리거로 CI 상에서 AI가 자동으로 실행되어 화면 초안까지 만들어냅니다. 개발자가 그때그때 프롬프트를 입력하는 것이 아니라, 엔드포인트 추가 → 연동 코드 생성 → UI 초안 생성까지 사람의 개입 없이 하나의 파이프라인으로 이어지는 완전 자동화입니다. 이때 AI에 주입되는 데이터의 형태(Schema)는 코드 생성기가 이미 100% 확정해둔 상태이므로, AI가 그려내는 UI가 실제 응답과 어긋날 확률도 줄어듭니다.
이처럼 자동화가 결정론적인 토대와 명확한 제약 조건(타입)을 깔아주면, AI는 그 제약 안에서 판단이 필요한 일만 수행합니다. AI의 최대 약점인 ‘비결정성(불확실성)’이 자동화의 ‘결정성(확실성)’으로 상쇄되는 시너지가 일어나는 것입니다.
실제로 앤트로픽(Anthropic)도 에이전트 설계 가이드 ‘Building Effective Agents’에서 같은 원칙을 권장합니다. 가능한 일은 미리 정의된 코드 경로(predefined code paths)로 실행하고, 여기에 프로그래밍 방식의 검증을 결합하라는 것입니다. 결정론적 토대 위에 AI를 얹는 이 역할 분담은, 에이전트 시대 전반이 수렴하고 있는 설계 원칙인 셈입니다.
이 글에서는 AI 워크플로우를 만들어나가는 여러 관점 중 하나로, 규칙 기반 자동화의 영역과 AI 본연의 역량이 필요한 영역을 구분 짓고 그 위에 워크플로우를 설계하는 접근을 제시해보았습니다. “얼마나 많은 일을 AI에 위임하느냐”보다, 그 경계를 명확히 이해하고 확정하는 것이 더 나은 출발점이 될 수 있다는 것입니다.
정형화된 원천 데이터가 존재하고, 도출되어야 할 결과물이 이미 결정되어 있으며, 기계적인 검증이 가능한 작업이라면 규칙 기반(Rule-based)의 자동화 시스템에 맡기세요. 그리고 맥락을 읽고 판단해야 하는 고차원적인 일에 AI를 투입하세요. 누구나 같은 모델을 빌려 쓸 수 있는 시대에, 엔지니어링의 진짜 경쟁력은 모델 자체가 아니라 이를 안전하게 감싸는 ‘결정론적 통제 계층’을 얼마나 촘촘히 구축하느냐에 달려 있습니다. 이 경계가 분명할수록 파이프라인은 견고해지며, AI 역시 자신의 영역 안에서 더 효율적으로 일할 수 있습니다.
습관적으로 AI 프롬프트 창에 복사-붙여넣기 하던 작업이 있나요? ‘결정론적 영역’에 속하는 업무는 없는지 한번 점검해보세요. 만약 있다면 전용 자동화 파이프라인 구축을 고려해볼 만합니다. 이 작은 경계의 구분이 여러분의 AI 워크플로우를 한층 더 효율적이고 강력하게 발전시켜 줄 것입니다.
ⓒ요즘IT의 모든 콘텐츠는 저작권법의 보호를 받는 바, 무단 전재와 복사, 배포 등을 금합니다.