명세 기반 개발 (Spec-Driven Development): Zero에서 Kiro까지
요약
AI 코딩 어시스턴트 사용 시 발생하는 '코드 우선(Code-First)' 방식의 문제점을 지적하며, Kiro를 활용한 명세 기반 개발(Spec-Driven Development) 방법론을 소개합니다. 명확한 요구사항과 설계를 먼저 정의함으로써 개발 시간과 버그를 획기적으로 줄이는 전략을 다룹니다.
핵심 포인트
- AI 코딩 도구 사용 시 '생각하기' 단계를 생략하면 잘못된 코드가 빠르게 생성됨
- 명세 기반 개발은 무엇을, 어떻게, 어떤 단계로 만들지 먼저 정의하는 방식임
- Kiro 활용 시 개발 시간 70% 감소, 운영 버그 60% 감소 효과 기대
- 구현 전 요구사항, 설계, 작업 단계를 구조화하는 것이 핵심
명세 기반 개발 (Spec-Driven Development): Zero에서 Kiro까지
Kiro는 행동하기 전의 사고 과정을 다시 살려냈습니다
저자: Luca D'Addeo - AWS Champion Authorized Instructor
대상: 개발자 (Developer), 솔루션 아키텍트 (Solutions Architect), 기술 리드 (Technical Lead)
읽기 시간: 15분
난이도: 중급
🎯 TL;DR (Too Long; Didn't Read)
문제점:
현대의 AI 코딩 어시스턴트 (Copilot, Cursor)는 코드를 빠르게 작성하게 해주지만, 가장 중요한 단계인 생각하기(thinking) 단계를 건너뛰게 만듭니다.
해결책:
Kiro를 활용한 명세 기반 개발 (Spec-Driven Development)은 구축을 시작하기 전에 무엇을 달성하고 싶은지를 정의하도록 강제하며, 더 적은 시간 안에 더 나은 소프트웨어를 생산하게 합니다.
수치:
- 개발 시간: -70%
- 운영 환경 버그 (Bug in production): -60%
- 필요한 리팩터링 (Refactoring): -80%
- 코드 명확성: +90%
📖 목차
- "코드 우선 (Code First)"의 문제점
- 명세 (Spec)란 무엇인가
- 명세 기반 (Spec-Driven) 철학
- Kiro에서의 작동 방식
- 완벽한 명세의 해부학
- 실제 사례: 10분 만에 만드는 REST API
- 명세 기반 (Spec-Driven) vs 코드 우선 (Code-First): 비교
- 베스트 프랙티스 (Best Practices)
- 명세 기반 (Spec-Driven)을 사용하지 말아야 할 때
- 결론
1. "코드 우선 (Code First)"의 문제점
전형적인 시나리오
다음과 같은 요청을 받았습니다:
"사용자 주문을 처리하기 위한 API 엔드포인트 (endpoint)를 추가해야 합니다"
Cursor/Copilot을 사용한 전통적인 접근 방식:
# 작성을 시작합니다...
@app.route('/orders', methods=['POST'])
def create_order():
...
무슨 일이 일어나고 있는 걸까요?
당신은 근본적인 질문에 답하지 않은 채 코드를 작성하기 시작했습니다:
- ❌ 입력 데이터에 어떤 유효성 검사 (validation)가 필요한가?
- ❌ 중복 주문은 어떻게 처리하는가?
- ❌ 결제가 실패하면 어떻게 하는가?
- ❌ 인증 (authentication)이 필요한가? 인가 (authorization)가 필요한가?
- ❌ 분석 (analytics)을 위해 주문을 어떻게 추적하는가?
- ❌ 응답 형식은 무엇인가?
- ❌ 어떤 에러가 발생할 수 있는가?
- ❌ 이 엔드포인트를 어떻게 테스트하는가?
결과: 코드는 빠르게 작성하지만, 그것은 잘못된 코드입니다.
코드 우선 (Code-First)의 비용
실제 시나리오 (중규모 프로젝트):
초기 개발: 2일 ✓
...
핵심 질문
"AI가 코드를 10배 더 빠르게 작성하더라도, 잘못된 코드를 작성한다면 당신은 정말로 더 생산적인가요?"
답변: 아니요. 틀리는 속도만 더 빨라질 뿐입니다.
2. 명세 (Spec)란 무엇인가
정의
**명세 (Specification)**란 다음을 기술하는 구조화된 문서입니다:
- 무엇을 (WHAT) 만들 것인가 (요구사항, Requirements)
- 어떻게 (HOW) 만들 것인가 (설계, Design)
- 어떤 단계로 (STEPS) 구현할 것인가 (작업, Tasks)
단 한 줄의 코드를 작성하기 전에 말이죠.
명세의 세 가지 섹션
REQUIREMENTS (무엇을)
## Requirements
1. API는 POST /orders를 통해 주문을 수락해야 함
...
DESIGN (어떻게)
## Design
### Architecture
...
python
Order:
- id: UUID (primary key)
- user_id: UUID (foreign key)
- product_id: UUID (foreign key)
- quantity: Integer
- total_price: Decimal
- payment_method: Enum
- status: Enum ['pending', 'confirmed', 'failed']
- created_at: Timestamp
- updated_at: Timestamp
### API Flow
1. 요청 도착 → JWT 검증 (validation)
...
markdown
TASKS (단계)
## Tasks
1. 프로젝트 구조 설정 (Setup project structure)
...
3. 명세 기반 (Spec-Driven) 철학
세 가지 원칙
원칙 1: 구축하기 전에 생각하라
Code-First: 아이디어 → 코드 → 문제 발견 → 리팩터링 (Refactor)
Spec-Driven: 아이디어 → 명세 (Spec) → 문제 발견 → 명세 업데이트 → 올바른 코드
오류의 비용:
- 명세 (Spec) 단계에서 발견 시: 수정에 5분 소요
- 코드 (Code) 단계에서 발견 시: 리팩터링 (Refactor)에 2시간 소요
- 운영 (Production) 단계에서 발견 시: 핫픽스 (Hotfix) 및 롤백 (Rollback)에 2일 소요
원칙 2: 소통이 곧 구현이다
잘 작성된 명세는 다음과 같습니다:
- ✅ 팀과 공유 가능 (동기화된 정렬, sync alignment)
- ✅ 코드 작성 전 검토 가능 (설계 검토, design review)
- ✅ 자동 문서화 (self-documenting)
원칙 3: 경제적인 반복 (Iteration)
명세 변경: 5분 편집
코드 변경: 2시간 리팩토링 (refactoring) + 테스트 (testing)
운영 환경 (prod) 변경: 2일 + 다운타임 (downtime) + 평판 손실 (reputation loss)
황금률 (Golden Rule):
코드에서 실패하지 말고, 종이 위에서 빠르게 실패하라.
오늘날 이것이 의미 있는 이유 (10년 전과는 다름)
2014년 - 명세 (Spec)는 오버헤드 (overhead)로 간주됨:
- 명세를 작성하는 데 며칠이 소요됨
- 어차피 코드는 직접 작성해야 함
- 명세는 즉시 구식이 됨
2026년 - AI 에이전트 (AI agents)와 함께, 명세는 자산 (asset)임:
- ✅ 10분 만에 명세 작성 (AI 보조 (AI assisted))
- ✅ AI가 명세로부터 코드를 생성 (자동화)
- ✅ 명세가 동기화된 상태로 유지됨 (단일 진실 공급원 (source of truth))
차이점:
이전의 명세는 _문서화 (documentation)_였습니다.
오늘날의 명세는 _실행 가능한 지침 (executable instructions)_입니다.
4. Kiro에서의 작동 방식
Kiro 워크플로 (Workflow)
1. 당신이 프롬프트 (prompt) 작성:
"[기능 설명]을 구축하는 명세를 생성하라"
...
실전 예시: 프롬프트에서 코드까지
입력 (INPUT):
API 성능을 향상시키기 위해 Redis 캐시 레이어 (cache layer)를 추가하는 명세를 생성하라:
- GET /users/:id 응답을 캐싱할 것
- TTL: 5분
...
KIRO 출력 (요구사항 (Requirements)):
## 요구사항 (Requirements)
1. 캐싱 전략 (Caching Strategy)
...
KIRO 출력 (설계 (Design)):
## 설계 (Design)
### 아키텍처 (Architecture)
[ASCII diagram]
Client → API → Cache Check → Redis (hit) → Return
↓
(miss) → Database → Update Cache → Return
### 구현 (Implementation)
- Redis 클라이언트 (client): redis-py
...
KIRO 출력 (작업 (Tasks)):
## 작업 (Tasks)
1. Redis 연결 설정
...
Kiro는 이후 작업을 실행(EXECUTE)하고 완전한 코드를 생성합니다.
5. 완벽한 명세의 해부학
템플릿: 명세 체크리스트 (Spec Checklist)
# [기능 이름] - 명세서 (Specification)
## 1. 요구사항 (Requirements)
...
좋은 명세의 특징
✅ SMART 요구사항 (Requirements)
- Specific (구체적): "빠를 것"이 아니라 "지연 시간 (Latency) < 200ms"
- Measurable (측정 가능): 정량화 가능한 지표 (metrics)
- Achievable (달성 가능): 가용 리소스로 실현 가능한 수준
- Relevant (관련성): 비즈니스 목표와 일치함
- Time-bound (기한 제한): 명확한 마감 기한
✅ 완전하면서도 유연한 설계 (Design Completo ma Flessibile)
- 문서화된 아키텍처 결정 사항 (Architectural decisions)
- 고려되었으나 합리적인 이유로 제외된 대안들
- 구현 단계에서의 조정을 위한 여지
✅ 원자적 작업 (Tasks Atomici)
- 각 작업은 2시간 이내에 완료 가능해야 함
- 명시적인 의존성 (Dependencies)
- 검증 가능한 체크포인트 (Checkpoints)
피해야 할 안티 패턴 (Anti-Pattern)
❌ 너무 일반적인 명세 (Spec troppo generica)
# Bad
요구사항 (Requirements):
- API가 잘 작동해야 함
...
✅ 구체적인 명세 (Spec specifica)
# Good
요구사항 (Requirements):
- API 응답 시간: p95 < 200ms, p99 < 500ms
...
❌ 결정이 없는 설계 (Design senza decisioni)
# Bad
설계 (Design):
- 데이터베이스를 사용할 것임
...
✅ 근거가 있는 설계 (Design con rationale)
# Good
설계 (Design):
- 데이터베이스: PostgreSQL
...
6. 실제 사례: 10분 만에 만드는 REST API
시나리오
고객: "요리 레시피를 관리할 API가 필요합니다"
1단계: Kiro에게 프롬프트 입력 (2분)
create a spec that builds a Recipe Management API with:
- CRUD operations for recipes
- Each recipe has: title, ingredients (list), steps (list), prep_time, cook_time, servings
...
2단계: Kiro가 명세 생성 (3분)
Kiro가 다음을 생성합니다:
- 15개의 상세 요구사항 (Requirements)
- FastAPI + PostgreSQL + JWT 인증을 포함한 설계 (Design)
- 12개의 구현 작업 (Tasks)
3단계: 검토 및 조정 (2분)
누락된 사항을 발견합니다:
"rate limiting 추가: 사용자당 분당 100회 요청"
Kiro가 명세를 업데이트합니다.
4단계: Kiro가 구현 (3분)
Task 1/12: 프로젝트 구조 설정 ✓
Task 2/12: 데이터 모델 생성 ✓
Task 3/12: CRUD 엔드포인트 구현 ✓
...
5단계: 검증 (보너스)
# 테스트 자동 실행
pytest
# 47개 테스트 통과
...
10분 만에 작동하는 API 완성.
결과
생성된 코드:
- 12개의 Python 파일
- 850줄 이상의 코드
- 47개의 단위 테스트 (Unit tests) + 통합 테스트 (Integration tests)
- 완전한 Swagger UI
- 예제가 포함된 README
수동 작업 시 (추정):
- 소요 시간: 6-8시간
- 예상 버그: 5-8개
- 테스트 커버리지 (Test coverage): ~60%
- 문서화 (Documentation): 최소 수준
Kiro + 명세 사용 시:
- 소요 시간 (Tempo): 10분
- 버그 (Bug): 0 (자동 테스트 완료)
- 테스트 커버리지 (Test coverage): 85%
- 문서화 (Documentation): 완전함
7. 명세 기반 (Spec-Driven) vs 코드 우선 (Code-First): 비교
비교 표
| 측면 (Aspetto) | 코드 우선 (Code-First) (Cursor/Copilot) | 명세 기반 (Spec-Driven) (Kiro) |
|---|---|---|
| 초기 소요 시간 | 빠름 (즉시 시작 가능) | 느림 (명세를 작성해야 함) |
| ... | ... | ... |
실제 지표 (AWS Certification Coach 프로젝트)
시나리오: 200개 이상의 자격증 퀴즈 처리 파이프라인
코드 우선 (Code-First) 접근 방식 (추정):
정신적 계획 (Planning mentale): 30분
코딩 (Coding): 4시간
엣지 케이스 디버깅 (Debug edge cases): 2시간
...
Kiro를 사용한 명세 기반 (Spec-Driven) 접근 방식 (실제):
명세 작성 (Scrivere spec): 15분
명세 검토 (Review spec): 10분
Kiro 구현 (Kiro implementation): 25분
...
절감 시간: 8.5시간 (89%)
학습 곡선 (Curva di Apprendimento)
Code-First:
└─ 평탄한 곡선 (즉시 시작하지만, 나중에 문제 발생)
...
8. 베스트 프랙티스 (Best Practices)
효과적인 명세를 작성하기 위한 방법
1. 도메인 언어 (Linguaggio del Dominio)를 사용하세요
❌ 나쁜 예 (Bad):
요구사항 (Requirements):
- 입력을 받아 프로세싱을 수행하는 함수
✅ 좋은 예 (Good):
요구사항 (Requirements):
- 다음을 수행하는 주문 검증 서비스 (Order validation service):
* OrderRequest (user_id, items, payment_method)를 수신함
...
2. 모든 것을 수치화하세요 (Quantifica Tutto)
❌ 나쁜 예 (Bad):
- API는 빨라야 한다
- 코드는 안전해야 한다
✅ 좋은 예 (Good):
- API 응답 시간 (API response time): p95 < 200ms, p99 < 500ms
- 보안 (Security):
* JWT 인증 (HS256)
...
3. 결정 사항을 문서화하세요 (Documenta le Decisioni)
모든 중요한 선택에는 다음 내용이 포함되어야 합니다:
- 내려진 결정 (Decisione presa)
- 고려된 대안 (Alternatives considerate)
- 근거 (Rationale) (왜 다른 것이 아닌 이것인지)
## 디자인 결정 (Design Decision): 데이터베이스 선택
**결정 (Decision):** PostgreSQL
...
4. 명세는 반복적입니다 (Spec è Iterativa)
한 번에 완벽한 명세를 작성할 것이라고 기대하지 마세요.
반복적 워크플로 (Workflow iterativo):
1. 초기 초안 (Draft iniziale) (80% 완성)
2. Kiro와 검토: "내가 놓치고 있는 엣지 케이스는 무엇인가?"
3. Kiro가 개선 사항을 제안함
...
5. 구체적인 예시를 사용하세요 (Usa Esempi Concreti)
❌ 나쁜 예 (Bad):
- 이메일별 입력 유효성 검사 (Input validation per email)
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기