같은 요청을 여러 번 고쳐 던져도 결과물이 자꾸 어긋난다면 원인은 모델 성능이 아니라 명세의 부재일 수 있습니다. 즉흥적으로 기능을 요청하고 오류가 날 때마다 대화로 수습하는 방식은 대화 이력이 컨텍스트 창을 뒤섞인 기록으로 채우고, 그만큼 오류율과 기술 부채를 함께 끌어올립니다. 이 방식으로 만든 코드는 버튼 하나 같은 단일 파일 부품을 넘어서기 어렵고, 오래 유지할 소프트웨어로 확장되지 않습니다. Spec-driven development는 여기서 출발합니다. 명세를 일회성 대화가 아니라 버전 관리되는 영구적인 기술 산출물로 취급하고, 무엇을 왜 만드는지를 어떻게 만드는지와 분리해 문서에 고정합니다.
즉흥 prompt가 무너지는 지점
대화형으로 코드를 얻는 방식은 언어 모델의 컨텍스트 창이 언젠가 열화된다는 사실을 외면합니다. 대화 이력을 프로젝트 기억으로 쓰는 것은 함정입니다. 세션이 길어질수록 앞선 결정은 흐려지고, agent는 환각과 반복 오류를 내놓기 시작합니다. 설계 결정을 모델의 즉흥적 선택에 맡기면 유지보수하기 어려운 코드베이스와 일관성 없는 제품이 남습니다. 단순한 스크립트나 화면 부품 하나를 만들 때는 즉흥적 prompt로도 충분하지만, 그 방식은 장기 프로젝트로 확장되지 않습니다.
명세를 먼저 쓰는 쪽은 반대입니다. agent가 20~30분 동안 자율적으로 코드를 작성한다면 이는 사람이 여러 시간 붙잡고 일한 양에 해당합니다. 그 앞에 3~4분을 들여 명세를 정리하면 결과를 예측할 수 있습니다. Spec-driven development가 내세우는 이점도 여기에 맞닿아 있습니다. 작은 spec 수정으로 거대한 코드 변경을 통제할 수 있고, 세션과 세션 사이의 컨텍스트 열화를 없앨 수 있으며, 의도한 바가 구현에 반영되는 충실도가 올라갑니다.
spec 한 문장이 하류에서 증폭되는 힘은 큽니다. 기술 스택 문서에서 데이터베이스 선택을 바꾸는 한 줄 수정은 애플리케이션 전반의 수백 줄 코드를 함께 바꿉니다. 그래서 명세는 사람 개발자, 비기술 이해관계자, 자율 agent를 잇는 명시적 계약이 됩니다. 컴파일러가 소스 코드를 기계어로 옮기듯, agent는 사람이 읽는 마크다운 명세를 소스 코드로 옮기는 변환기 역할을 합니다. 다만 일반 챗봇과 달리 코딩 agent는 작업 공간을 살피고 터미널 명령을 실행하고 파일을 고치기 때문에 명확한 설계 청사진이 필요합니다.

▲ 대화 이력과 명세의 차이
프로젝트 헌법 세 문서
워크플로는 두 계층으로 나뉩니다. 프로젝트 수준에서 방향을 정하고, 기능 수준에서 반복합니다. 프로젝트 수준에서 만드는 것이 헌법입니다. 미션, 기술 스택, 로드맵 세 문서로 구성되며, 개별 기능을 시작하기 전에 프로젝트 전체에 적용될 기준과 경계를 정합니다.
미션, 기술 스택, 로드맵
미션 문서에는 프로젝트가 무엇을 위해 존재하고 누구를 위한 것인지, 어떤 어조를 취할지를 담습니다. 예제로 드는 프로젝트는 컨텍스트 창이 좁아진 데 답답함을 느끼거나 prompt 피로를 호소하는 AI agent를 치료하는 풍자적인 클리닉 애플리케이션이며, 이런 유쾌한 어조가 미션 문서에 명시됩니다. 기술 스택 문서는 서버 사이드 TypeScript, Hono와 JSX 렌더링, 개발 서버, SQLite와 better-sqlite3 같은 선택을 확정합니다. 로드맵 문서는 각 단계가 한 개에서 세 개의 작은 기능만 담는 나노 단계로 쪼개집니다. 단계가 작아야 구현 주기가 짧고 검토 가능한 크기로 유지됩니다.
문서는 agent가 마음대로 쓰게 두지 않습니다. 이해관계자 요구사항을 먼저 주고, 구조화된 선택지 메뉴를 제시하는 질문 도구를 쓰게 한 뒤 사람이 답을 고릅니다. 이렇게 얻은 세 파일은 전용 specs 디렉터리에 저장하고, 변경 내역을 사람이 확인한 뒤 커밋합니다. 명세 수준의 변경은 하류에서 수백 줄의 구현 코드로 불어나기 때문에 spec 검토는 생략할 수 없습니다. 반대로 변수 이름 같은 저수준 구현 세부까지 명세에 적는 것은 token을 낭비하고 agent의 문제 해결 능력을 묶습니다. 목표와 대상, 제약은 분명히 적고 구현 방법은 agent의 추론에 남겨 둡니다.

▲ 프로젝트 헌법 세 문서
기능 단위 루프: 명세, 구현, 검증
기능 수준의 작업은 명세, 구현, 검증 세 단계를 돕니다. 그리고 다음 기능으로 넘어가기 전에 재계획 단계를 둡니다. 개발자의 자리는 수석 아키텍트이자 감리자입니다. 도면을 그리고 공사를 점검하고 결과물을 승인하되, 모든 줄을 직접 통제하지는 않습니다.
명세 단계
기능 명세를 시작하기 전에 대화 이력을 비우는 명령을 실행합니다. 세션에 남은 옛 맥락을 지워 agent가 헌법에서만 문맥을 가져오게 만드는 것입니다. 이어서 기능 브랜치를 만들고, 타임스탬프가 붙은 디렉터리에 요구사항 문서, 계획 문서, 검증 문서를 생성합니다. 이때 agent는 프레임워크 버전 고정 여부, 엄격한 타입 검사 적용, 검증 기준 같은 것을 되묻습니다. 사람이 개입할 지점도 있습니다. 계획 문서에 홈 페이지 자리표시자 컴포넌트와 라우트를 추가하라고 지시하고, 계획 문서의 작업 그룹과 검증 문서의 수용 기준을 함께 갱신하게 합니다. 범위 경계와 의존성, 테스트 조건은 확실히 못 박되 사소한 변수명까지 지시하지는 않습니다.
구현 단계
구현은 계획 문서의 남은 작업 그룹을 한 번에 실행하라는 단일 prompt로 시작할 수 있습니다. 프레임워크 설치, 설정 파일 구성, 스크립트 갱신, 서버 진입점 작성, 홈 컴포넌트 생성이 이어집니다. 데이터베이스 마이그레이션처럼 민감한 코드는 작업 그룹을 하나씩 처리하는 편이 낫지만, 스캐폴딩 수준의 작업은 묶어서 실행해도 무리가 없습니다. 마무리로 타입 검사를 돌리고 서버를 띄운 뒤 로컬 주소로 요청을 보내 응답을 확인합니다.
검증 단계
agent가 성공했다고 보고했다고 해서 바로 병합해서는 안 됩니다. 커밋 내역에서 생성된 파일을 사람이 읽어야 합니다. 이 과정에서 홈 컴포넌트 하나에 헤더, 본문, 푸터가 모두 들어 있는 식의 구조 문제가 드러나기도 합니다. 이런 단순한 재구성은 agent에 맡기는 대신 IDE의 리팩터링 도구로 직접 컴포넌트를 분리할 수 있습니다. 주의할 점은 코드만 고치고 명세를 두면 드리프트가 생긴다는 것입니다. 문서와 코드가 어긋나기 시작하면 이후 agent의 판단 근거가 흔들립니다. 그래서 수동 리팩터링 직후 계획 문서, 요구사항 문서, 검증 문서를 실제 코드에 맞게 갱신하도록 요청합니다. 검사와 엔드포인트 확인까지 통과하면 로드맵에 해당 단계 완료를 표시하고 기능 브랜치를 스쿼시 병합합니다.
재계획과 대규모 확장
기능과 기능 사이에는 멈춰서 구조 건전성을 점검하는 재계획 단계를 둡니다. 이때를 위해 별도의 재계획 브랜치를 만듭니다. 예를 들어 모든 후속 단계에 적용할 테스트 프레임워크를 도입하며 기술 스택 문서를 갱신하고, 테스트 스크립트와 초기 단위 테스트를 추가해 회귀가 없음을 확인합니다. 제품 쪽에서 사용자의 40%가 모바일로 접속한다는 피드백이 오면, 재계획 단계에서 viewport meta tag와 반응형 CSS를 표준으로 못 박습니다.
반복 작업을 자동화하는 방법도 있습니다. 변경 로그 생성기 같은 스킬을 만들어 두면 커밋 로그에서 날짜별 기록을 뽑아 마크다운 요약을 만들고 변경 로그 파일을 자동으로 커밋합니다. 스킬은 파일과 설정을 갖춘 재사용 단위이며, agent는 스킬 설명을 읽고 언제 호출할지 스스로 판단합니다. 다만 외부 스킬은 임의의 셸 명령을 실행할 수 있으므로 설치 전에 내용을 확인해야 합니다.
기능을 크게 묶는 실험도 가능합니다. 레이아웃, 데이터베이스, agent와 질환 카탈로그를 하나의 기능으로 통합하거나, 여러 단계를 한 브랜치에 모아 열 개 작업 그룹짜리 계획을 한 번에 실행할 수도 있습니다. 이때 코드 검토가 부담이 됩니다. 밀집한 코드 변경을 한꺼번에 읽는 과정에서 오는 인지적 피로, 이른바 AI 피로를 줄이려면 계획 단계와 기능 단계의 경계를 지키고, 컨텍스트를 자주 비우고, 커밋을 작게 나눠야 합니다.
검토 자체를 여러 관점으로 나눌 수도 있습니다. TypeScript 코드 리뷰, 데이터베이스 구조, HTML·접근성 검토를 각각 맡는 병렬 subagent를 띄우면 실제 문제가 드러납니다. 예를 들어 SQLite에서 외래 키 제약이 기본적으로 꺼져 있어 이를 켜는 설정이 빠진 점이나 불필요한 런타임 의존성이 지적되고 자동으로 수정되기도 합니다. 여러 단계를 한 번에 구현한 뒤에는 결과물을 원래 명세와 대조하는 역방향 검증을 돌려, 잘못된 입력에 400 대신 200 상태 코드를 돌려주는 식의 간극을 찾아냅니다.
기존 코드베이스에 적용하기
Spec-driven development는 새로 시작하는 프로젝트에만 맞는 방법이 아닙니다. 명세 디렉터리 없이 코드와 개략적인 할 일 목록만 있는 저장소에서도 시작할 수 있습니다. agent에게 코드베이스를 살피고 설정 파일과 소스를 분석하게 한 뒤 헌법을 역설계하게 합니다. 프로젝트 관례에서 기술 선택을 뽑아 기술 스택 문서로 만들고, 목표를 미션 문서로 정리하고, 할 일 목록의 항목을 로드맵 단계로 바꿉니다. 역설계한 헌법을 커밋한 뒤에는 새 프로젝트와 동일하게 기능 명세와 구현을 진행합니다.
도구 생태계와 교체 가능성
spec이 특정 agent의 대화 기록이 아니라 버전 관리되는 마크다운 파일에 있으면 도구 선택의 자유가 생깁니다. Claude Code로 만든 프로젝트와 스킬을 OpenAI Codex CLI로 옮겨 동일한 워크플로를 실행할 수 있습니다. 편집기와 agent를 연결하는 개방형 표준도 등장했습니다. 언어 서버 프로토콜을 본떠 만든 agent 클라이언트 프로토콜은 편집기와 agent 사이의 통신을 형식화해, 여러 IDE가 여러 agent를 플러그 앤 플레이로 붙일 수 있게 합니다.
도구 통합의 무게중심도 옮겨가고 있습니다. 무거운 프로토콜 서버보다 token 효율이 좋고 설정이 단순한 CLI 기반 도구를 선호하는 흐름이 뚜렷합니다. 문서 조회 CLI를 붙여 두면 필요한 순간에만 최신 패키지 문서를 가져와 컨텍스트를 오염시키지 않습니다. 중첩 조인 문법을 물었을 때 추측 대신 공식 문서를 참조하는 식입니다. 확정되지 않은 조사와 라이브러리 비교 검토는 별도의 백로그 디렉터리에 쌓아 두고 활성 로드맵에는 넣지 않습니다.
코딩 agent의 benchmark 순위는 매주 흔들립니다. 그래서 개발 절차를 특정 모델에 고정하는 것은 위험합니다. 명세와 스킬을 열린 형식으로 관리하는 것이 곧 위험 관리입니다.
정리하며: 오늘 할 일
Spec-driven development의 핵심은 생성형 AI를 예측 불가능한 도구에서 신뢰할 수 있는 개발 파트너로 바꾸는 규율에 있습니다. 무엇을 왜 만드는지, 어떤 제약이 있는지를 버전 관리되는 문서로 분리해 두면 개발자는 설계의 통제권을 쥔 채 agent의 실행 속도를 그대로 활용할 수 있습니다. 기능 루프마다 사람이 검토하는 감리자 역할을 유지하고, 단계 사이에 재계획을 넣어 구조를 갱신하는 것이 유지보수 가능한 결과물로 가는 길입니다.
오늘 바로 할 일은 세 가지입니다. 첫째, 진행 중인 프로젝트의 미션, 기술 스택, 로드맵을 각각 한 문서로 정리합니다. 둘째, 다음 기능 하나를 골라 요구사항과 계획, 검증 문서를 만들어 보고 구현 전에 컨텍스트를 비우는 습관을 들입니다. 셋째, 코드를 수동으로 고쳤다면 같은 시점에 명세도 갱신해 드리프트를 남기지 않습니다.