스펙 기반 개발(Spec-Driven Development; SDD)이란?
스펙 기반 개발은, 요구사항·제약 조건·불변의 규칙을 담은, 버전 관리가 되는 명세서(Specification)를 유일한 진실의 원천(Source of Truth)으로 삼고, 그 기준으로 코드를 생성·검증하는 AI 지원 개발 방식입니다. 바이브 코딩의 프롬프트 → 코드 → 패치 사이클 대신 명세 → 설계 → 작업 계획 → 구현 → 검증이라는 흐름으로 개발이 진행됩니다. 목표는 더 안전한 자율 코딩, 더 적은 재작업, 실제 코드베이스에서도 예측 가능한 결과물입니다.
오늘은 아래와 같은 내용을 여러분과 나누려고 합니다:
‘바이브 코딩’, 규모가 커지면 왜 문제가 급속하게 커지는가: 지속적인 계획의 부재, 비결정론적 결과물, 그리고 아키텍처의 취약성
AWS Kiro 스타일의 스펙 기반 워크플로우를 활용하면, 어떻게 요구사항을 구조화하고 검증을 지속적으로 해서 전체적인 신뢰성을 높일 수 있는가
실전적인 관점에서, 개발팀이 경량 스펙, 형식 검증, AI + 기호 검증이라는 하이브리드 옵션 중 언제 어떤 것을 쓸 것인지
오늘 글의 핵심 내용을 작성하는데 AWS의 VP이자 Agentic AI 담당 Distinguished Engineer인 Marc Brooker의 도움을 받았습니다. 감사드립니다.
들어가며
AI 기술이 ‘소프트웨어 개발’ 영역에 본격적으로 활용되기 시작하면서, 한 가지 중요한 질문을 피하기 어려워졌죠 - 이게 정말 안전한 걸까? 하는 질문이 바로 그겁니다.
‘바이브 코딩’가 프로그래밍의 세계에 편의성과 속도, 그리고 재미를 가져다 줬다는 것은 뭐 너무나 분명합니다. 개발의 문턱을 엄청나게 낮춘 것도 사실이구요. 그런데 동시에, 품질이 별로 좋지 않고 구조도 없는 코드—흔히 서구권에서는 ‘AI 코딩 슬롭(AI coding slop)’이라 불리는—도 엄청나게 쏟아졌죠.
그렇다고 바이브 코딩을 완전히 포기하는 건 너무 성급한, 그리고 현명하지 못한 선택일 겁니다. 그렇다면, ‘바이브 코딩’을 좀 더 안전하게, 그리고 효과적으로 할 수 있는 방법은 없을까요? AI가 만들어낸 코드가, 프롬프트마냥 흔들리지 않을 진실의 원천(Source of Truth; 기준)을 어떻게 찾을 수 있을까요?
바로 여기에서, 스펙 기반 개발(Spec-Driven Development, SDD)이 등장합니다.
SSD의 아이디어는 간단합니다. 유저 스토리, 요구사항, 시스템 동작 방식, 제약 조건, 인수 기준, 기능—이 모든 것을 명세서(Specification)라는 한 곳에 담고, 코딩 프로세스를 거기서부터 시작하는 것이죠. 명세서는 명확한 목표가 설정된 규칙의 토대가 됩니다. 코딩 에이전트가 프롬프트의 바다에서 길을 잃지 않도록 하는 지도 역할을 한다고나 할까요?
그럼, 오늘은 SDD가 왜 바이브 코딩 대비 좀 더 신뢰할 수 있는 대안인지 알아보고, 지금 당장 쓸 수 있는 몇 가지 주요 SDD 도구들을 살펴보겠습니다.
오늘 다룰 내용은 다음과 같습니다:
코딩의 짧은 역사
지난 수십 년간, 프로그래밍이라는 작업은 컴퓨터에게 어떻게 할지를 일일이 하나하나 알려주는 일이었습니다. C나 포트란 같은 초기 언어들은 특히 완전히 절차적이었구요. 반복문, 메모리, 제어 흐름—모든 단계를 개발자가 직접 손으로 써야 했습니다.
그러다 1970년대에 SQL이 완전히 다른 아이디어를 들고 나타났습니다. 절차를 묘사하는 대신 원하는 결과를 묘사하는 것이었거든요.
SELECT name FROM users WHERE country = 'KR'
인덱스를 어떻게 쓸지, 조인을 어떻게 처리할지 등을 직접 지정할 필요가 없었습니다. 데이터베이스가 알아서 실행 방법을 찾아냈으니까요. 어떤 면에서 보면, SQL이야말로 ‘스펙 기반 프로그래밍의 첫 번째 주류 사례’라고 해도 될지 모르겠네요. 원하는 것의 명세를 제공하면, 시스템이 실행을 담당하는 것 그 자체였으니까요.
2000년대에 업계는 이 아이디어를 한 단계 더 밀어붙이려고 했고, 그게 바로 모델 주도 개발(MDD, Model-Driven Development)이었습니다. 엔지니어들이 UML 다이어그램이나 도메인 모델 같은 형식 모델로 시스템을 설계하면, 도구가 코드를 자동으로 만들어내는 방식이었죠 - 아 정말 기억이 새록새록 떠오르네요.
모델이 핵심 산출물의 자리를 차지하고, 코드는 그 부산물에 불과한 세상—이론상 완벽했습니다. 하지만 현실에서 이 MDD를 위한 도구들은 너무 경직되어 있었고, 개발자들은 이 도구들이 만들어낸 코드와 씨름하는 데 더 많은 시간을 쏟았던 게 현실이었습니다.
또 다른 갈래로는 행동 주도 개발(BDD)이 있었습니다. 비즈니스 관점에서 사용자의 행동에 집중하고 시스템이 제대로 된, 올바른 일을 하고 있는지 확인하는 방식인데요.
그리고 지금 이 시대, 생성형 AI가 새로운 코딩의 시대를 열었습니다. 코딩 어시스턴트와 자율 에이전트 덕분에 예전에 프로그래머들이 꿈만 꾸던 일들이 현실이 됐죠. 자연어를 그대로 작동하는 코드로 변환하고, 대규모의 코드베이스를 수정하고, 테스트 스크립트를 손쉽게 생성하고, 시스템을 리팩터링하는 것들 모두가 AI의 일이 되었습니다.
바이브 코딩은 AI 코딩 어시스턴트 활용의 정점이죠. 프롬프트를 하나씩 보내면서 진행하는 방식이 주된 형태고, 구체적인 흐름은 이렇습니다: 개발자가 프롬프트 작성 → AI가 코드 생성 → 개발자가 더 많은 프롬프트로 수정하고 버그를 잡음 → 반복. 놀라우리만큼 잘 작동하고, 코딩 과정을 단순하게 만들어 줘서, 훨씬 더 많은 사람들이 개발에 접근할 수 있게 해줬습니다.
그런데 동시에, 바이브 코딩은 굉장히 취약하기도 합니다:
지속하는 전체적 계획이 없습니다. 매번 새 프롬프트로 시작하는 건 매번 지도 없이 길을 떠나는 것과 비슷하죠.
결과물이 비결정론적입니다. 같은 프롬프트도 매번 다른 코드를 만들어 내거든요.
요구사항이 채팅 히스토리 속에 묻혀버립니다. 3주 전에 "왜 이렇게 짰지?"를 기억하기 위해서 스크롤업을 하거나 검색을 해 본 경험이 있다면 이해하실 겁니다.
모든 변경사항이 이전의 결정내용을 덮어써 버립니다. 에이전트는 과거를 모르거든요.
아키텍처가 서서히 무너집니다. 처음에는 괜찮아 보이지만, 나중에는 아무도 전체 그림을 설명할 수 없게 됩니다.
에이전트가 대규모의 작업을 안전하게 처리하기 쉽지 않습니다. 자율성이 높아질수록 실수의 경계도 거대해질 수 밖에요.
왜 그럴까요? 바로, 바이브 코딩에는 구조가 없기 때문입니다. 규칙과 제약의 토대, 검증 시스템, '제대로 하는 것'이 무엇인지 정의하고 반복해 가는 그 과정 중에 에이전트가 길을 잃지 않도록 잡아주는 나침반 같은 것이 없습니다.
그리고, 스펙 기반 개발이 바로 이 문제를 해결하려는 시도이구요.
스펙 기반 개발(SDD)이란 무엇인가?
스펙 기반 개발은, ‘AI가 지원해주는 소프트웨어 개발’의 흐름에 형식적 구조, 확장성, 그리고 검증 가능한 정확성을 다시 도입하려는 시도라고 설명할 수 있겠습니다. MDD와 BDD, 그리고 바이브 코딩의 중간 어딘가에 놓으면 될 것 같아요.
"스펙 기반 개발은, 코딩 에이전트라는 변화가 훨씬 더 문제를 줄이면서도 앞으로 전진하고 발전하기 쉽게 만들어 주는 방법론입니다. 에이전트에게 소프트웨어를 ‘지속적으로’ 만들어나갈 수 있는 ‘맥락’을 제공하죠."
SDD에서는, 규칙과 제약이 훨씬 명시적입니다. 그리고 이 SDD의 핵심 기반이 바로 ‘명세서(Specification)입니다.
명세서(Specification): 프로그램을 묘사하는 새로운(?) 방법
SDD 방법론에서, 모든 것은 명세서에서 시작되고, 명세서가 중심을 잡는 객체가 됩니다. 코딩 에이전트의 나침반 이야기 연장선상에서, 명세서는 기계가 읽을 수 있는 북극성(North Star)같은 거라고 비유할께요. 생성된 코드에 지속적인 전역 목표를 부여하는 역할을 합니다.
좀 더 구체적으로 들여다보면, 명세서는 아래와 같은 내용을 구조화해서 담은 문서입니다:
시스템 컴포넌트가 무엇을 해야 하는지
어떤 제약 조건과 속성을 만족해야 하는지
시스템이 어떻게 동작해야 하는지
어떤 유저 스토리를 충족하는지
비기능적 요구사항이 무엇인지
Marc Brooker는 SDD에서 크게 보면 명세서가 두 번 쓰인다고 강조했습니다:
소프트웨어를 만들고, 유지보수하고, 기능을 추가할 때.
그 소프트웨어를 둘러싼 테스트 인프라를 구축할 때.
명세서는 소프트웨어가 무엇을 해야 하는지를 정의하고, UI·단위·통합 테스트를 비롯한 다양한 테스트, 형식 검증 등 ’실제로 작동하는’ 소프트웨어를 만드는 데 필요한 것들을 구축하는 기준이 됩니다.
자, 실제로 어떻게 생겼는지 궁금하시죠? 거창할 것도 없고, 가장 간단한 형태로는 이런 식입니다:
# 명세서: 사용자 인증 모듈
## 기능 요구사항
- 이메일/비밀번호 기반 회원가입 및 로그인
- 소셜 로그인 (Google, Kakao)
- 비밀번호 찾기 (이메일 인증)
## 제약 조건
- 비밀번호는 bcrypt로 해싱 (rounds: 12)
- JWT 토큰 만료: 액세스 1시간, 리프레시 7일
- 로그인 5회 실패 시 15분 잠금
## 검증 기준 (완료 조건)
- [ ] 모든 엔드포인트 단위 테스트 통과
- [ ] SQL 인젝션 취약점 없음
- [ ] 응답 시간 200ms 이하
이 명세서를 에이전트에게 주면, 에이전트는 "무엇을 만들어야 하는가"와 "올바르게 만들었는지 어떻게 아는가"를 동시에 알게 되는 겁니다. 채팅창의 프롬프트가 아니라, 검토하고 수정하고 버전 관리도 할 수 있는 문서가 기준이 되는 거죠.
스펙 기반 개발은 바이브 코딩보다 훨씬 반복적인 프로세스입니다. 내부 루프(Inner Loop)와 외부 루프(Outer Loop)로 생각하면 이해하기 쉬울까 싶은데, 내부 루프는 현재 명세서에 맞는 소프트웨어를 만드는 목표 지향적인 실행 과정이고, 외부 루프는 그 소프트웨어가 실제 세계를 만나는 과정입니다.
내부 루프는 에이전트가 완전 자율로 실행할 수 있는 단계들로 구성됩니다:
명세 작성 또는 업데이트
LLM과 도구를 통해서 명세에서 코드 생성
명세에서 테스트 생성
테스트에 맞춰 코드 실행
테스트 실패 시 통과할 때까지 반복
테스트가 원래 명세와 일치하는지 검증
외부 루프는, 소프트웨어를 사용자, 팀, 고객 앞에 내보이고, 새로운 기능과 변경·수정에 대한 피드백을 수집하고, 명세를 업데이트하고, 내부 루프를 다시 실행해서 변경 사항을 구현합니다. 소프트웨어와 명세를 실제 세계에 맞게 계속 발전시켜 나가는 순환인 거죠. 그리고 무엇보다 중요한 것은, 정확성이 지속적으로 강제된다는 점이구요.
여기서 핵심은, 명세서라는 것이 개발이 시작되고 나면 서랍 속으로 들어가야 하는 ‘기획 문서’가 아니라는 겁니다. Git 같은 버전 관리 시스템 안에서 코드와 동시에 함께 살아 숨쉬고, 소프트웨어 개발의 전체 사이클에 직접 연결되는, 개발 프로세스 안에서 살아 숨쉬는 무언가입니다.
엔지니어들이 멱등성(Idempotence), 단조성(Monotonicity), 교환법칙(Commutativity), 상태 일관성 같은 불변 조건들을 정의하면, AI 시스템이 대용량 입력 공간을 자동으로 생성해서 그 속성들을 스트레스 테스트합니다. 검증은 CI/CD 파이프라인의 일부가 됩니다. AI 에이전트가 명세를 읽고 업데이트하고, 명세에서 작업을 계획하고, 변경 사항을 명세에 맞게 검증합니다. 오류는 즉시 잡히고, 검증된 변경 내용만이 지속해서 유지됩니다.
명세서를 통해서, 자율 에이전트는 비로소 정확한 목표를 향해 올바르게 나아가는 방법의 지도를 얻게 됩니다. 명세서가 1차 산출물이 되고, 코드는 파생 산출물이 되는 셈이예요.


