스펙 주도 개발(SDD) 이해하기: Kiro, Spec-Kit, Tessl

5 hours ago 1

  • Spec-Driven-Development(SDD) 는 AI 기반 코딩에서 코드 작성 전에 명세서(spec)를 먼저 작성하는 접근 방식으로, 명세서가 개발자와 AI의 진실 공급원(source of truth) 역할을 수행
  • SDD는 세 가지 구현 수준으로 구분되며, spec-first(명세 우선 작성), spec-anchored(유지보수를 위한 명세 보존), spec-as-source(명세를 주요 소스 파일로 사용하며 개발자는 코드 직접 편집 안 함)로 단계적 발전
  • Kiro는 요구사항→설계→작업의 단순한 3단계 워크플로우를 제공하고, spec-kit은 헌법(constitution)이라는 강력한 규칙 기반 워크플로우를 사용하며, Tessl은 명세와 코드를 1:1로 매핑하는 spec-as-source 접근 방식 실험
  • 세 도구 모두 작은 버그 수정에는 과도한 프로세스를 요구하고, 마크다운 파일 리뷰가 코드 리뷰보다 번거로우며, 큰 컨텍스트 윈도우에도 불구하고 AI가 모든 지시사항을 제대로 따르지 못하는 한계 존재
  • SDD는 과거 모델 주도 개발(MDD)의 실패 사례를 상기시키며, 비결정성과 비유연성이라는 양쪽의 단점을 모두 가질 위험이 있어 실제 프로젝트에서의 유용성에 대한 검증 필요

스펙 주도 개발(SDD)의 정의

  • SDD는 코드 작성 전 명세서를 먼저 작성하는 "문서 우선(documentation first)" 접근 방식으로, 명세서가 개발자와 AI 모두에게 단일 진실 소스(single source of truth) 역할 수행
  • GitHub는 "소프트웨어 유지보수는 명세서의 진화를 의미하며, 개발의 공통 언어가 더 높은 수준으로 이동하고 코드는 최종 단계 접근 방식"이라고 정의
  • Tessl은 "명세서가 코드가 아닌 주요 산출물이 되는 개발 접근 방식으로, 명세서는 구조화되고 테스트 가능한 언어로 의도를 설명하며 에이전트가 이에 맞춰 코드 생성"이라고 설명
  • SDD는 세 가지 구현 수준으로 나뉨
    • Spec-first: 잘 구성된 명세서를 먼저 작성하고 AI 지원 개발 워크플로우에 사용
    • Spec-anchored: 작업 완료 후에도 명세서를 유지하여 해당 기능의 진화와 유지보수에 계속 활용
    • Spec-as-source: 명세서가 시간이 지나도 주요 소스 파일로 유지되며, 개발자는 명세서만 편집하고 코드는 직접 건드리지 않음
  • 모든 SDD 접근 방식은 spec-first이지만, 모두가 spec-anchored나 spec-as-source를 지향하는 것은 아니며, 시간 경과에 따른 명세서 유지 전략이 모호하거나 완전히 열려 있는 경우가 많음

명세서(spec)란 무엇인가

  • 명세서는 자연어로 작성된 구조화되고 행동 지향적인 산출물로서 소프트웨어 기능을 표현하고 AI 코딩 에이전트에게 가이드 역할 수행
  • 가장 일관된 정의는 명세서를 제품 요구사항 문서(PRD) 에 비유하는 것
  • 명세서는 코드베이스를 위한 일반적인 컨텍스트 문서와 구분되어야 함
    • 일반 컨텍스트에는 규칙 파일, 제품 및 코드베이스의 고수준 설명이 포함되며, 일부 도구는 이를 메모리 뱅크(memory bank) 라고 부름
    • 메모리 뱅크 파일은 코드베이스의 모든 AI 코딩 세션에서 관련되지만, 명세서는 특정 기능을 생성하거나 변경하는 작업에만 관련됨
  • 각 SDD 변형은 명세서의 구조, 세부 수준, 프로젝트 내 조직 방식에 대한 고유한 접근 방식을 정의

SDD 도구 평가의 어려움

  • SDD 도구와 접근 방식을 실제 사용에 가깝게 평가하는 것은 매우 시간 소모적
    • 다양한 규모의 문제, 그린필드/브라운필드 프로젝트에서 시도해야 하며, 중간 산출물을 피상적이 아닌 철저히 검토하고 수정하는 시간 필요
  • GitHub의 spec-kit 블로그 포스트는 "중요한 것은 당신의 역할이 단순히 방향을 잡는 것만이 아니라 검증하는 것이며, 각 단계에서 반영하고 개선해야 한다"고 강조
  • 세 도구 중 두 개는 기존 코드베이스에 도입하는 데 더 많은 작업이 필요해 보이며, 브라운필드 코드베이스에 대한 유용성 평가를 더욱 어렵게 만듦
  • 실제 코드베이스에서 일정 기간 동안 사용한 사람들의 사용 보고서를 듣기 전까지는 실제 작동 방식에 대한 많은 미해결 질문 존재

Kiro

  • Kiro는 세 도구 중 가장 단순하고 가벼운 도구로, 대부분 spec-first 접근 방식에 해당
    • 작업이나 사용자 스토리에 사용하는 예시만 발견되었으며, 시간이 지나면서 여러 작업에 걸쳐 spec-anchored 방식으로 요구사항 문서를 사용하는 방법에 대한 언급은 없음
  • 워크플로우: 요구사항 → 설계 → 작업
    • 각 워크플로우 단계는 하나의 마크다운 문서로 표현되며, Kiro는 VS Code 기반 배포판 내에서 이 3단계를 안내
  • Kiro의 주요 구성 요소

    • 요구사항(Requirements)
      • 각 요구사항이 "사용자 스토리"(As a... 형식)를 나타내는 요구사항 목록으로 구조화
      • 수락 기준은 GIVEN... WHEN... THEN... 형식 사용
    • 설계(Design)
      • 구성 요소 아키텍처 다이어그램, 데이터 흐름, 데이터 모델, 오류 처리, 테스트 전략, 구현 접근 방식, 마이그레이션 전략 등의 섹션 포함
      • 작업에 따라 일관된 구조인지 또는 변경되는지 불확실
    • 작업(Tasks)
      • 요구사항 번호로 추적되는 작업 목록
      • 작업을 하나씩 실행하고 작업별 변경 사항을 검토할 수 있는 추가 UI 요소 제공
  • Kiro의 메모리 뱅크

    • Kiro는 메모리 뱅크 개념을 "steering(조종)"이라고 부름
      • 내용이 유연하며, 워크플로우가 특정 파일의 존재에 의존하지 않는 것으로 보임
    • Kiro가 조종 문서 생성을 요청받을 때 생성하는 기본 구조는 product.md, structure.md, tech.md

Spec-kit

  • spec-kit은 GitHub의 SDD 버전으로, 다양한 일반 코딩 어시스턴트를 위한 작업 공간 설정을 생성할 수 있는 CLI로 배포
  • 구조 설정 후 코딩 어시스턴트의 슬래시 커맨드를 통해 spec-kit과 상호작용
  • 모든 산출물이 작업 공간에 직접 배치되므로, 논의된 세 도구 중 가장 커스터마이징 가능
  • Spec-kit의 워크플로우

    • 워크플로우: 헌법(Constitution) → 𝄆 명세화(Specify) → 계획(Plan) → 작업(Tasks) 𝄇
    • spec-kit의 메모리 뱅크 개념은 spec-driven 접근 방식의 전제 조건
      • 이를 헌법(constitution) 이라고 부르며, 모든 변경에 항상 적용되어야 하는 "불변" 고수준 원칙 포함
      • 워크플로우에서 많이 사용되는 매우 강력한 규칙 파일
  • Spec-kit의 작동 방식

    • 각 워크플로우 단계(specify, plan, tasks)에서 bash 스크립트와 템플릿을 사용하여 파일 및 프롬프트 세트를 인스턴스화
    • 워크플로우는 파일 내 체크리스트를 많이 활용하여 필요한 사용자 명확화, 헌법 위반, 연구 작업 등을 추적
      • 각 워크플로우 단계의 "완료 정의(definition of done)" 같은 역할 (AI가 해석하므로 100% 보장은 없음)
    • 하나의 명세서는 여러 파일로 구성됨
      • 예: data-model, plan, tasks, spec, research, api, component 등 8개 파일
  • Spec-kit의 접근 방식

    • GitHub는 처음에는 spec-anchored 접근 방식을 지향하는 것으로 보임
      • "명세서를 정적 문서가 아닌 프로젝트와 함께 진화하는 살아있는 실행 가능한 산출물로 재고하고 있으며, 명세서는 공유된 진실 공급원이 됨"
    • 그러나 spec-kit은 생성되는 모든 명세서에 대해 브랜치를 생성하므로, 명세서를 기능의 수명이 아닌 변경 요청의 수명 동안 살아있는 산출물로 보는 것으로 해석됨
    • 커뮤니티 논의에서도 이 혼란에 대해 이야기하고 있으며, spec-kit은 여전히 spec-first에만 해당하고 시간이 지나도 spec-anchored는 아닌 것으로 보임

Tessl Framework

  • Tessl Framework는 비공개 베타 단계이며, spec-kit처럼 다양한 코딩 어시스턴트를 위한 작업 공간 및 구성 구조를 생성할 수 있는 CLI로 배포
  • CLI 명령은 MCP 서버로도 작동
  • Tessl의 특징

    • 세 도구 중 유일하게 spec-anchored 접근 방식을 명시적으로 지향하며, spec-as-source 수준의 SDD도 탐구 중
    • Tessl 명세서는 유지 관리 및 편집되는 주요 산출물 역할을 할 수 있으며, 코드는 상단에 // GENERATED FROM SPEC - DO NOT EDIT 주석으로 표시
      • 현재는 명세서와 코드 파일 간 1:1 매핑, 즉 하나의 명세서가 코드베이스의 한 파일로 변환
      • 여전히 베타 단계이며 다양한 버전을 실험 중이므로, 하나의 명세서가 여러 파일이 있는 코드 구성 요소로 매핑되는 수준으로도 발전 가능
  • Tessl 명세서 구조

    • @generate나 @test 같은 태그는 Tessl에게 무엇을 생성할지 지시
    • API 섹션은 코드베이스의 다른 부분에 노출되는 최소한의 인터페이스를 명세서에 정의하는 아이디어를 보여주며, 생성된 구성 요소의 중요한 부분이 유지 관리자의 완전한 통제 하에 있도록 보장
    • tessl build를 실행하면 해당 JavaScript 코드 파일 생성
  • Tessl의 추상화 수준

    • spec-as-source를 위한 명세서를 코드 파일당 상당히 낮은 추상화 수준에 배치하면, LLM이 수행해야 하는 단계 및 해석의 양과 따라서 오류 가능성 감소
    • 이렇게 낮은 추상화 수준에서도 동일한 명세서에서 여러 번 코드를 생성할 때 비결정성 관찰
      • 명세서를 반복적으로 작성하고 코드 생성의 반복 가능성을 높이기 위해 점점 더 구체적으로 만드는 과정은 모호하지 않고 완전한 명세 작성의 함정과 과제를 상기시킴

관찰 사항 및 질문

  • 하나의 워크플로우로 모든 규모를 다룰 수 있는가?

    • Kiro와 spec-kit은 각각 하나의 독단적인 워크플로우를 제공하지만, 둘 다 대부분의 실제 코딩 문제에 적합하지 않을 가능성이 있음
    • 문제 크기에 맞는 충분한 다양성을 제공하는지 불분명
      • 작은 버그를 Kiro로 수정하려고 했을 때, 워크플로우가 망치로 호두를 깨는 것 같았음
      • 요구사항 문서가 작은 버그를 총 16개 수락 기준이 있는 4개 "사용자 스토리"로 변환
    • spec-kit 사용 시에도 어떤 크기의 문제에 사용해야 할지 불확실
      • 과거 팀에서 3-5 포인트 스토리가 될 기능을 시도했을 때, spec-kit이 취한 단계 수와 생성한 마크다운 파일 양이 문제 크기에 비해 과도하게 느껴짐
      • 동일한 시간에 "일반" AI 지원 코딩으로 기능을 구현할 수 있었을 것이며, 훨씬 더 제어력을 느꼈을 것
    • 효과적인 SDD 도구는 다양한 크기와 유형의 변경을 위해 최소한 몇 가지 다른 핵심 워크플로우에 대한 유연성 제공 필요
  • 코드 리뷰보다 마크다운 리뷰?

    • spec-kit은 검토할 많은 마크다운 파일을 생성
      • 서로 반복적이고 이미 존재하는 코드와도 반복적
      • 일부는 이미 코드를 포함하고 있어 전체적으로 매우 장황하고 검토하기 지루함
    • Kiro에서는 3개 파일만 얻고 "요구사항 > 설계 > 작업"의 멘탈 모델을 이해하기 더 직관적이어서 조금 더 쉬움
      • 하지만 Kiro도 수정을 요청한 작은 버그에 비해 너무 장황함
    • 솔직히 이 모든 마크다운 파일보다 코드를 검토하는 것이 낫다는 생각
    • 효과적인 SDD 도구는 매우 좋은 명세서 검토 경험 제공 필요
  • 잘못된 통제감?

    • 이 모든 파일, 템플릿, 프롬프트, 워크플로우, 체크리스트에도 불구하고 에이전트가 궁극적으로 모든 지시사항을 따르지 않는 경우를 자주 목격
    • 컨텍스트 윈도우가 더 커진 것은 SDD의 활성화 요인 중 하나로 언급되지만, 윈도우가 더 크다고 해서 AI가 그 안의 모든 것을 제대로 파악한다는 의미는 아님
    • 예시
      • spec-kit은 계획 중에 연구 단계가 있고 기존 코드에 대해 많은 연구를 수행했지만, 궁극적으로 에이전트는 이것이 기존 클래스에 대한 설명이라는 점을 무시하고 새로운 명세로 받아들여 모두 다시 생성하여 중복 생성
      • 지시사항을 무시하는 예뿐만 아니라, 지시사항(예: 헌법 조항 중 하나)을 너무 열심히 따르려다 과도하게 수행하는 에이전트도 목격
    • 과거 경험상 우리가 구축하는 것을 통제하는 최선의 방법은 작고 반복적인 단계였으므로, 많은 사전 명세 설계가 좋은 아이디어인지 매우 회의적
    • 효과적인 SDD 도구는 반복적인 접근 방식을 수용해야 하지만, 작은 작업 패키지는 SDD의 아이디어와 거의 상반되는 것처럼 보임
  • 기능적 명세와 기술적 명세를 효과적으로 분리하는 방법?

    • SDD에서 기능적 명세와 기술적 구현 사이의 분리를 의도적으로 하는 것은 일반적인 아이디어
      • 근본적인 열망은 궁극적으로 AI가 모든 솔루션과 세부 사항을 채우고 동일한 명세로 다른 기술 스택으로 전환할 수 있다는 것
    • 실제로 spec-kit을 시도할 때 언제 기능적 수준에 머물러야 하고 언제 기술적 세부 사항을 추가할 때인지 자주 혼란스러웠음
      • 튜토리얼과 문서도 이에 대해 일관성이 없었으며, "순수하게 기능적"이 실제로 무엇을 의미하는지에 대한 다른 해석 존재
    • 요구사항과 구현을 제대로 분리하지 못한 많은 사용자 스토리를 떠올려보면, 우리 직업 전체가 이를 잘 수행한 기록이 좋지 않음
  • 대상 사용자는 누구인가?

    • 많은 spec-driven 개발 도구의 데모와 튜토리얼에는 제품 및 기능 목표 정의 같은 것이 포함되며, "사용자 스토리" 같은 용어도 사용
    • 여기서의 아이디어는 AI를 cross-skilling의 활성화 요인으로 사용하여 개발자가 요구사항 분석에 더 적극적으로 참여하도록 하는 것일 수 있음
      • 또는 개발자가 이 워크플로우에서 작업할 때 제품 담당자와 페어링?
    • 이 중 어느 것도 명시적으로 설명되지 않으며, 개발자가 이 모든 분석을 수행하는 것이 당연한 것처럼 제시됨
    • 그렇다면 SDD는 어떤 문제 크기와 유형을 위한 것인가?
      • 아마도 아직 매우 불명확한 큰 기능에는 적합하지 않을 것이며, 그런 경우 확실히 더 전문적인 제품 및 요구사항 기술과 연구 및 이해관계자 참여 같은 많은 다른 단계 필요
  • Spec-anchored와 spec-as-source: 과거로부터 배우고 있는가?

    • 많은 사람들이 SDD와 TDD 또는 BDD 사이의 유사점을 그리지만, 특히 spec-as-source의 경우 살펴봐야 할 또 다른 중요한 유사점은 MDD(모델 주도 개발)
    • 경력 초기에 MDD를 많이 사용한 몇 가지 프로젝트에서 작업했으며, Tessl Framework를 시도할 때 계속 이것을 상기하게 됨
      • MDD의 모델은 기본적으로 명세서였지만 자연어가 아닌 맞춤형 UML이나 텍스트 DSL로 표현
      • 이러한 명세서를 코드로 변환하기 위해 맞춤형 코드 생성기 구축
  • MDD와 SDD의 비교

    • 궁극적으로 MDD는 비즈니스 애플리케이션에서 성공하지 못했으며, 어색한 추상화 수준에 있고 너무 많은 오버헤드와 제약 생성
    • 그러나 LLM은 MDD의 오버헤드와 제약 중 일부를 제거하므로, 이제 명세 작성에 집중하고 코드를 생성할 수 있다는 새로운 희망 존재
    • LLM을 사용하면 미리 정의되고 파싱 가능한 명세 언어로 제약받지 않으며, 정교한 코드 생성기를 구축할 필요도 없음
      • 그 대가는 물론 LLM의 비결정성
    • 파싱 가능한 구조는 유효하고 완전하며 일관된 명세를 작성하는 데 많은 도구 지원을 명세 작성자에게 제공할 수 있었던 장점도 있었으며, 이제 이를 잃고 있음
    • spec-as-source, 심지어 spec-anchoring도 MDD와 LLM 모두의 단점으로 끝날 수 있음: 비유연성 그리고 비결정성
    • 과거의 spec-from-code 시도를 살펴보고 오늘날 spec-driven을 탐구할 때 이로부터 배워야 함

결론

  • 개인적으로 AI 지원 코딩을 사용할 때 코딩 에이전트에게 제공할 명세 형태를 신중하게 작성하는 데 시간을 할애하는 경우가 많음
    • 따라서 spec-first의 일반 원칙은 많은 상황에서 확실히 가치 있음
  • 명세 구조화 방법에 대한 다양한 접근 방식은 매우 필요하며, 현재 실무자들로부터 가장 자주 받는 질문 중 하나
    • "메모리 뱅크를 어떻게 구조화하나요?", "AI를 위한 좋은 명세 및 설계 문서를 어떻게 작성하나요?"
  • 그러나 "spec-driven development"라는 용어는 아직 잘 정의되지 않았으며, 이미 의미론적으로 확산됨
    • 최근에는 "spec"을 기본적으로 "상세한 프롬프트"의 동의어로 사용하는 것도 들음
  • 도구에 대한 평가

    • 일부는 기존 워크플로우를 AI 에이전트에게 너무 문자 그대로 제공하려고 시도하여, 궁극적으로 검토 과부하 및 환각 같은 기존 과제를 증폭시킬 수 있음
    • 특히 많은 파일을 생성하는 더 정교한 접근 방식의 경우, 독일어 합성어 "Verschlimmbesserung"(개선하려다 더 나빠지게 만드는 것)을 생각하게 됨
      • 더 좋게 만들려는 시도에서 무언가를 더 나쁘게 만들고 있는 것은 아닌지 의문

Read Entire Article