
간병인이 Claude Code로 AI 개발 팀을 만든 이야기
요약
Claude Code를 활용하여 Planner, Generator, Evaluator라는 세 가지 역할을 가진 AI 에이전트 팀을 구축한 사례를 소개합니다. 각 에이전트에게 명확한 역할을 부여하고 SPEC.md를 단일 진실 공급원으로 활용하여 개발 품질을 높이는 방법을 다룹니다.
핵심 포인트
- Claude Code 기반의 3단계 에이전트(Planner, Generator, Evaluator) 구조 설계
- AI의 자기 객관화 한계를 극복하기 위해 역할 분리 및 피드백 루프 구축
- SPEC.md를 프로젝트의 단일 진실 공급원(SSOT)으로 활용하여 일관성 유지
- 설계, 구현, 검증의 분리를 통한 개발 프로세스 최적화
이 블로그는 인간 1명과 AI 3명의 팀이 만들었다.
정확하게는, Claude Code라는 도구 위에 3개의 AI 에이전트 (Agent)를 구축하고, 각각에게 역할을 부여하여 개발을 진행했다.
Planner, Generator, Evaluator.
이 세 가지가 무엇을 하는지, 왜 그런 구성으로 했는지에 대해 쓰겠다.
처음에는 심플하게 AI에게 지시를 내리고, 돌아온 코드를 그대로 사용하는 방식으로 진행했다.
하지만 곧 한계가 왔다.
AI는 자신의 출력을 스스로 리뷰하는 것을 어려워한다.
"이 코드에 문제없나요?"라고 물으면, 대개 "문제없습니다"라고 답한다. 자신이 쓴 것을 스스로 부정하는 것은 AI도 인간도 어려운 일이다.
그래서 간병 현장의 일을 떠올렸다.
간병 현장에서도 혼자서 모든 것을 판단하는 경우는 드물다. 케어 매니저가 계획을 세우고, 간병사가 실행하며, 간호사나 관리자가 확인한다. 각자가 역할을 가지고 서로를 체크함으로써 케어의 질이 유지된다.
소프트웨어 개발도 마찬가지가 아닐까 생각했다.
그렇게 생각하여 만든 것이 Planner / Generator / Evaluator의 3 에이전트 구성이다.
Planner의 업무는 구현 전에 "무엇을 만들 것인가"를 명확히 하는 것이다.
애매한 요구사항을 그대로 Generator에게 전달하면, 빗나간 구현이 돌아온다. 그래서 Planner가 먼저 요건을 정리하고, 태스크 (Task)를 분해하며, 구현 방침을 결정한다.
설계서를 만드는 이미지에 가깝다.
# .claude/agents/planner.md (발췌)
당신은 Planner입니다.
SPEC.md에 기재된 스프린트 (Sprint) 정의를 읽고,
...
Generator는 Planner의 출력을 받아 실제로 코드를 작성한다.
이곳은 순수하게 구현에 집중하게 한다. 설계에 대한 논의는 하지 않는다. Planner가 결정한 것을 충실히 구현할 뿐이다.
역할을 나눔으로써 "생각하는 것"과 "만드는 것"이 혼재되지 않게 된다.
# .claude/agents/generator.md (발췌)
당신은 Generator입니다.
Planner가 출력한 태스크 정의에 따라 코드를 구현해 주세요.
...
Evaluator가 가장 중요할지도 모른다.
Generator가 작성한 코드를 다른 관점에서 리뷰한다. 버그 검출, 설계상의 문제, 퍼포먼스 (Performance) 우려, 보안 리스크. Generator가 놓친 것을 잡아내는 역할이다.
같은 AI라도 "만드는 역할"과 "평가하는 역할"을 나누면 지적의 질이 올라간다. 자신이 작성한 코드를 스스로 리뷰하는 상태에서 탈피할 수 있다.
# .claude/agents/evaluator.md (발췌)
당신은 Evaluator입니다.
Generator의 구현을 비판적인 시각으로 리뷰해 주세요.
...
3개의 에이전트와 SPEC.md, 그리고 자신(운영자)이 어떻게 연결되어 있는지 도식화하면 다음과 같다.
Evaluator에서 Generator로 향하는 화살표가 포인트다. 한 번에 "완료"되는 것이 아니라, 지적이 있으면 구현으로 돌아간다. 이 루프 (Loop)가 있음으로써 혼자서 리뷰하는 것보다 결함을 찾아내기가 쉬워졌다.
3 에이전트를 움직이는 데 있어 또 하나 중요한 것이 있다.
SPEC.md다.
SPEC.md는 스프린트 정의를 작성한 파일로, 프로젝트의 "단일 진실 공급원 (Single Source of Truth)"로서 기능한다.
# Sprint 3: 태그 기능 구현
## Goal
기사에 태그를 부여하고, 태그별 목록 페이지를 생성한다
...
Planner는 이것을 읽고 움직인다. Generator는 Planner의 출력을 바탕으로 움직인다. Evaluator는 Generator의 출력을 평가한다.
SPEC.md가 애매하면 전체가 흔들린다. 반대로 SPEC.md가 명확하면 3 에이전트가 놀라울 정도로 매끄럽게 움직인다.
단일 AI와의 최대 차이점은 결함 검출률이다.
한 명의 AI에게 "구현도 하고 리뷰도 해줘"라고 부탁하면 자신의 출력을 긍정하기 쉽다. 하지만 Evaluator를 분리하면 Generator가 놓친 엣지 케이스 (Edge Case)나 보안상의 우려를 잡아내는 일이 늘어났다.
실제로는 순탄치 않았다.
CloudFront Function이 AWS 상에 존재하지 않아 개별 기사가 모두 403 에러가 난다. GitHub Actions의 OIDC 권한 설정이 부족하여 배포에 실패한다. Terraform 관리 외의 리소스가 섞여 구성이 깨진다.
문제 발견은 자신일 때도 있고 Evaluator일 때도 있었지만, 적어도 여러 관점에서 확인하는 메커니즘이 없었다면 훨씬 더 멀리 돌아갔을 것이라고 생각한다.
또 하나는 스프린트 주도(Sprint-driven) 방식과 궁합이 좋다는 점이다.
SPEC.md로 범위를 구분하고, 1스프린트씩 진행한다. 이 블로그는 Sprint 0부터 Sprint 9까지, 총 10스프린트에 걸쳐 완성되었다.
스프린트가 작을수록 Planner의 설계가 정확해지고, Generator의 구현이 흔들리지 않으며, Evaluator의 리뷰가 날카로워진다.
참고로, 실제 에이전트(Agent) 구성은 다음과 같다.
.claude/
└── agents/
├── planner.md
...
Claude Code는 이 .claude/agents/
하위 파일들을 에이전트 정의로 읽어 들인다. 프롬프트(Prompt) 파일을 리포지토리(Repository)에 두는 것만으로도, 팀 멤버(AI와 인간 모두)가 동일한 정의에 따라 움직일 수 있다.
솔직히 처음에는 '에이전트를 만든다'는 발상 자체가 없었다.
AI에게 물어보고, 돌아온 코드를 붙여넣는다. 그게 전부라고 생각했다.
하지만 역할을 나눔으로써 AI 출력의 질이 높아졌다. 그리고 내가 어디에 집중해야 하는지도 명확해졌다.
Planner에게 설계를 맡기는 동안, 나는 SPEC.md를 다듬는 데 집중할 수 있다. Generator가 구현하는 동안, 나는 다음 스프린트를 생각할 수 있다. Evaluator가 리뷰하는 동안, 나는 커피를 마실 수 있다.
간병 현장에 비유하자면, 역할 분담과 팀 플레이의 이야기다. 혼자서 전부 하려고 하는 것보다, 역할을 정해 팀으로 움직이는 편이 훨씬 더 좋은 결과물을 만들 수 있다. 그것은 AI 팀에서도 마찬가지였다.
AWS 공부를 시작했을 때, 나는 VPN이라는 단어조차 몰랐다.
그런 내가 지금, AI에게 역할을 부여하고, Terraform으로 인프라를 관리하며, GitHub Actions로 자동 배포(Automated Deployment)를 돌리고 있다.
솔직히 스스로도 조금 믿기지 않는다.
하지만 이 블로그 자체가 그 증거라고 생각한다.
이 시점에서는 아직 블로그를 공개하지 못한 상태였다. 다음에 맞닥뜨린 과제는 Terraform과 GitHub Actions를 이용한 배포 파이프라인(Deployment Pipeline) 구축이었다.
다음 회차에서는 그 인프라 구축에 관한 이야기를 쓰겠다 (간병인이 Terraform + GitHub Actions + OIDC로 블로그의 CI/CD를 구축한 이야기).
이 기사는 필자의 블로그에서 전재되었습니다 → 원문 보기
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기