Jeremy

3개 프로젝트의 교훈을 npm 패키지 하나에 담기까지

18 min readEnglish

들어가며

이전 글에서 3개 프로젝트를 거치며 에이전트 시스템을 구축한 과정을 다뤘다. 오케스트레이터, 파일 소유권 매트릭스, 게이트 시스템, 스킬 패키지 — 프로젝트마다 반복적으로 만들어야 했던 것들이다.

문제는 새 프로젝트를 시작할 때마다 이 시스템을 처음부터 다시 구축해야 했다는 점이다. 에이전트 정의 파일 8개를 손으로 쓰고, 스킬을 복사하고, 파일 소유권을 설정하고. 프로젝트 C의 세팅에 반나절이 걸렸을 때 생각했다 — "이걸 도구로 만들면 어떨까?"

그렇게 create-agent-system이 태어났다.

문제: "매번 처음부터"

이전 글에서 최종 형태로 정리된 워크플로우는 꽤 정교했다. 하지만 그 정교함이 곧 진입 장벽이었다.

새 프로젝트를 시작할 때 해야 하는 일:

  1. 에이전트 정의 파일 8개 작성 — PO/PM, 아키텍트, CTO, 디자이너, 테스트 작성자, 프론트엔드 개발자, 백엔드 개발자, QA 리뷰어. 각각의 역할, 담당 디렉토리, 사용할 스킬을 명시해야 했다.
  2. 스킬 파일 복사-붙여넣기 — 이전 프로젝트에서 검증된 스킬을 복사하되, 새 프로젝트의 기술 스택에 맞게 수정.
  3. 파일 소유권 매트릭스 수동 설정 — 어떤 에이전트가 어떤 디렉토리를 소유하는지 정리.
  4. CLAUDE.md 작성 — 프로젝트 컨벤션, 기술 스택, 워크플로우 규칙.
  5. settings.json 설정 — Agent Teams 활성화, 모델 설정.

거기에 더 근본적인 문제가 있었다. Claude Code의 공식 문서는 빠르게 바뀐다. 에이전트 정의에 쓸 수 있는 필드가 추가되거나, 스킬 포맷이 달라지거나. 한 달 전에 만든 에이전트 프롬프트가 이미 구식이 되는 일이 생겼다. 이전 프로젝트에서 복사해온 설정이 최신 스펙과 맞는지 일일이 확인할 방법이 없었다.

해결: Scaffold Once, Stay Up to Date Forever

create-agent-system의 핵심 철학은 한 문장으로 요약된다:

한 번 생성하고, 영원히 최신 상태를 유지한다.

기존 스캐폴더들(create-react-app, create-next-app 등)은 "생성 후 방치" 모델이었다. 초기 보일러플레이트를 만들어주지만, 이후 프레임워크가 바뀌어도 생성된 코드는 그대로다. 사용자가 알아서 따라가야 한다.

create-agent-system은 다르게 접근했다. 공식 문서를 SSOT(Single Source of Truth)로 삼는다. 번들된 /sync-spec 스킬이 최신 Claude Code 공식 문서와 현재 설정을 비교 검증해준다. 생성 시점뿐 아니라 이후에도 스펙 변경을 따라갈 수 있는 구조다.

30초 체험

설치와 실행은 한 줄이다:

npx create-agent-system

인터랙티브 모드가 실행되면서 프리셋, 프로젝트 이름, Claude Code 자동 실행 여부를 물어본다. 질문에 답하면 이런 구조가 생성된다:

your-project/
├── CLAUDE.md
└── .claude/
    ├── agents/
    │   ├── po-pm.md
    │   ├── architect.md
    │   ├── cto.md
    │   ├── designer.md
    │   ├── test-writer.md
    │   ├── frontend-dev.md
    │   ├── backend-dev.md
    │   └── qa-reviewer.md
    ├── skills/
    │   ├── scoring/SKILL.md
    │   ├── visual-qa/SKILL.md
    │   ├── tdd-workflow/SKILL.md
    │   ├── adr-writing/SKILL.md
    │   ├── ticket-writing/SKILL.md
    │   ├── design-system/SKILL.md
    │   ├── cr-process/SKILL.md
    │   └── sync-spec/SKILL.md
    └── settings.json

위는 full-team 프리셋 기준이다. solo-dev를 선택하면 5개 에이전트와 5개 스킬만 생성된다.

CI/CD나 자동화에서 쓰려면 비인터랙티브 모드도 지원한다:

npx create-agent-system --preset solo-dev --project-name my-app --yes

--dry-run 플래그를 붙이면 실제 파일을 만들지 않고 어떤 파일이 생성될지 미리 볼 수 있다.

프리셋 시스템

모든 프로젝트가 8개 에이전트와 8개 스킬을 다 필요로 하지는 않는다. 이 블로그를 만들 때 full-team 프리셋을 적용했다가 CTO가 README 수정에 리뷰 코멘트를 다는 상황을 보고 깨달았다 — 혼자 하는 사이드 프로젝트에 CTO 리뷰나 EPIC 기반 개발은 과하다. 그래서 3개의 프리셋을 만들었다.

프리셋규모에이전트스킬QA 모드Visual QAEPIC 기반
solo-devsmall55liteLevel 1No
small-teammedium88standardLevel 2Yes
full-teamlarge88standardLevel 3Yes

solo-dev는 혼자 개발하는 경우를 위한 프리셋이다. 아키텍트, CTO, 디자이너를 빼고 PO/PM, 테스트 작성자, 프론트/백엔드 개발자, QA 리뷰어 5개 에이전트만 활성화한다. QA도 간소화된 lite 모드로 돌아간다.

small-team은 팀 단위 개발을 위한 프리셋이다. 8개 에이전트 전부 활성화되고, CTO 리뷰 사이클(최대 5라운드), EPIC 기반 워크플로우, Level 2 Visual QA가 포함된다.

full-team은 대규모 프로젝트용이다. small-team과 에이전트/스킬 구성은 같지만, Visual QA가 Level 3(가장 엄격)으로 올라간다.

프리셋은 **의견 있는 기본값(opinionated defaults)**이다. 의견 없는 도구는 쓰기 어렵다. "어떤 에이전트를 활성화할지 골라주세요"라고 하면 처음 쓰는 사람은 막막하다. 프리셋이 합리적인 기본 구성을 제안하고, 거기서 커스터마이즈하는 게 훨씬 빠르다.

에이전트와 스킬

8개 에이전트

에이전트역할핵심 책임
PO/PM기획자스펙 작성, 티켓 관리, 우선순위 결정
Architect설계자ADR 작성, 컴포넌트 인터페이스 정의
CTO기술 리더코드 리뷰, 기술 방향 결정
Designer디자이너UI/UX 설계, 디자인 시스템 관리
Test Writer테스트 작성자TDD 기반 테스트 코드 작성
Frontend Dev프론트엔드UI 구현, 상태 관리
Backend Dev백엔드API, 데이터베이스, 비즈니스 로직
QA ReviewerQA최종 검증, 시각적 QA, 점수 기반 평가

이전 글에서 3개 프로젝트를 거치며 다듬어진 역할 분리가 그대로 반영되어 있다. 각 에이전트는 프로젝트의 기술 스택(패키지 매니저, 프레임워크 등)에 맞게 템플릿이 렌더링된다.

8개 스킬

스킬용도
scoring정량적 코드 품질 평가 (1000점 만점)
visual-qa시각적 QA 체크리스트
tdd-workflow테스트 주도 개발 워크플로우
adr-writingArchitecture Decision Record 작성
ticket-writing티켓/이슈 작성 표준
design-system디자인 시스템 컨벤션
cr-process코드 리뷰 프로세스
sync-spec공식 문서 동기화 검증

이전에는 이 스킬들을 프로젝트 간에 수동으로 복사했다. 이제는 프리셋을 고르면 해당 프리셋에 맞는 스킬이 자동으로 설치된다.

Intersection Skill Computation

에이전트 시스템을 설계하면서 마주친 미묘한 문제가 있었다. 에이전트마다 기본으로 사용하는 스킬이 다르고, 프리셋마다 활성화하는 스킬이 다르다. 이 둘을 어떻게 조합할 것인가?

각 에이전트에는 기본 스킬 목록이 정의되어 있다:

PO/PM       → scoring, ticket-writing, cr-process
Architect   → scoring, adr-writing
CTO         → scoring
Designer    → design-system, visual-qa, scoring
Test Writer → tdd-workflow, scoring
Frontend    → visual-qa, scoring
Backend     → scoring
QA Reviewer → visual-qa, scoring

그리고 프리셋마다 활성화하는 스킬이 다르다. solo-dev는 5개(scoring, tdd-workflow, ticket-writing, cr-process, sync-spec), small-team과 full-team은 8개 전부.

최종적으로 에이전트에 할당되는 스킬은 두 집합의 교집합이다:

에이전트의 최종 스킬 = 에이전트 기본 스킬 ∩ 프리셋 활성 스킬

왜 교집합인가? 처음에는 합집합으로 구현했다. 에이전트가 할 수 있는 건 다 주자는 생각이었다. 결과는 참담했다 — solo-dev 프리셋의 Backend 에이전트가 visual-qa 체크리스트를 출력하며 스크린샷을 요구하는 상황이 벌어졌다. 불필요한 스킬이 에이전트의 컨텍스트를 오염시킨 것이다. 교집합으로 바꾸자 이 문제가 사라졌다.

구체적인 예시를 보자:

solo-dev 프리셋의 활성 스킬:
  {scoring, tdd-workflow, ticket-writing, cr-process, sync-spec}
 
Designer의 기본 스킬:
  {design-system, visual-qa, scoring}
 
교집합 결과 → Designer에게 할당되는 스킬:
  {scoring}
 
(design-system, visual-qa는 프리셋에서 비활성이므로 제외)

이 교집합 연산은 코드 한 줄로 구현되어 있다:

function computeAgentSkills(agentName, presetSkills) {
  const defaults = AGENT_DEFAULT_SKILLS[agentName];
  return defaults.filter((skill) => presetSkills.includes(skill));
}

단순하지만 효과적이다. 에이전트에는 해당 프리셋에서 의미 있는 스킬만 할당된다.

doc-spec 기반 검증

에이전트 시스템의 가장 큰 적은 시간이다. Claude Code의 공식 스펙이 바뀌면, 에이전트 정의에 쓸 수 있는 필드, 스킬의 포맷, settings.json의 구조가 달라질 수 있다. 생성 시점에는 유효했던 설정이 한 달 뒤에 구식이 되는 문제.

실제로 이 문제를 겪었다. 프로젝트 B에서 만든 에이전트 정의를 프로젝트 C에 복사했는데, 그 사이 스킬 포맷에 allowed_tools 필드가 추가된 걸 몰랐다. 에이전트가 스킬을 로드하지 못해 한참을 삽질했다. 그래서 /sync-spec 스킬을 만들었다. Claude Code 안에서 실행하면, Context7 MCP를 통해 최신 공식 문서를 가져와 현재 설정과 비교한다:

claude
> /sync-spec

sync-spec은 다음을 검증한다:

  • 에이전트 정의 파일의 필드가 최신 스펙에 유효한지
  • 스킬 포맷이 현재 지원되는 형식인지
  • settings.json의 구조가 올바른지
  • 새로 추가된 기능이나 필드가 있는지

검증 결과와 함께 개선 제안이 출력된다. "스펙이 바뀌어도 에이전트가 따라간다"는 철학이 이 스킬에 담겨 있다.

validate 명령어도 별도로 제공된다:

npx create-agent-system validate

이 명령은 로컬에서 즉시 실행되며, frontmatter 검증, 스킬 참조 확인, 프로젝트 구조 체크를 수행한다. CI에 넣어두면 설정 파일이 깨진 채로 커밋되는 것을 방지할 수 있다.

설계하면서 배운 것

1. 좋은 기본값이 최고의 문서다

프리셋을 고르고 실행하면 바로 동작하는 에이전트 시스템이 나온다. 사용자가 README를 끝까지 읽지 않아도 합리적인 구성으로 시작할 수 있다. 문서를 아무리 잘 써도, 동작하는 기본값만큼 효과적인 온보딩은 없었다.

2. 프리셋은 의견이다 — 의견 없는 도구는 쓰기 어렵다

"모든 옵션을 열어두겠다"는 설계는 유연해 보이지만, 처음 쓰는 사람에게는 혼란이다. solo-dev에서 CTO 리뷰를 빼고, lite QA를 쓰는 것은 **"혼자 개발할 때는 이 정도면 충분하다"**는 의견이다. 그 의견이 합리적이면 사용자는 따라가고, 아니면 커스터마이즈한다. 어느 쪽이든 빈 캔버스보다 낫다.

3. 동기화 없는 스캐폴딩은 반쪽짜리다

초기 생성만 해주고 이후 관리가 없으면, 시간이 지나면서 설정이 구식이 된다. sync-spec 스킬이 없었다면 create-agent-system도 "한 번 쓰고 버리는 도구"가 됐을 것이다. 생성과 유지를 함께 해결해야 진짜 가치가 생긴다.

4. 에이전트가 많을수록 교집합 필터가 중요하다

처음에는 에이전트에 가능한 한 많은 스킬을 넣으려 했다. 하지만 불필요한 스킬은 프롬프트만 길어지게 하고, 에이전트가 관련 없는 규칙에 신경 쓰게 만든다. 해당 맥락에서 의미 있는 스킬만 할당하는 것이 더 나은 결과를 만들었다.

5. 추상화의 적정 수준이 있다

에이전트 정의 템플릿을 Handlebars로 만들면서, 너무 많은 것을 파라미터화하고 싶은 유혹이 있었다. 게이트 단계 수, 리뷰 라운드, 파일 소유권 규칙까지 전부 변수로 뺐다가 템플릿이 100줄을 넘어갔다. 결과물을 예측할 수 없게 되자 다시 되돌렸다. 핵심 변수(기술 스택, 모델, 스킬 목록)만 파라미터화하고, 나머지는 고정값으로 두는 것이 맞았다.

마치며

3개 프로젝트의 교훈이 npm 패키지 하나에 담겼다:

npx create-agent-system

GitHub에서 코드를 확인할 수 있다: github.com/jeremy-kr/create-agent-system

하지만 이건 시작일 뿐이다. 지금의 3개 프리셋과 8개 에이전트/스킬은 내 경험에서 나온 것이다. 다른 개발자의 경험은 다를 수 있다. React Native 전용 에이전트 세트, 데이터 파이프라인을 위한 스킬, 모노레포에 최적화된 프리셋 — 커뮤니티가 자신의 패턴을 공유할 수 있는 Community Registry로의 확장도 고려하고 있다.

에이전트 시스템은 혼자 만들면 개인 도구에 머문다. 커뮤니티의 경험이 더해져야 진짜 완성된다.