제 스펙은 다음에 무엇을 해야 할지 알려주지 않았고, 그래서 나만의 SDD 하네스를 만들었습니다
요약
본 글은 AI 에이전트를 활용한 스펙 기반 개발(SDD)의 필요성을 설명하며, 기존 하네스 프레임워크의 한계를 극복하기 위해 직접 제작한 개인 도구에 대해 소개합니다. 이 도구는 프로젝트 내부에서 상태 관리를 가능하게 하고, 의사 코드 스타일의 프롬프트 최적화 및 엄격한 TDD 적용을 통해 개발 효율성을 높였습니다.
핵심 포인트
- AI 에이전트 기반 스펙 기반 개발(SDD) 필요성 제기
- 프로젝트 내부에 상태 관리하는 커스텀 하네스 제작
- 의사 코드 스타일 프롬프트가 자연어보다 성능 및 토큰 효율 우수
- 하나의 질문에는 하나의 파일이라는 원칙을 적용하여 구조화
저는 AI 에이전트를 사용하여 스펙 기반 개발(spec-driven development)을 합니다. 저는 잘 알려진 스펙 기반 하네스들을 사용해 보았고, 결국 저만의 도구를 만들었으며, 몇 달 동안 오직 그것만 사용하고 있습니다. 이 글에서는 왜 제가 저만의 도구가 필요했는지, 그리고 언제 유용한지에 대해 설명합니다.
Repo: [https://github.com/opellen/opengoal]
제 스펙이 답하지 못한 질문
AI 코딩에 빠진 많은 개발자들처럼, 저는 여러 프로젝트를 동시에 정신없이 진행하고 있었습니다. 어느 순간부터 스펙 기반 개발의 필요성을 느끼게 되었고, 잘 알려진 하네스 프레임워크들을 사용했습니다. 하지만 저는 병목 현상에 부딪혔습니다:
"다음에 무엇을 해야 할까?"
스펙은 다음에 무엇을 해야 할지 알려주지 않았습니다.
임시방편으로, 저는 Notion에 프로젝트별 페이지를 만들고 그곳에서 관리했습니다. 하지만 그것은 프로젝트와 분리된 장소였기 때문에 최신 상태로 유지하는 것이 번거로웠습니다. 그래서 저는 프로젝트 내부에 존재하는 상태 관리를 원하게 되었습니다.
제가 직접 만든 이유
저의 SDD 하네스는 취미 프로젝트, 즉 게임 리버스 엔지니어링에서 시작되었습니다. 리버스 엔지니어링은 여러 세션에 걸쳐 많은 분석과 설계를 필요로 하며, 설계와 계획이 끊임없이 뒤집히곤 합니다. 매번 AI 하네스와 브레인스토밍을 하고 스펙을 다시 작성하는 것은 너무 많은 작업이었습니다. 만약 이 과정이 CLI를 통해 실행된다면 더욱 민첩하지 못합니다. 저는 기존 하네스의 프롬프트를 수정하는 것을 생각했지만, 그러면 그들의 업데이트 속도를 따라잡을 수 없었습니다. 그래서 저만의 하네스 프롬프트도 Jekyll과 유사한 방식으로 확장 가능하기를 원했습니다.
다른 이유들도 몇 가지 있었습니다.
AI가 때때로 하네스(harness)의 슬래시 명령어 후반부를 무시하는 경우가 있었습니다. 저는 그 원인이 산문 같은 자연어 스타일로 작성된 긴 텍스트 때문임을 알게 되었습니다. 그래서 프롬프트를 최적화하기 시작했습니다. 저는 의사 코드(pseudocode-style) 방식의 프롬프트가 자연어보다 더 잘 따르며 토큰 사용량도 적다는 연구 결과를 바탕으로 이를 진행했습니다.
- EMNLP 2023: 의사 코드 스타일 프롬프트를 사용했을 때, 자연어 대비 F1 점수가 7점에서 16점 향상되었습니다.
- CodeAgents (2025): 의사 코드로 에이전트 워크플로우를 작성한 결과, 토큰 사용량이 55%에서 87% 감소했으며 성능은 3점에서 36점 향상되었습니다.
강제적인 엄격 TDD(Test-Driven Development)도 또 다른 이유였습니다. 작은 작업에도 큰 작업과 동일하게 엄격한 TDD를 적용해야 했고, 만약 여전히 오류가 남아 있다면 프로세스를 다시 실행해야 했습니다. 그렇게 낭비되는 토큰은 고통스러웠습니다.
하나의 질문에 하나의 파일
제 하네스는 하나의 규칙을 기반으로 합니다: 하나의 질문에는 하나의 파일이 있어야 합니다. 프로젝트에 무언가를 물어보고 싶다면, 그 답은 정확히 하나의 파일에 있습니다.
ROADMAP.md ───────────── 전체 그림에서 내가 어디에 있는가?
CONTEXT.md ──────── 이 프로젝트는 무엇인가?
● GOAL.md ── 지금 나는 무엇을 해야 하는가?
이 구조는 기본적으로 docs 폴더에 유지됩니다. 다른 위치를 선택할 수도 있습니다.
일부 하네스 프레임워크도 비슷한 구조를 가지고 있습니다. 하지만 제 하네스인 OpenGoal은 CLI(Command Line Interface)나 훅(hooks)을 사용하지 않습니다. 순수한 마크다운입니다. 런타임에 추가되는 것이 전혀 없기 때문에 가볍게 작동합니다. 저는 주로 Claude Code에서 이를 사용하지만, Cursor와 Codex를 포함하여 약 20개의 도구에 설치할 수 있습니다.
스펙 기반 하네스 프레임워크는 신중하게 구조화된 스펙을 요구하지만, 이는 작은 작업에는 너무 과도할 수 있습니다. 그래서 OpenGoal은 단순히 목표(goal)만 생성할 수 있습니다. 이 목표를 필요한 만큼 더 작은 조각들로 분할할 수 있으며, 간단한 작업의 경우 설계 문서(design document) 단계를 건너뛸 수도 있습니다. 저는 스펙을 버리지 않았습니다. 작업을 크기에 맞게 작성하며, GOAL.md는
사용자: /opgl:scout
AI: 기존 코드베이스를 찾았습니다. CONTEXT.md는 아직 없습니다.
/opgl:context로 프로젝트 컨텍스트를 설정할까요?
...
토론을 통해 목표에 대한 충분한 컨텍스트가 주어지면, 저는 AI에게 다음과 같이 목표를 작성하도록 요청합니다.
You: /opgl:goal init JWT에서 세션 기반으로 인증 모듈 마이그레이션
AI: ✓ docs/GOAL.md 생성됨 (5개 작업)
그러면 AI는 목표를 더 세분화하거나, 디자인 문서를 작성하거나, 또는 간단한 작업의 경우 디자인 문서 없이 바로 시작할 것을 추천할 수 있습니다.
AI: `/opgl:goal breakdown`을 추천합니다. — 이 작업들에는 여러 숨겨진 단계가 포함되어 있습니다.
AI: `/opgl:design init`을 추천합니다. — 파일 레벨의 결정이 필요한 구현 작업입니다.
AI: `/opgl:go`를 추천합니다. — 이것은 간단한 작업입니다.
작업에 디자인이 필요할 때는, 디자인 문서가 먼저 나옵니다. OpenGoal에서 이 문서는 작업 단위의 명세서(spec) 역할을 합니다.
You: /opgl:design init
AI: ✓ docs/DESIGN.md 생성됨
세션 스토어 선택, 마이그레이션 전략, 롤백 계획 포함
작업 중 중요한 결정이 있을 때, AI는 제 의견을 묻습니다.
You: /opgl:go
AI: 작업 1/5: 세션 스토어 설정... ✓ 완료
작업 2/5: 미들웨어 교체... ✓ 완료
...
장기적인 목표를 처리하고 싶을 때는 로드맵(roadmap)을 작성할 수 있습니다.
You: /opgl:roadmap init
AI: ✓ docs/ROADMAP.md 생성됨
├── M1: 인증 마이그레이션
...
목표 완료 및 일시 중지
목표의 모든 작업이 완료되면, 저는 이를 아카이브(archive)합니다. /opgl:goal archive는 GOAL.md와 DESIGN.md를, 존재한다면 PLAN.md와 CHECKPOINT.md를 docs/archive/goals/로 이동시킵니다. 로드맵이 있다면, 해당 마일스톤도 완료 처리됩니다.
아카이브된 목표는 그 이후에도 계속 사용됩니다. 나중에 해당 부분을 수정하거나 다음 목표를 진행할 때, AI는 아카이브에 저장된 당시의 설계(design), 결정(decisions), 그리고 체크포인트(checkpoints)를 찾아 컨텍스트로 활용합니다. OpenGoal은 아카이브를 자동으로 읽지 않습니다. 아카이브는 고정된 위치에 남아 있으며, CONTEXT.md나 다음 목표의 문서들이 종종 이 아카이브를 가리키기 때문에, 필요할 때 AI가 직접 찾아서 읽게 됩니다.
진행 중인 목표의 상태를 체크포인트로 저장할 수 있습니다. 저는 주로 체크포인트를 압축(compaction)을 준비하거나, 다른 세션 또는 다른 AI 도구에 작업을 인계하기 위해 사용합니다. 체크포인트는 종종 압축 요약본이 놓치는 상세 정보를 보존하고 있습니다. 압축은 전체 대화를 한 번에 줄여버리지만, 체크포인트는 AI가 지금까지 찾은 내용과 다음 단계를 별도로 기록해 줍니다.
You: /opgl:goal checkpoint
AI: ✓ docs/CHECKPOINT.md saved
(세션이 끊겨도 다음에 이어서 작업할 수 있습니다)
자연어 및 기타 기능
매번 명령어를 입력할 필요가 없습니다. 컨텍스트가 명확하면, 자연어만으로도 작동합니다. 추천되는 명령어에 대해서는 'ok'나 'go'로 답변할 수 있고, 'task 6 진행하기(proceed with task 6)'라고 하면 /opgl:go가 실행되며, '진행 상황 저장하기(save progress)'라고 하면 /opgl:goal checkpoint이 실행됩니다.
그 외에도, 제가 오랫동안 직접 사용해 본 경험을 통해 OpenGoal은 목표(goals)와 하위 목표(sub-goals), 백로그(backlog) 등을 일시 중지하고 재개하는 기능을 처리하게 되었습니다. 저는 마크다운만으로 최대한 많은 기능을 끌어냈습니다.
토큰 사용
전반적으로 OpenGoal은 소중한 토큰 사용을 줄이도록 설계되었습니다. CONTEXT.md가 여기서 중요한 역할을 합니다. AI는 사물이 어디에 있는지 미리 알기 때문에 도구 호출(tool calls) 횟수가 적고, 매 세션 시작 시 코드베이스를 재탐색할 필요성이 줄어듭니다. 또한, 후크(hooks)나 MCP 서버가 없으므로 사용하지 않는 도구 정의(tool definitions)가 토큰을 차지하지 않습니다. 함께 설치되는 서브 에이전트 스킬(subagent skill)도 같은 목적을 수행합니다. 메인 에이전트는 작업의 난이도를 기준으로 어떤 모델에 서브 에이전트를 할당할지 결정하며, 스스로 아주 작은 수정 작업을 합니다. 서브 에이전트가 분석 자료를 수집하지만, 실제 분석은 메인 에이전트가 직접 수행합니다. 저는 다른 하네스(harnesses)에서 메인 에이전트가 컨텍스트의 미세한 디테일을 잃어버리는 문제를 겪었습니다.
마크다운만으로 충분한 이유
제가 OpenGoal을 구축하게 된 가장 큰 이유는 이런 생각 때문이었습니다. 우리가 의존하고 싶어 하는 완벽함을 위해 구축된 이 모든 장치들이 AI가 빠르게 발전함에 따라 대부분 불필요해질 수 있고, 그때는 오직 마크다운(markdown)만으로도 충분할 수 있다는 것입니다. 그리고 저는 그 생각이 실현되었다고 생각합니다. 저는 작은 Obsidian 플러그인부터 Notion 스타일의 블록 편집 기능을 갖춘 네이티브 모바일 에디터, 상태 기계 설계자(state machine designer)에 이르기까지 OpenGoal만을 사용하여 다양한 프로젝트를 완료했습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기