
Github Spec Kit을 활용한 명세 기반 AI 보조 개발 (Spec-Driven AI-Assisted Development)
요약
빠른 프로토타이핑을 위한 '바이브 코딩'과 프로덕션 단계의 안정성을 위한 '명세 기반 개발'의 조화를 제안합니다. AI 보조 개발 환경에서 기술 부채를 방지하고 품질을 유지하기 위한 엔지니어링 제어 전략을 다룹니다.
핵심 포인트
- 바이브 코딩은 초기 탐색과 실험 단계에 최적화됨
- 프로덕션 단계에서는 명세 기반 피드백 루프가 필수적임
- AI는 설계 결정의 효과를 규모 있게 증폭시킴
- 속도와 품질 사이의 균형을 위한 단계적 접근 필요
“바이브 코딩 (Vibe coding)”은 빠르고 직관적이며, 솔직히 모멘텀을 쌓기에 가장 즐거운 방법 중 하나입니다. 이는 창의성을 최대 속도로 해방시키는 느낌이며, 저 또한 정기적으로 사용하고 있습니다.
무언가를 얼마나 빨리 만들 수 있는지, 그리고 그만큼 얼마나 빨리 미래의 자신을 혼란스럽게 만들 수 있는지는 정말 놀라운 일입니다.
하지만 탐색 단계에서 프로덕션 (Production) 단계로 넘어갈 때, 모멘텀만으로는 충분하지 않습니다. 프로덕션 시스템에서 구조 없는 속도는 종종 피할 수 있는 복잡성을 초래합니다.
빠르게 출시하는 것은 훌륭합니다. 하지만 빠르게 출시하고 똑같은 버그를 반복해서 수정하는 것은... 그리 훌륭하지 않습니다.
구조화된 피드백 루프 (Feedback loop)가 없다면, 팀은 빠르게 기술 부채 (Technical debt)를 쌓을 수 있으며, 이는 재작업, 버전 불일치, 보안 취약점, 그리고 점진적인 아키텍처 드리프트 (Architecture drift)로 이어집니다.
기술 부채는 헬스장 회원권 비용과 같습니다. 처음에는 눈에 띄지 않지만, 배경에서 조용히 복리로 쌓입니다.
이 포스트는 AI 보조 소프트웨어 인도 (Software delivery) 환경에서 협업하는 엔지니어, 테크 리드 (Tech leads), 그리고 제품 전문가라는 다양한 독자층을 위한 교육용 플레이북 역할을 합니다.
AI가 조만간 엔지니어를 대체하지는 않겠지만, 좋은 설계 결정과 나쁜 결정 모두를 규모 있게 증폭시키는 것은 확실합니다.
본문 전반의 예시는 저의 주요 기술 스택인 Angular와 Java/Quarkus를 기반으로 합니다. 하지만 이 원칙들은 기술 중립적 (Technology-agnostic)입니다. 버전 드리프트 (Version drift), 암시적 기본값 (Implicit defaults), 아키텍처 불일치와 관련된 동일한 문제들은 모든 프레임워크와 플랫폼에 존재합니다.
프레임워크는 변합니다. 의존성 (Dependency) 버전도 변합니다. 하지만 프로덕션의 혼돈은요? 그 부분은 놀라울 정도로 안정적입니다.
주요 의제
목표는 바이브 코딩 (Vibe coding)을 중단하는 것이 아닙니다.
목표는 바이브 코딩 주변에 엔지니어링 제어 (Engineering control)를 도입하여, 품질을 타협하지 않으면서 속도를 유지할 수 있도록 하는 것입니다.
이렇게 생각해 보세요:
Vibe coding은 구조보다 속도와 창의성이 더 중요한 발견(discovery), 실험(experimentation), 그리고 빠른 프로토타이핑(rapid prototyping) 단계에서 매우 탁월합니다.
반면, 명세 기반 피드백 루프(Specs-driven feedback loops)는 정확성(correctness), 일관성(consistency), 그리고 유지보수성(maintainability)이 타협할 수 없는 요소가 되는 프로덕션(production) 결정 단계로 나아갈 때 필수적입니다.
프로토타입은 학습을 위한 것입니다. 프로덕션은 당신의 결정과 함께 살아가는 것입니다.
승리하는 모델은 '이것 아니면 저것(either-or)'이 아닙니다. 두 가지를 순차적으로 적용하는 것입니다.
먼저, 문제 공간(problem space)을 탐색할 수 있을 만큼 충분히 빠르게 움직입니다.
그다음, 구축한 것이 실제로 현실과 맞닿았을 때 살아남을 수 있는지 확인하기 위해 딱 필요한 만큼 속도를 늦춥니다.
의사결정 프레임워크: 언제 Vibe를 사용하고, 언제 Spec을 사용할 것인가
간단한 가이드라인을 사용하세요:
초기 발견 (Early discovery) → vibe coding으로 시작하세요.
이 단계는 속도, 실험, 그리고 반복(iteration)이 가장 중요하며, 목표는 무엇이 작동하는지 빠르게 배우는 것입니다.
프로덕션 환경의 사용자 대면 기능 (Anything user-facing in production) → 명세 기반 피드백 루프(specs-driven feedback loop)로 시작하세요.
이 단계에서는 변경 사항이 실제 사용자과 시스템에 영향을 미치기 때문에, 가공되지 않은 속도보다 명확성(clarity), 일관성(consistency), 그리고 검증(validation)이 더 중요합니다.
마이그레이션 또는 플랫폼 수준의 작업 (Migration or platform-level work) → 항상 사전에 명시적인 버전 관리(versioning)와 호환성 체크(compatibility checks)를 포함하세요.
이는 숨겨진 의존성 문제(dependency issues), 파괴적 변경(breaking changes), 그리고 장기적인 유지보수 측면의 예기치 못한 상황을 방지하는 데 도움이 됩니다.
이러한 접근 방식은 가치를 더하는 곳에서는 속도를 보존하는 동시에, 진정으로 중요한 곳에는 엄격함(rigor)을 적용하여, 단기적인 추진력이 장기적인 기술적 마찰(technical friction)로 변하는 것을 방지합니다.
두 가지 워크플로우, 두 가지 결과
워크플로우 A: 프롬프트에서 구현까지 (피드백 루프 없음)
전형적인 흐름:
- AI에게 프로젝트를 구축하도록 요청합니다.
- 큰 검토 없이 기본 선택 사항을 수락합니다 ("AI가 아마 더 잘 알겠지"라고 생각하며).
- 즉시 기능 구현을 시작합니다.
- 나중에 통합(integration), 테스트, 또는 운이 좋다면 출시 직전에 문제를 발견합니다.
일반적인 실패 모드 (Common failure modes):
- AI가 프레임워크(Framework)나 라이브러리(Library) 버전을 암묵적으로 선택하여 팀 표준이나 지원 정책과 일치하지 않음.
- 보안(Security), 관찰 가능성(Observability), 유지보수성(Maintainability)과 같은 비기능적 요구사항(Non-functional requirements)이 조용히 사라짐 (분명히 "암시되어" 있었다고 함).
- 설계가 실제로 명확해지기 전에 구현이 시작되어 제품의 의도(Product intent)가 희석됨.
- 작동하는 코드베이스(Codebase)를 올바른 아키텍처(Architecture)로 오해함.
내 컴퓨터에서는 잘 됐는데... AI가 작성한 것이니, 이제 두 가지 미스터리가 생겼군요.
기능을 배포하자마자 세 개의 새로운 Jira 티켓을 바로 생성하는 것만큼 자신감을 보여주는 것도 없죠.
워크플로우 B: 명세 기반 AI 사이클 (피드백 루프 포함) (Workflow B: Specs-Driven AI Cycle (With Feedback Loop))
전형적인 흐름:
- 의도(Intent), 제약 조건(Constraints), 그리고 "완료(Done)"가 실제로 무엇을 의미하는지 포착합니다.
- 코드를 건드리기 전에 고수준의 기술 설계(High-level technical design)를 정의합니다.
- 이를 명시적인 결정 사항(API, 아키텍처, 데이터 흐름, 버전 등)으로 세분화합니다.
- AI에게 명세(Spec)에 따라 엄격하게 구현하도록 요청합니다.
- 의존성(Dependencies), 프레임워크 버전, 아키텍처 정렬 및 테스트를 검증합니다.
- 발견된 사항을 다음 명세 반복(Iteration)에 다시 반영합니다.
이 워크플로우는 여전히 빠르게 진행되지만, 통제된 방식의 속도입니다. "희망 기반 개발(Hope-driven development)"보다는 "의도 기반 엔지니어링(Intent-driven engineering)"에 가깝습니다.
워크플로우 A에서는 배포 중에 문제를 발견합니다. 워크플로우 B에서는 문서를 통해 먼저 정중하게 그 문제들에 대해 논쟁합니다.
AI는 코드를 생성하는 데 탁월합니다. 또한 매우 자신만만하게 틀린 가정을 생성하는 데도 탁월합니다. 따라서 명세(Spec)는 여러분의 안전벨트입니다.
운영 환경(Production)에서 갑작스러운 문제가 나타나는 대신, 문제를 수정할 때 정서적 지원을 위한 간식과 롤백(Rollback) 계획이 필요하지 않은 이른 시점에 문제가 나타나게 됩니다.
목표는 놀라운 일이 적어지는 것이 아닙니다. 목표는 놀라운 일의 비용을 낮추는 것입니다.
일반적인 조언 vs 실질적인 현실 (Common Advice vs Practical Reality)
일반적인 조언 지도 (Common advice map)
- "그냥 프롬프트(Prompt)를 더 잘 작성하세요."
- "AI는 충분히 똑똑하니, 그냥 배포하세요."
- "나중에 정리하면 됩니다."
현실 지도 (Reality map)
- 더 나은 프롬프트(Prompt)가 도움이 될 수는 있지만, 시스템 설계(System Design)를 대체할 수는 없습니다.
- 빠른 출력(Output)이 유효한 아키텍처(Architecture)와 동일한 것은 아닙니다.
- 나중에 정리하는 것은 보통 더 느리고 비용이 많이 듭니다.
만약 바이브 코딩(Vibe coding)이 재즈라면, 프로덕션(Production)은 클래식 음악입니다. 사용하는 악기는 같지만, 틀린 음을 냈을 때의 결과는 매우 다릅니다.
Github Spec Kit
고품질 소프트웨어를 더 빠르게 구축하세요.
모든 조각을 처음부터 바이브 코딩(Vibe coding)하는 대신, 제품 시나리오와 예측 가능한 결과에 집중할 수 있게 해주는 오픈 소스 툴킷(Toolkit)입니다.
마침내, '엔드포인트 하나만 더 추가하는 것'에 설계 문서(Design doc)가 필요한지를 두고 새벽 2시에 AI와 논쟁하는 일을 멈출 방법이 생겼습니다.
이것부터 시작해 봅시다. 왜냐하면 바이브 코딩(Vibe coding)에는 롤백(Rollback) 계획이 포함되어 있지 않기 때문입니다.
설치를 위해 Python이 필요하므로, 이제 이것은 더 이상 '그냥 느낌대로(Just vibe it)' 할 수 있는 상황이 아닙니다.
프로젝트에 이를 통합하는 몇 가지 방법이 있습니다
- 최신 릴리스(Release)를 다운로드하여 프로젝트 디렉토리나 기존 코드베이스(Codebase)에 수동으로 추가하는 방법이 있습니다.
uv specify --from git+https://github.com/github/spec-kit.git@vX.Y.Z를 사용하세요. 여기서 vX.Y.Z는 Releases의 최신 태그(Tag)로 교체해야 합니다.- CLI를 사용하여
uv tool install specify-cli --from git+https://github.com/github/spec-kit.git@vX.Y.Z를 실행합니다.
오, Spec Kit을 먼저 설치해야 하네요. 축하합니다, 이제 우리는 "진정한 엔지니어링 설정 단계"에 진입했습니다.
Spec Kit 살펴보기
이 튜토리얼에서는 브라운필드(Brownfield) 프로젝트를 사용하여 작업할 것입니다. 다음 명령어로 시작해 보겠습니다:
specify init <project_name> --integration copilot
GitHub Copilot을 사용하고 있으므로, 통합 모드(Integration mode)는 copilot으로 설정됩니다.
Spec Kit에 의해 생성된 폴더 구조는 아래와 같습니다:
[

우리의 기술 스택(Technology stack)은 다음과 같습니다:
Angular Angular Skill(https://angular.dev/ai/agent-skills)
Quarkus Quarkus skill(https://github.com/quarkusio/skills)
두 스킬 저장소(repositories)에서 제공하는 지침을 따르면, 설정 과정의 일부로 에이전트 디렉토리 내에 전용 폴더가 생성됩니다.
이러한 설정을 통해, 이제 LLM(Large Language Model)에 보내는 모든 프롬프트(prompt)는 구성된 스킬(skills)의 영향을 받게 됩니다. 즉, 코드 생성(code generation)이 사전에 정의된 패턴과 가이드라인을 일관되게 따르게 된다는 의미입니다.
이 시점에서 당신은 더 이상 단순히 LLM에 프롬프트를 던지는 것이 아닙니다. LLM은 마치 갑자기 매우 책임감 있는 존재가 된 것처럼, 답변하기 전에 자신의 '스킬 폴더(skills folder)'를 정중하게 참조합니다.
다시 말해, 모든 응답은 이제 지능과 구조, 그리고 새벽 2시에 독단적으로 아키텍처 결정을 내리는 것을 방지할 수 있을 만큼의 적절한 규율이 결합된 결과물이 됩니다.
IntelliJ에서의 GitHub Copilot
저는 IntelliJ IDEA에서 GitHub Copilot 플러그인 CLI를 사용하고 있습니다. 하지만 동일한 기능은 Visual Studio Code에서도 사용할 수 있습니다.
SpecKit과 함께 가장 흔히 사용되는 슬래시 명령어(slash command)는 다음과 같습니다.
코딩 에이전트(coding agent)용 슬래시 명령어:
/speckit.constitution - 프로젝트 원칙 수립
/speckit.specify - 기준 명세(baseline specification) 생성
/speckit.plan - 구현 계획(implementation plan) 생성
/speckit.tasks - 실행 가능한 작업(actionable tasks) 생성
/speckit.implement - 구현 실행
spec-kit.constitution의 주요 목표는 프로젝트를 위한 명확한 경계를 정의하여, LLM이 잘 정의된 원칙 세트 내에서 작동하도록 하는 것입니다.
이것을 시스템을 위한 가드레일 (guardrails)을 설정하는 것이라고 생각하십시오. 즉, 일관성 (consistency), 예측 가능성 (predictability), 그리고 프로젝트 표준과의 정렬 (alignment)을 보장하는 것입니다.
이는 LLM을 위한 잘 설계된 동물원 우리와 비슷합니다. 움직이고, 탐색하고, 수행할 수 있는 충분한 공간을 제공하되, 안전하고 효과적으로 작동할 수 있도록 명확하게 정의된 경계 내에 두는 것입니다.
CLI에서 /speckit.constitution <프로젝트에 대한 설명> 명령어를 실행하세요. 당신의 원칙에 기반하여 제시할 수 있는 설명입니다.
**예시**
`/speckit.constitution 서비스는 Spring Boot, Quarkus 또는 Micronaut를 사용할 수 있지만, 각 서비스는 반드시 명확한 경계 컨텍스트 (bounded-context) 책임, 명시적인 API 계약 (API contracts), 그리고 격리된 빌드/런타임 설정을 소유해야 합니다. 서비스 간 의존성은 반드시 문서화된 인터페이스를 통해 발생해야 하며, 내부 패키지 결합 (internal package coupling)을 통해서는 절대 발생해서는 안 됩니다.`
...
## 핵심 원칙 (Core Principles)
### I. 다중 언어 서비스 경계 (Polyglot Service Boundaries)
...
모든 업데이트된 파일은 .specify >> templates 아래에 제공된 템플릿을 기반으로 합니다.
또한 .github >> co-pilot-instruction.md 아래에 다음과 같은 지침을 Co-pilot을 위해 추가해야 합니다.
Angular 개발 가이드를 보려면 `.github/agents/skills/angular-developer/SKILL.md`를 읽으세요.
새로운 Angular 앱을 생성하려면 `.github/agents/skills/angular-new-app/SKILL.md`를 읽으세요.
...
계획 템플릿 (plan-template)을 당신의 기술 스택 (tech stack)으로 업데이트하는 것이 LLM에게 훨씬 더 좋습니다. 간단한 예시는 다음과 같습니다.
**언어/버전 (Language/Version)**: [예: Java 25 또는 확인 필요 (NEEDS CLARIFICATION)]
**주요 의존성 (Primary Dependencies)**: [예: Spring Boot 4.0.6, Angular 21.2, Quarkus 3.2.1, Micronaut 5.0.0 또는 확인 필요 (NEEDS CLARIFICATION)]
...
우리는 에이전트 (agent)를 위해 .github 및 .specify 아래의 파일들을 편집할 권한을 항상 가집니다.
오—정말 대담한 선언이군요. AI가 적극적으로 따르고 있는 규칙서 (rulebook)를 자신 있게 편집하는 것만큼 '책임감 있는 엔지니어링 (responsible engineering)'을 잘 나타내는 것도 없으니까요.
- /speckit.specify - <설명>
예시
/speckit.specify - 사용자의 이름(first name), 성(last name), 이메일 주소가 포함된 회원가입 화면을 생성하라
이 명령을 실행하면 LLM (Large Language Model)이 spec 폴더 아래에 여러 파일을 생성합니다. spec 디렉토리 내부에 생성된 .md 파일들을 반드시 검토해야 합니다.
이
.md파일들을 마치 인터넷 전체를 읽었지만 여전히 당신의 프로젝트 컨텍스트 (Project Context)는 잊어버린, 매우 빠른 인턴이 수행한 코드 리뷰 (Code Review)처럼 취급하세요.
생성된 파일의 샘플
### 기능 요구사항 (Functional Requirements)
- **FR-001**: 회원가입 페이지는 반드시 이름(first name), 성(last name), 그리고 이메일 주소(email address)를 위한 입력 필드를 제공해야 한다.
...
/speckit.clarify
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기
