본문으로 건너뛰기

© 2026 Molayo

Zenn헤드라인2026. 06. 15. 14:09

개인 개발에서 SDD(사양 주도 개발)를 18번 반복하며 깨달은 것

요약

AI 시대의 개발 속도를 결정하는 핵심은 구현이 아닌 상류(upstream) 설계에 있음을 강조하며, 사양 주도 개발(SDD) 방법론을 소개합니다. 사양서를 최상위 아티팩트로 취급하여 AI와의 문맥 상실 문제를 해결하고 개발의 일관성을 유지하는 과정을 다룹니다.

핵심 포인트

  • Vibe coding의 한계인 문맥 상실 문제를 SDD로 해결
  • 사양(Spec)을 최상위 아티팩트로 정의하여 코드의 파생물로 관리
  • EARS 기법을 활용한 요구사항의 구체화 및 모호성 제거
  • Non-Goals(범위 외) 설정을 통한 AI의 불필요한 구현 방지
  • 요구사항-설계-태스크로 이어지는 체계적인 3종 세트 구성

개인 개발 SNS인 「ShippAI」를, 기능 추가를 할 때마다 사양서 3종 세트를 작성한 후 구현하는 스타일(SDD: Spec-Driven Development)로 개발하고 있습니다. 이 글을 쓰는 시점에서 spec은 18개입니다. 인증도 타임라인도 AI 연동도 모더레이션도, 전부 이 프로세스를 거쳤습니다.

「개인 개발에서 사양서라니? 너무 거창한 거 아냐?」라고 생각하는 분이야말로 읽어주었으면 하는 내용입니다. 결론부터 말하자면, **구현이 빠른 시대에 개발 속도를 결정하는 것은 상류(upstream)**이며, SDD는 이를 위한 메커니즘입니다.

왜 vibe coding을 그만두었는가

AI와 대화하며 분위기로 코드를 작성하게 하는, 이른바 vibe coding에는 구조적인 문제가 있습니다. 바로 이터레이션(iteration)마다 문맥이 상실된다는 점입니다.

AI는 이전 대화의 「사고 과정」을 잊어버립니다. 그러면 잘못된 전제로 계속 코드를 작성하게 되고, 기존 아키텍처에 맞지 않는 코드가 조금씩 축적됩니다. 3일째쯤 되어 「어라, 이 처리는 어디서 무엇을 하고 있었지?」라고 느끼게 되는 것은 코드가 나빠서가 아니라 정답이 될 문서가 없기 때문입니다.

SDD는 이를 역전시킵니다. 사양(spec)을 최상위 아티팩트(artifact)로 취급하고, 코드는 사양으로부터의 파생물로 위치시킵니다. AI에게는 「무엇을 만들 것인가·왜 만드는가·무엇을 만들지 않을 것인가」를 구현 전에 전부 전달합니다.

3종 세트의 실물

기능별로 specs/###-<feature-name>/를 나누고, 3개의 파일을 순서대로 작성합니다. 실물(spec 015: 모더레이션 기능)에서 발췌하겠습니다.

1. requirements.md — 수락 기준은 EARS 기법으로

### R1: 게시물 신고(저장)
- **User Story**: 부적절한 게시물을 발견한 열람자로서, 나는 해당 게시물을 이유와 함께 신고하고 싶다. 그래야 운영진이 나중에 대처할 수 있고, 안심하고 사용할 수 있는 공간이 된다.
...

포인트는 두 가지입니다. EARS 기법(WHEN/IF 〜 THE SYSTEM SHALL 〜)으로 통일하면, 「적절하게 신고할 수 있다」와 같은 모호한 요구사항을 물리적으로 작성할 수 없습니다. 그리고 R1.3과 같은 번호 체계. 이것이 후속 단계에서 참조되는 앵커(anchor)가 됩니다.

또한, requirements에는 반드시 **범위 외(Non-Goals)**를 작성합니다. spec 015라면 「관리자 화면·자동 숨김·차단/뮤트 기능은 만들지 않는다」라고 적습니다. AI는 내버려 두면 친절한 마음으로 이것저것 만들어버리기 때문에, 「만들지 않겠다는 선언」은 「만들겠다는 선언」만큼이나 효과적입니다.

2. design.md — 설계와 테스트 전략

아키텍처·데이터 모델·어떤 파일이 생성될지에 대한 File Structure Plan에 더해, 저희 팀은 design에 반드시 테스트 전략을 포함한다는 규칙을 가지고 있습니다(이것이 SDD와 TDD를 연결합니다. 자세한 내용은 별도 기사에서 다룹니다).

3. tasks.md — 1태스크 = 1커밋 + 검증 절차

- [x] **T4: reportFailure / deleteFailure Server Actions**
- `src/app/actions/report.ts`: `requireAuth`+Zod+INSERT, `23505`→「이미 신고됨".
- _Requirements:_ R1.1, R1.3, R1.4, R3.1, R3.2, R3.3
...

각 태스크에 4가지 메타데이터를 붙입니다.

  • _Requirements:_ — 어떤 수락 기준을 충족하는 태스크인가 (R 번호로 추적)
  • _Boundary:_수정해도 좋은 파일 범위. AI의 「덤으로 하는 수정」을 여기서 차단
  • _Depends:_ — 의존 태스크. 병렬 실행 가능 여부가 여기서 결정됨
  • _Verify:_ — 완료에 대한 객관적인 판정 절차

태스크는 레이어 단위가 아니라 가치(value) 단위로 나눕니다. 「DB 레이어가 완성됨」은 아무것도 작동하지 않지만, 「신고가 DB에 저장됨」은 작동하는 기능이 하나 늘어납니다.

페이즈 게이트(Phase Gate): 리뷰는 경계에서, 두텁게

SDD의 핵심은 review at phase gates, not during implementation(구현 도중이 아니라, 페이즈의 경계에서 리뷰한다)입니다.

요구사항 (requirements) → [Gate 1] → 설계 (design) → [Gate 2] → 작업 (tasks) → [Gate 3] → 구현 (実装, auto-accept)

각 게이트(Gate)에서 인간이 승인한 후 다음 단계로 진행합니다. 반대로 말하면, 구현 중에는 세세한 승인을 거치지 않습니다. 구현 중에 매번 "이대로 해도 될까요?"라는 질문을 받으면, 인간은 "승인 피로 (approval fatigue)"로 인해 생각 없이 클릭만 하게 됩니다. 리뷰의 밀도를 게이트에 집중시키고, 구현은 한 번에 몰아치는 것이 인간의 주의력이라는 희소 자원을 배분하는 올바른 방법입니다.

저희는 여기서 더 나아가, 인간의 승인 전에 **AI 리뷰어에 의한 스펙 리뷰 (spec-review)**를 거칩니다. 기계적으로 잡아낼 수 있는 것들(EARS 형식의 붕괴, 참조 번호의 불일치, 예외 케이스의 누락 등)은 인간의 눈에 닿기 전에 미리 처리합니다. 이 메커니즘에 대해서는 별도 기사인 「자작 AI 리뷰어 4체의 관점 리스트 전격 공개」에 작성해 두었습니다.

18번 반복하며 알게 된 것

1. 재작업(手戻り)은 제로가 되지 않는다. 하지만 비용은 저렴해진다

솔직히 말씀드리면, 재작업은 있었습니다. 구현 중에 컬럼을 추가하거나, 집계용 뷰를 추가하는 식이었죠. "상류 단계에 투자하면 재작업이 제로가 된다"는 말은 거짓말입니다.

하지만 질이 다릅니다. 사양(Specification)이 문서로 고정되어 있으면, 변경의 영향 범위를 즉시 파악할 수 있습니다. "이 컬럼 추가는 R2.2와 T4에 영향을 준다. design의 데이터 모델 섹션을 수정하고, T4를 다시 수행하자"라고 특정할 수 있습니다. 바이브 코딩 (vibe coding)의 재작업이 "어디까지 망가졌는지 모르니 전부 다 확인해야 한다"는 식이라면, SDD의 재작업은 차분 (diff)을 정의할 수 있습니다. 그래서 비용이 저렴합니다.

2. 사양 변경은 .md 파일을 먼저 수정한다

가장 엄격히 지켜야 할 규율은 이것이었습니다. 구현 중에 설계 오류를 발견하면, 코드가 아니라 스펙 (spec)을 먼저 수정한 후 재구현합니다. 코드만 수정하면 사양서가 부패하고, 다음 스펙부터는 아무도 읽지 않게 됩니다. 사양서는 "쓰는 것"보다 "올바른 상태를 유지하는 것"이 더 어렵습니다.

3. 작은 기능이라도 요구사항 (requirements)은 작성한다

"이 정도는 사양서가 필요 없겠지"라며 건너뛴 기능일수록 나중에 다시 만들어야 했습니다. 단 3줄이라도 좋으니 요구사항을 작성하세요. 작성할 수 없다면, 그것은 "무엇을 만들지 스스로도 이해하지 못하고 있다"는 신호입니다.

4. 스펙은 그대로 개발 로그 자산이 된다

18개의 스펙 디렉토리는 그 자체로 프로젝트 의사결정의 역사입니다. "왜 신고 기능에 자유 기술란이 없는가" → 스펙 015의 Non-Goals 섹션에 그 이유가 적혀 있습니다. 미래의 자신에게 전달하는 인수인계 문서가 개발 프로세스의 부산물로서 자연스럽게 쌓여갑니다.

요약 — 핵심은 3원칙

  • Spec is the source of truth — 코드가 아니라 사양이 진실의 근원이다
  • Review at gates, not at edits — 매 라인 리뷰하지 말고 경계(gate)에서 두텁게 리뷰한다
  • Fresh context per phase — 페이즈마다 새로운 컨텍스트로 (이전 페이즈의 사고 과정이 아닌 결과물만을 전달한다)

구현 비용이 계속 낮아지는 이상, 개발의 승부처는 "무엇을 어떻게 만들 것인가"를 결정하는 상류 단계로 옮겨갑니다. SDD는 대기업의 무거운 프로세스 이야기가 아니라, **AI 시대의 개인 개발에야말로 효과적인 레버리지 (leverage)**였습니다.

이 프로세스로 만들고 있는 "ShippAI" (실패를 AI가 웃음과 교훈으로 바꾸는 SNS)는 곧 출시될 예정입니다. 개발 진행 상황은 X @ShippAI_dev 에서 실시간으로 공개하고 있습니다. spec-review / code-review의 내용, SDD × TDD의 연결 방식도 순차적으로 글로 올릴 예정이니, 관심 있다면 팔로우해 주세요.

Discussion

AI 자동 생성 콘텐츠

본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0