코드 우선, 명세는 나중에: AI 주도 개발을 위한 실무 가이드
요약
AI 에이전트 시대에 코드와 명세 사이의 불일치 문제를 해결하기 위한 실무 가이드를 제시합니다. 명세 주도 개발(SDD)과 코드 우선 명세 사후 보완 개발을 결합하여 코드와 명세를 지속적으로 정렬하는 방법을 제안합니다.
핵심 포인트
- AI 주도 개발 시 코드와 명세의 불일치로 인한 블랙박스화 문제 경고
- 명세 주도 개발(SDD)을 통한 AI 구현 가이드 방식 소개
- 코드 변경 후 명세를 업데이트하는 사후 보완 개발 방식 제안
- 코드와 명세를 단일 진실 공급원(Source of Truth)으로 유지하는 전략
1. 서론
Claude Code나 GitHub Copilot과 같은 AI 에이전트가 일상화된 시대에, 개발 환경은 극적인 변화를 겪었습니다. 일단 명령을 내리면 코드가 막힘없이 흘러나옵니다. 하지만 한 가지 남아있는 문제점이 있지 않나요? 무엇을 만들고 싶은지 AI에게—말로든 채팅으로든—반복해서 설명하고 있는 자신을 발견하곤 하지 않나요?
이는 운전자(AI)에게 최종 목적지를 알려주지 않은 채 운전 방향만 지시하는 것과 비슷합니다. 얻어낸 코드가 당장은 작동할지 모르지만, 시간이 흐른 뒤에는 필연적으로 다음과 같은 의문이 들게 됩니다: "왜 구현이 이런 구조로 되어 있지?" 그리고 "원래 명세(Specification)가 뭐였더라?" 코드와 명세가 점차 어긋나면서, 많은 팀이 프로젝트 규모와 상관없이 이 문제에 직면합니다.
실제로 다음과 같은 상황은 흔히 발생합니다:
- "애초에 명세가 존재하지 않음"
- "명세는 있지만, 오래되어 더 이상 현재 상태를 반영하지 못함"
- "더 이상 전체적인 그림을 파악할 수 있는 사람이 없음; 블랙박스가 되어버려 무엇이 어떻게 작동하는지 알 수 없음"
명세는 흔히 "한 번 쓰고 잊혀지는" 문서가 되기 쉽습니다. 구현이 진행됨에 따라 코드와 명세 사이의 불일치가 쌓이고, 결국 팀은 "코드가 곧 명세인" 상태에 놓이게 됩니다.
이 글에서 저는 결합된 접근 방식을 소개하고자 합니다: 먼저 명세를 작성하고 이를 사용하여 AI 구현을 가이드하는 명세 주도 개발 (Spec-Driven Development), 그리고 코드 변경을 먼저 구현한 뒤 명세를 그에 맞게 업데이트하는 **코드 우선 명세 백필 개발 (Code-First Spec-Backfill Development)**을 결합하는 방식입니다. 이 두 접근 방식을 함께 사용하면 코드와 명세 모두를 단일하고 지속적으로 정렬된 단일 진실 공급원 (Source of Truth)으로서 최신 상태로 유지할 수 있습니다.
참고: "Code-First Spec-Backfill Development"는 이 글을 위해 제가 만든 용어입니다. 만약 다른 이름으로 이미 존재하는 유사한 방법론이 있다면, 댓글로 알려주시면 감사하겠습니다!
이 글은 다음과 같은 독자들을 대상으로 합니다:
- Claude Code 또는 GitHub Copilot을 매일 개발에 사용하는 분
- 명세(Spec)가 준비되기 전에 코드가 먼저 작성되는 상황을 자주 겪는 분
- 명세 작성이 지루하게 느껴지고 우선순위에서 밀리는 경향이 있는 분
- "명세를 업데이트한 지 한참 된 것 같은데..."라고 생각해 본 적이 있는 분
- 명세가 아예 존재하지 않거나 도저히 손쓸 수 없을 정도로 최신 상태가 아닌 분
- 코드와 명세가 단절되어 시스템이 블랙박스(Black box)가 되어버린 분
- 코드와 명세 사이의 추적성(Traceability)을 확립하고 싶은 분
- 개발이 처음이라 명세를 어떻게 작성해야 할지조차 막막한 분
2. 두 가지 접근 방식: 명세 주도 개발(Spec-Driven Development) vs. 코드 우선 명세 사후 보완 개발(Code-First Spec-Backfill Development)
AI에게 느슨한 요구사항을 전달하고 직관에 따라 코드를 작성하게 하는 "바이브 코딩(Vibe Coding)"에 대해 들어보셨을 것입니다. 이 방식은 빠른 프로토타이핑(Rapid prototyping)에는 뛰어나지만, 대규모 애플리케이션에는 어려움이 있습니다. 이 글은 그 반대의 입장을 취합니다. 즉, 명세(Specification)라는 토대 위에서 AI 개발을 수행하는 것입니다. 하지만 이 접근 방식에는 실제로 두 가지 뚜렷한 방향이 있습니다.
2.1. 명세 주도 개발(Spec-Driven Development): 명세가 코드를 가이드함
첫 번째는 **명세 주도 개발(Spec-Driven Development, SDD)**입니다. 이는 사전에 상세한 명세(요구사항, 설계, 세부 명세, 구현 계획)를 준비한 다음, 이를 사용하여 AI 에이전트(AI agents)를 구동하는 워크플로(Workflow)입니다.
논리는 간단합니다:
상세한 명세를 미리 준비함으로써, AI의 동작을 정밀하게 제어할 수 있습니다.
바이브 코딩(Vibe Coding)이 "AI가 알아서 하게" 두는 방식이라면, 명세 주도 개발은 "설계 문서로 AI를 가이드하는" 방식입니다. 이 접근 방식은 기존 코드베이스가 없는 상태에서 앱을 처음부터 구축할 때 가장 강력한 힘을 발휘합니다.
2.2. 코드 우선 명세 사후 보완 개발(Code-First Spec-Backfill Development): 코드가 명세를 업데이트함
반면, 실제 개발 환경에서 모든 작은 변경 사항에 대해 "명세를 먼저 업데이트한 후 구현한다"는 원칙을 엄격히 따르는 것은 불필요하게 제약이 많다고 느껴질 수 있습니다. 사소한 수정의 경우, 코드를 직접 수정하여 작동을 확인한 뒤 나중에 명세를 업데이트하는 방식, 즉 역방향 워크플로(Workflow)가 더 실용적인 경우가 많습니다.
이것이 바로 이 글의 두 번째 축인 **코드 우선 명세 사후 보충 개발 (Code-First Spec-Backfill Development, CFSD)**입니다. 핵심 아이디어는 명세 주도 개발 (Spec-Driven Development)과는 반대로 "코드 → 명세" 순서로 작업하되, 궁극적으로 코드와 명세가 일치하도록 보장하는 것입니다.
참고: "Code-First Spec-Backfill Development"는 이 글을 위해 제가 만든 용어입니다. 만약 다른 이름으로 이미 존재하는 유사한 방법론이 있다면, 댓글로 알려주시면 감사하겠습니다!
2.3. 프로젝트 단계에 따른 두 가지 접근 방식의 활용
이 두 방식은 서로 모순되는 것이 아닙니다. 오히려 프로젝트의 상황과 단계에 따라 어떤 방식을 사용할지 선택해야 합니다:
- 앱을 처음부터 구축하는 경우 → 명세 주도 개발 (Spec-Driven Development) (명세 → 코드)
- 기존 앱을 작업 중이지만 명세가 부족하거나, 불완전하거나, 오래된 경우 → 먼저 코드를 분석하고 명세 파일 (spec.yaml)을 생성합니다 (코드 → 명세)
- 기존 앱을 점진적으로 개선하고 발전시키는 경우 → 코드 우선 명세 사후 보충 개발 (Code-First Spec-Backfill Development) (코드 → 명세)
명세가 없거나 구현 내용과 일치하지 않는 기존 애플리케이션의 경우, 우선 AI가 현재 코드를 분석하여 시작점으로서 spec.yaml을 생성하도록 하는 것부터 시작하십시오. 인간의 검토와 수정을 거친 후, 명세 주도 개발 또는 코드 우선 명세 사후 보충 개발로 전환하십시오.
어떤 접근 방식을 사용하든 궁극적인 목표는 동일합니다: 코드와 명세를 영구적으로 동기화된 상태로 유지하는 것입니다.
2.4. 명세 형식으로 YAML 사용
이 글에서는 명세 형식으로 YAML을 사용합니다.
최근 연구들은 LLM (Large Language Model)에게 JSON이나 YAML과 같은 **구조화된 형식 (Structured formats)**으로 정보를 제공하는 것을 강조합니다. Elnashar 등(2025)은 GPT-4o를 사용하여 세 가지 프롬프트 스타일 (JSON, YAML, 그리고 Hybrid CSV/Prefix)을 비교하였으며, 프롬프트 형식이 출력 품질, 토큰 비용 및 처리 시간에 영향을 미친다는 것을 입증했습니다. 그들은 YAML이 가독성과 효율성 사이에서 탁월한 균형을 제공한다는 것을 발견했습니다.
우리가 명세 형식으로 YAML을 채택한 이유는 다음과 같습니다:
- 계층 구조를 명확하게 나타내는 단순한 구조
- (JSON과 달리) 주석 지원
- 사람이 읽고 유지보수하기 쉬움
- AI에게 구조화된 정보를 전달하기 용이함
3. Step 1: YAML 형식으로 명세 문서(spec.yaml) 작성하기
먼저, Claude Code나 GitHub Copilot을 사용하여 spec.yaml 설계 문서를 생성하세요.
여기서 핵심적인 측면은 **세분성 (granularity)**입니다. AI가 이 문서만 읽고도 앱 전체를 구현할 수 있을 정도로 충분히 상세하게 명세를 작성하세요. 모호한 언어는 피하고, AI가 혼란을 느낄 여지가 없는 명세를 목표로 삼아야 합니다.
단순히 API와 데이터베이스 설계뿐만 아니라, 컨트롤러/서비스/레포지토리 (controller/service/repository)의 역할, 클래스 이름, 그리고 함수/메서드 이름을 명세에 포함하는 것을 권장합니다. 이 정도 수준의 상세함은 AI가 임의의 명명 규칙이나 아키텍처를 만들어내는 것을 방지하며, 추적성 (traceability)을 유지하기 훨씬 쉽게 만듭니다.
물론, 이러한 상세한 명세를 처음부터 직접 작성하는 것은 진정으로 어려운 일입니다. 이에 대한 제 권장 사항은 다음과 같습니다: AI와 상호작용하며 명세를 공동 제작(co-create)하세요. 앱의 대략적인 개요를 전달하는 것부터 시작하여, 필요한 각 구성 요소를 하나씩 짚어가며 YAML을 작성해 나가는 방식입니다. 초기에는 시간이 많이 걸리는 것처럼 보일 수 있지만, 나중에 큰 보상으로 돌아옵니다. AI가 명확한 명세를 갖게 되면 구현 지침은 단순해지고 재작업 (rework)은 현저히 줄어듭니다.
기존 애플리케이션에도 동일한 접근 방식이 적용됩니다. 만약 명세가 누락되었거나 오래되었다면, AI에게 현재 코드를 분석하여 spec.yaml의 시작점을 생성하도록 요청하세요. 하지만 한 번의 생성으로 끝내서는 안 됩니다. 대신, 다음과 같이 반복적인 대화를 나누세요: "이 기능에 대한 명세는 무엇인가요?" "이 API의 역할은 무엇인가요?" "이 클래스 구조가 타당한가요?" 실제 요구사항을 반영할 때까지 대화를 통해 명세를 반복적으로 정교화하세요.
다시 말해, 처음부터 새로 시작하든 기존의 레거시 코드 (Legacy code)와 함께 작업하든, 첫날부터 완벽한 명세 (Spec)를 목표로 하지 마세요. AI와의 대화를 통해 반복적으로 이를 정교화하세요. 더 높은 수준의 명세 품질은 구현 품질 및 유지보수성 (Maintainability)의 향상으로 직결됩니다.
언어, 프레임워크 (Frameworks), 데이터베이스 (Databases)를 결정할 때 AI에게 자문을 구하되, 그 제안을 무비판적으로 수용하지는 마세요. 다음과 같이 조사하고 검증해야 합니다: "이 아키텍처 (Architecture)가 정말로 타당한가?" "대안은 없는가?" AI는 설계 파트너이지, 의사 결정자가 아닙니다. 최종 설계와 기술 선택에 대한 책임은 당신에게 있습니다.
최소한 다음 항목들은 문서화해야 합니다:
- 앱의 목적 및 개요 (Purpose and overview)
- 언어 (Languages) (프론트엔드/백엔드)
- 사용할 프레임워크 (Frameworks)
- 데이터베이스 (Database) (유형, 테이블 구조 등)
- API 설계 (API design) (엔드포인트, 요청/응답 스키마)
- 화면 레이아웃 (Screen layouts) 및 기능 목록
- 클래스 설계 (Class design) (Controllers/Services/Repositories)
- 함수 이름 (메서드 이름) 및 책임 (Responsibilities)
- 디렉토리 구조 (Directory structure)
- 인증/인가 방식 (Authentication/authorization approach)
- 환경 변수 (Environment variables)
- 외부 서비스/API 연동 (External service/API integrations)
- 테스트 전략 (Testing strategy) (단위/통합/E2E 테스트)
- 코딩 표준 및 명명 규칙 (Coding standards and naming conventions)
- 제약 사항 (Constraints) (비기능적 요구사항, 성능, 보안 요구사항)
- 변경 이력 (Changelog)
- 미구현 기능 / 향후 작업 (Unimplemented features / future work (TODOs/Backlog))
3.1. 예시 spec.yaml
project:
name: TaskManagerApp
version: 1.0.0
...
이 YAML은 단순한 예시입니다. 더 명확한 명세 구조나 추가로 유용한 섹션에 대한 아이디어가 있다면 댓글로 공유해 주세요!
핵심은 당신이 "무엇을", "어떤 언어/기술로", "어떤 구조로" 구축하고 있는지를 세심하게 문서화하는 것입니다. 이러한 명세가 있다면 AI에게 설명을 반복할 필요가 없으며, 이는 토큰 (Tokens)을 절약하는 데에도 도움이 됩니다.
4. 2단계: 개발 환경 설정
명세가 준비되었다면, 실제 개발 환경을 준비합니다.
4.1. Git 설정
먼저, 코드 변경 사항을 추적하고 관리하기 위해 Git을 도입하세요. GitHub Desktop이나 이와 유사한 GUI(그래픽 사용자 인터페이스)를 사용하면 편리합니다.
- GitHub 계정 생성
- 저장소 (Repository) 생성 (Private(비공개)로 설정하는 것을 강력히 권장합니다)
상세한 설정 방법은 온라인에 훌륭한 가이드가 매우 많으므로, 여기서는 세부 사항을 생략하겠습니다.
4.2. 에디터 설정
다음으로, Visual Studio Code와 같은 에디터를 설치하고 Claude Code 또는 GitHub Copilot 확장 프로그램/CLI를 설치하세요. 설치 방법은 공식 문서를 참조하십시오:
5. 3단계: 명세에 기반하여 AI가 구현하도록 하기
환경 준비가 완료되었다면, 이제 AI가 앱을 구현할 차례입니다. 여기서 명세 주도 개발 (Spec-Driven Development)의 진가가 드러납니다. 참고: 이 단계는 새로운 앱을 구축하고 있다는 가정하에 진행됩니다. 이미 애플리케이션이 있다면, 4단계: "명세와 구현 사이의 불일치 확인"으로 건너뛰세요.
5.1. 앱 생성을 시작하기
@spec.yaml
전체 내용을 읽고 누락 없이 앱을 구현하세요.
5.2. 코드와 함께 테스트를 작성하도록 AI에게 요청하기
@spec.yaml
전체 내용을 읽고 테스트 코드도 함께 작성하세요.
이 프롬프트를 제출한 후 결과를 기다리세요. 범위에 따라 상당한 시간이 걸릴 수 있으니 인내심을 갖고 기다려야 합니다.
6. 4단계: 명세와 구현 사이의 불일치 확인
구현이 완료되면, AI가 명세와 실제 코드가 완벽하게 일치하는지 확인하도록 합니다. 이는 추적성 (Traceability)을 보장하기 위한 핵심 단계입니다.
@spec.yaml
현재 코드와 명세 사이의 모든 불일치 사항을 보고하세요.
불일치가 보고되면, 구현이 문제인지 아니면 명세가 문제인지 평가한 다음, 어느 쪽을 수정할지 결정하세요.
만약 구현이 문제라면 (코드가 spec.yaml을 따르지 않는 경우):
방금 확인한 불일치 사항을 수정하세요.
코드를 @spec.yaml에 맞게 조정하세요.
만약 명세가 문제라면 (spec.yaml이 구현과 다른 경우):
언급한 변경 사항을 다음 문서에 반영하세요.
그에 따라 @spec.yaml을 업데이트하세요.
이런 방식으로 코드와 명세를 지속적으로 동기화함으로써, 다음 단계로 나아갈 준비를 마칠 수 있습니다.
7. 5단계: 리뷰 → 수정 또는 명세 업데이트 루프 (The Review → Fix or Spec Update Loop)
완성된 앱은 거의 항상 원래의 비전과 약간의 차이가 있습니다. 여기서 여러분은 루프(loop)에 진입하게 됩니다.
7.1. 먼저 커밋하기 (Commit First)
커밋(commit)을 통해 현재 상태를 기록하세요.
7.2. 비전과 일치하지 않는다면 → 프롬프트를 통해 수정 (If It Doesn't Match Your Vision → Fix via Prompt)
(원하는 변경 사항)에 맞춰 코드를 수정하세요.
수정 사항이 적절해 보인다면, 해당 변경 사항에 대한 테스트를 요청하세요:
이 변경 사항을 읽고 이를 위한 테스트 코드 (test code)를 작성하세요.
7.3. 비전과 일치한다면 → 명세 업데이트 (If It Matches Your Vision → Update the Spec)
구현이 올바르다면 (코드는 맞고, 명세 업데이트가 필요한 경우), 명세 측을 업데이트하세요:
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기