본문으로 건너뛰기

© 2026 Molayo

Qiita헤드라인2026. 06. 15. 06:44

【AI 주도 개발】 OpenSpec을 기존 프로젝트에 도입했을 때 했던 일 정리

요약

기존 스크럼 개발 프로세스를 유지하면서 OpenSpec을 도입하여 AI 주도 개발을 강화한 사례를 정리했습니다. 기존 브랜치 전략과 워크플로우를 변경하지 않고도 AI 에이전트 활용도를 높일 수 있는 방법론을 다룹니다.

핵심 포인트

  • 기존 브라운필드(Brownfield) 프로젝트에 도입하기 용이한 설계
  • 스크럼 개발 플로우와 OpenSpec 레이어의 자연스러운 결합
  • 문서 기반의 합의 과정을 통한 AI 컨텍스트 관리 최적화
  • Claude Code 및 GitHub Copilot 등 다양한 에이전트와의 호환성

이미 일정량의 코드가 있는 기존 개발 팀에 OpenSpec을 도입했을 때 했던 일과, 그 후 사용해 보며 느낀 점을 정리했습니다.

이번에 OpenSpec을 도입한 프로젝트는 신규 프로젝트가 아니라, 이미 스크럼 (Scrum)을 채택하여 개발을 진행하고 있는 팀이며, 코드도 어느 정도 양이 완성되어 있는 프로젝트입니다. 기존의 개발 플로우나 리포지토리 (Repository) 구성에 대해 대략적으로 설명하자면 다음과 같습니다.

  • 1주일 단위의 스프린트 (Sprint)로 개발을 진행하는 스크럼 (Scrum) 개발
  • PBI (Product Backlog Item) 기반의 태스크 (Task) 관리
  • 스프린트 (Sprint)마다 대응할 PBI를 결정
  • PBI의 구현 방침은 개발 팀 전원이 합의한 후 Wiki에 정리하여 구현에 착수
  • 구현은 개인별로 진행하기도 하고, 페어 프로그래밍 (Pair Programming)이나 모브 프로그래밍 (Mob Programming)으로 진행하기도 함
  • 코드 리뷰 (Code Review)는 PR (Pull Request) 기반으로 수행
  • 리포지토리 (Repository)는 main 브랜치와 개발 시 생성하는 feature 브랜치 구성 (develop 브랜치는 없음)

AI를 사용한 개발 (Claude Code나 GitHub Copilot, 기술 및 프롬프트 (Prompt) 준비)은 하고 있었지만, 이를 강화하면서도 기존의 개발 플로우나 리포지토리 (Repository)의 브랜치 구성 등을 바꾸지 않고 도입할 수 있는 도구를 찾고 있었습니다.

또한, 이미 가동 중인 Web 애플리케이션의 코드가 있기 때문에, 신규 개발이 아니더라도 도입하기 쉬운 도구가 바람직하다고 생각했습니다.

그러한 조건 속에서 OpenSpec이 좋아 보인다고 느낀 이유는 주로 다음 5가지입니다.

  • propose부터 archive까지 순서대로 실행하기만 하면 되어 외울 것이 적고, 도입 장벽이 낮았다는 점

  • AI 주도 개발용 개발 플로우로 변경하지 않고, 스크럼 (Scrum) 개발의 스프린트 (Sprint) 안에서 기존의 브랜치 운용이나 PR 기반의 개발 플로우를 크게 바꾸지 않고 넣을 수 있었다는 점

  • OpenSpec의 공식 문서에도 "built for brownfield not just greenfield"라고 명시되어 있는 것처럼, 기존 리포지토리 (Repository)로의 도입을 의식한 설계가 되어 있다는 점.

  • openspec/config.yaml에 기존 문서나 운용 규칙을 모아둠으로써, AI에게 읽히고 싶은 문맥 (Context)을 리포지토리 (Repository) 측에 둘 수 있다는 점

  • OpenSpec의 개발 플로우를 따름으로써 "어떤 명령어를 사용하여 무엇을 생성할지"가 팀 내에서 통일된다는 점. 개별 멤버가 독자적으로 프롬프트 (Prompt)를 고안하지 않아도 동일한 흐름으로 진행할 수 있기 때문에, AI 활용 수준이 개인의 기술에 의존하기 어려워질 것을 기대했습니다.

  • proposal.mdtasks.md의 형태로, 구현 전의 합의 내용을 파일로 남길 수 있다는 점

  • 팀에서 구현 방침을 먼저 합의한 후 구현에 들어가는 플로우가 있었기 때문에, /opsx:propose로 생성되는 proposal.md, design.md, tasks.md가 그 합의의 장으로서 그대로 사용될 수 있었습니다. 리포지토리 (Repository)에 합의 내용이 남으므로 리뷰 (Review) 등에서도 확인하기 쉽고, 나중에 다시 볼 때도 편리할 것 같다고 느꼈습니다.

  • Claude Code와 GitHub Copilot 양쪽에서 유사한 흐름으로 사용할 수 있어, 에이전트 (Agent)를 넘나들며 운용하기 쉬웠다는 점

특히 좋았던 점은, AI 주도 개발을 강화하면서도 갑자기 팀의 방식을 전부 바꾸지 않아도 되었다는 것입니다. 지금 있는 스크럼 (Scrum) 개발의 흐름에 explore, proposal, apply, archive 레이어를 추가하는 느낌으로 넣을 수 있었기에, 도입 부하를 낮게 억제할 수 있었다고 생각합니다.

도입한 이야기에 들어가기에 앞서, OpenSpec이 어떤 흐름으로 동작하는지만 간단히 언급해 두겠습니다.

OpenSpec은 AI에게 갑자기 구현을 시키기보다는, 먼저 변경 내용을 change로 분리하고, 그 change에 대해 제안, 구현, 반영을 진행하는 형태의 도구입니다. 작성한 change는 개발 중에만 사용되며, 최종적으로 spec (정식 사양)으로 반영되는 이미지입니다.

대략적인 흐름은 다음과 같습니다.

  • /opsx:propose로 change를 만들고, proposal.md, design.md, tasks.md 등의 계획용 파일과 이 변경에 의한 delta spec (spec의 차분)을 생성함
  • 사람이 그 내용을 리뷰 (Review)하여 방침을 확정함
  • /opsx:apply로 tasks에 따라 구현을 진행함
  • /opsx:archive로 change의 내용을 본체의 spec에 반영하여 이력화함

그림으로 나타내면 이런 이미지입니다.

이때 중요한 점은 OpenSpec에는 「작업 중인 변경 사항 (change)」과 「현재의 정식 사양 (spec)」이라는 두 개의 계층이 있다는 것입니다.

openspec/changes/ 하위는 현재 진행 중인 change의 작업 공간입니다.
openspec/specs/ 하위는 현시점에서의 정식 사양입니다.

changes 측에 있는 spec은 해당 change에서 추가하거나 변경하고 싶은 내용만을 작성하는 차분 사양, 이른바 delta spec입니다. 최종적으로 /archive를 하면, 그 차분이 openspec/specs/ 측으로 반영됩니다.

openspec/
├── changes/
│ └── <change-name>/
...

OpenSpec에서는 이 specs에 코드의 동작을 축적해 나감으로써, 후속 작업에서는 "현재 코드는 이러한 사양으로 되어 있다"라는 것을 AI에게 이해시키면서 진행할 수 있게 됩니다.

OpenSpec을 사용하기 시작하기에 앞서, 우선 OpenSpec을 설치하고, 리포지토리(repository)에 초기 설정을 넣은 뒤, 기존 코드에서 사양을 추출하여 openspec/specs/에 넣는 작업까지 수행했습니다.

리포지토리에 OpenSpec을 넣기 전에, 먼저 개발 단말기에 OpenSpec을 설치해야 합니다. 설치 방법은 공식 설치 가이드를 따라주세요. 사용하기 전에 수행한 설정으로서, OpenSpec은 텔레메트리 (telemetry) 수집을 비활성화할 수 있으므로 저희는 비활성화했습니다. 비활성화 시 설정하는 환경 변수는 다음 두 가지입니다.

OPENSPEC_TELEMETRY=0

DO_NOT_TRACK=1

둘 중 하나를 설정하면 OpenSpec의 텔레메트리를 비활성화할 수 있습니다 (하지만 둘 다 설정했습니다). 실제 설정 명령어나 최신 안내는 공식 리포지토리의 Telemetry 섹션을 참조해 주세요.

도입하려는 리포지토리로 이동하여, 먼저 openspec init을 실행합니다. 이를 통해 OpenSpec이 사용하는 openspec/ 디렉토리와 각 AI 에이전트 (agent)가 참조하는 OpenSpec의 명령어 및 스킬 (skill)이 생성됩니다.

openspec init

자세한 내용은 공식 문서의 Quick Start 섹션을 참조해 주세요.

OpenSpec은 초기화만 해도 사용할 수 있지만, 각 명령어의 동작이나 AI에게 이해시키고 싶은 프로젝트의 문맥 (context)을 openspec/config.yaml에 작성해 나감으로써 더욱 효과적으로 사용할 수 있습니다.

저희의 설정에서는 다음과 같은 정보를 넣었습니다.

  • 기술 스택 (tech stack)
  • 어떤 계층이 어떤 계층에 의존해도 되는지
  • 기존 아키텍처 (architecture) 자료 및 코딩 규약
  • 테스트 방침
  • spec을 어떤 단위로 나눌지

공개용으로 조금 흐릿하게 표현하면 이런 이미지입니다. 사용하면서 점진적으로 업데이트하는 방식도 문제없겠지만, 처음에 어느 정도 넣어두면 AI가 프로젝트의 문맥을 이해하기 쉬워집니다.

openspec/config.yaml에서 설정할 수 있는 주요 항목으로는 contextrules가 있습니다. context는 모든 지시에 공통적으로 AI에게 이해시키고 싶은 프로젝트의 문맥을 넣는 곳이며, rules는 proposal이나 specs, tasks 등 생성하는 대상마다 개별적으로 규칙을 지정할 수 있는 곳으로, 기본값으로는 proposal, specs, design, tasks를 지정할 수 있습니다.

schema: spec-driven
tools:
- claude
...

OpenSpec에서는 openspec/specs/ 이하에 해당 리포지토리의 동작을 거킨 (Gherkin) 표기법으로 남겨 나갑니다. 이 specs의 구성은 처음에 결정해 두는 것이 운용하기 편할 것이라고 생각합니다.

아무것도 지정하지 않으면, specs/ 하위에 md 파일이 나열되는 구성이 되거나 하나의 파일에 방대한 양이 작성되어 관리가 어려워지는 경우가 있습니다.

그래서 저희는 독립된 사이트 (feature) 단위로, 그리고 그 안에서 책무 (responsibility) 단위로 디렉토리를 나누는 방침을 세웠습니다.

openspec/specs/
└── <feature>/
    ├── page/
    ...

이렇게 나누기로 한 이유는 세 가지입니다.

  • 화면 사양과 비즈니스 규칙 (business rule), 그리고 외부 연동의 관심사를 분리하여 관리하고 싶었다
  • 개발 시 태스크 (task)의 입도 (granularity)에 맞춘 단위로 나누고 싶었다
  • spec의 컨플릭트 (conflict)를 줄이고 싶었다

이것이 베스트라기보다는, 팀의 개발 스타일이나 프로젝트의 내용에 맞춰 결정하는 것이 좋다고 생각합니다. 결정했다면, openspec/config.yaml에 규칙으로 적어둡니다.

신규 개발과 달리, 기존 리포지토리(repository)에서는 첫 번째 spec이 비어 있습니다. 이 부분은 약간의 궁리가 필요했습니다.

저희는 앞서 언급한 openspec/config.yaml 설정을 마친 후, 먼저 /opsx:explore를 통해 "기존 코드에서 spec을 만들고 싶다"라고 지시하면서, 코드뿐만 아니라 Wiki나 머지(merge)된 PR(Pull Request) 등도 참조하도록 지시에 추가하여 정보 수집과 spec 생성을 수행했습니다.

흐름은 다음 4단계입니다.

  • /opsx:explore로 기존 코드와 기존 자료의 관련 부분을 조사하게 함 (과거의 PR이나 Wiki에서 관리하는 부분을 지정)
  • /opsx:propose로 proposal.md, design.md, tasks.md를 생성
  • 사람이 proposal을 리뷰하고 수정
  • /opsx:apply로 spec을 생성하고, 마지막으로 /opsx:archive로 반영

/opsx:explore/opsx:propose 타이밍에는 가급적 성능이 좋은 모델을 사용하는 것이 좋을지도 모릅니다. 또한, GitHub MCP나 Atlassian MCP 등을 호출할 수 있도록 하여 조사 중에 필요한 정보를 가져올 수 있게 해두면 좋을 것 같습니다. spec의 구조를 바꾸기 쉬운 것은 이 단계이므로, 생성된 결과가 마음에 들지 않는다면 지우고 다시 하는 것도 방법이라고 생각합니다.

도입 후 개발 멤버들로부터 나온 의견으로는, 경미한 변경까지 전부 OpenSpec에 올리는 것은 무겁지 않을까 하는 것이 있었습니다.

그래서 OpenSpec을 사용해야 하는 변경과 그렇지 않은 변경을 정리했습니다.

OpenSpec은 거킨(Gherkin) 표기법으로 코드의 동작(behavior)을 spec화해 나가는 스타일입니다.

이 때문에 spec으로 관리하지 않는 것(동작을 변경하지 않는 것)은 OpenSpec을 사용하지 않아도 문제없습니다.

정리한 결과는 다음과 같습니다.

변경 종류OpenSpec비고
오타(typo) 수정임의동작에 영향 없음
...

결국 대상 코드나 문서에 spec 파일이 존재하는지 여부와, 그 변경이 동작에 영향을 주는지 여부로 판단하고 있습니다. 따라서 환경에 따라 위의 필수·임의 사항은 바뀔 수도 있습니다. 또한, 나중에 spec 파일을 변경에 맞춰 추종(follow)하게 할 수도 있으므로, 그렇게까지 신경질적으로 대응할 필요는 없다고 생각합니다.

도입 전부터 spec 파일의 컨플릭트(conflict)는 우려하고 있었습니다. 그래서 spec 디렉토리는 feature와 책임(responsibility)에 따라 디렉토리를 나누고, 그 안에서도 여러 파일로 나누는 구성으로 하여 컨플릭트 가능성을 줄이는 궁리를 했습니다. 하지만 그럼에도 가까운 코드를 병렬로 개발했을 경우에는 spec의 컨플릭트가 발생하는 경우도 있었습니다. 다만, OpenSpec의 spec 파일은 다음과 같은 거킨(Gherkin) 표기법이라서, 소스 코드의 복잡한 충돌보다는 해소하기 쉽다는 인상이었고 큰 부담은 아니었습니다.

#### Scenario: 인증 정보로 로그인 성공
- GIVEN 사용자가 로그인 화면을 열고 있다
- WHEN 유효한 이메일 주소와 비밀번호를 입력하고 로그인 버튼을 누른다
...

/archive로 spec이 업데이트되면 당연히 PR의 차이(diff)에 spec 파일의 변경이 포함됩니다. 다만 저희 팀에서는 이 부분의 리뷰는 가볍게 훑어보는 정도로 하고, 코드와 같은 입도(granularity)로 리뷰하지는 않습니다.

이유는 /archive 이후의 spec은 AI가 자동 생성하는 것이며, 동작에 직접적인 영향을 주는 변경이 아니라 사람이 참조하여 사용하는 문서도 아니기 때문입니다. spec의 내용이 구현과 일치하는지는 어느 정도 AI에게 맡기고 있으며, 사람이 제대로 확인하는 것은 /propose 단계에서 생성되는 proposal.md, design.md, tasks.md로 하고 있습니다.

그렇다고는 해도, spec과 코드가 조금씩 어긋날 리스크는 있습니다. 장래에는 후술할 /opsx:verify나 전용 스킬을 준비하여 spec과 코드의 괴리를 검지할 수 있도록 하고 싶지만, 현재로서는 아직 되지 않았습니다.

팀 전체적으로는 아직 표준화하지 않았지만, 개인적으로 시도해 보아서 좋았던 것이 /opsx:verify입니다.

입니다. OpenSpec의 기본 설정에서는 활성화되어 있지 않은 명령이지만, 확장 워크플로우 (extension workflow)를 활성화하면 사용할 수 있게 됩니다. OpenSpec의 확장 워크플로우에서는 /opsx:apply 다음에 /opsx:verify를 끼워 넣을 수 있습니다. 공식 문서(official documentation)를 보면, verify는 다음 세 가지를 확인하도록 설계되어 있습니다.

  • Completeness (완결성)
  • Correctness (정확성)
  • Coherence (일관성)

요컨대, "tasks(작업)는 완료되었는가", "구현이 spec(명세)의 의도와 일치하는가", "설계의 정합성이 깨지지 않았는가"를 확인해 줍니다.

모든 확장 명령을 넣으면 조금 무거워지지만, verify만이라도 추가할 가치는 충분해 보였습니다. 특히, archive(아카이브) 전의 셀프 체크(self-check) 용도로는 상당히 사용하기 편리합니다.

저희 팀은 main 브랜치에서 직접 토픽 브랜치(topic branch)를 따는 GitHub Flow 방식의 운영을 하고 있습니다. 이 경우, 여러 토픽 브랜치가 병행하여 진행되면 spec 파일의 충돌(conflict)이 발생할 가능성이 있습니다. feature와 책임(responsibility)에 따라 spec 디렉토리를 세분화함으로써 충돌 가능성을 줄일 수는 있지만, 동일한 기능을 여러 명이 동시에 다루는 경우에는 피할 수 없는 경우도 있습니다.

현재는 아직 시도해보지 않았지만, 개선책으로 생각하고 있는 것은 다음 두 가지입니다.

  • Git Flow처럼 develop 브랜치를 사이에 두는 구성(main ← develop ← topic)으로 하여, develop에 머지(merge)된 후에 archive하는 운영 방식
  • CI(지속적 통합)를 사용하여 main으로의 반영 후에 자동으로 archive할 수 있도록 하는 방식

어느 쪽이든, archive 타이밍을 브랜치의 머지 플로우(merge flow)와 맞춤으로써 충돌 리스크를 더욱 줄일 수 있을 것이라고 느꼈습니다.

OpenSpec은 명령어를 순차적으로 실행할 뿐이라서 외워야 할 것이 적고, 기존의 스크럼(Scrum) 개발 플로우를 크게 바꾸지 않고도 원활하게 도입할 수 있었습니다. 반면, 초기 도입 시의 spec 디렉토리 구성은 나중에 변경하기 어렵기 때문에, 처음에 잘 설계해 두는 것이 중요하다는 것을 느꼈습니다.

좋았던 점을 정리하면 다음과 같습니다.

  • openspec/config.yaml을 팀과 함께 키워나가는 형태를 취할 수 있어 스크럼 개발과의 궁합이 좋았다.
  • "어떤 명령어를 사용하여 무엇을 생성할 것인가"가 팀 내에서 통일됨으로써, AI 활용도가 개인의 역량에 의존하는 정도가 낮아졌다.
  • 제안과 구현 사이에 인간의 리뷰(human review)를 넣기 쉬워져서, AI 구현 후의 재작업(rework)이 줄어들었다.

작은 변경사항까지 전부 OpenSpec에 태우려고 하면 부하가 커지므로, 동작(behavior)이 변하는지 여부를 기준으로 OpenSpec을 사용할 범위를 미리 정해두는 것을 추천합니다.

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0