콘텐츠로 이동

스펙 주도 루프 설계

Ralph 기법의 PROMPT.md는 단순하고 강력하다. 그런데 프로젝트가 커지고, 여러 루프가 동시에 돌아가고, 팀원이 추가되면 단일 파일로는 한계가 생긴다. 스펙 주도 루프 설계는 이 확장 문제에 답한다. 핵심 아이디어는 같다 — 매 루프 이터레이션마다 안정적인 컨텍스트를 재주입한다. 그 컨텍스트를 더 체계적으로 관리하는 것이 다르다.

specs 디렉터리: 루프의 장기 메모리

섹션 제목: “specs 디렉터리: 루프의 장기 메모리”

스펙 주도 설계에서 specs/ 디렉터리는 루프의 안정적 진실 원천이다. 개별 PROMPT.md가 단일 태스크를 담는다면, specs는 프로젝트 전체의 요구사항, 설계 결정, 제약 조건을 체계적으로 담는다.

┌─────────────────────────────────────────────────────────────────┐
│ 스펙 주도 루프 파일 구조 │
└─────────────────────────────────────────────────────────────────┘
프로젝트 루트/
├── AGENTS.md # 루프 목차: 어디서 무엇을 찾는지
├── specs/
│ ├── requirements.md # 기능 요구사항 (변경 빈도: 낮음)
│ ├── architecture.md # 설계 결정·패턴 (변경 빈도: 낮음)
│ ├── conventions.md # 코드 컨벤션·도구 규칙 (변경 빈도: 낮음)
│ └── fix_plan.md # 현재 진행 중인 수정 계획 (변경 빈도: 높음)
├── src/
└── tests/

변경 빈도에 따른 분리가 핵심이다. requirements.mdarchitecture.md는 거의 변하지 않는 안정적 컨텍스트다. 루프는 이것을 항상 읽어 프로젝트의 불변 제약을 인식한다. fix_plan.md는 현재 루프가 달성해야 할 구체적 목표를 담으며, 루프마다 업데이트된다.

fix_plan.md는 Ralph의 PROMPT.md를 더 구조화한 형태다. 단순한 지시문 대신, 에이전트가 진행 상황을 추적하고 업데이트할 수 있는 형식을 갖춘다.

# 현재 수정 계획 (fix_plan.md)
## 목표
사용자 인증 플로우에서 세션 만료 처리 버그 수정
## 현재 상태
- [x] 버그 재현 완료 (tests/auth/session_test.py:42)
- [x] 원인 파악: refresh_token 검증 누락
- [ ] TokenService.refresh() 수정
- [ ] 세션 만료 시나리오 테스트 추가
- [ ] 기존 인증 테스트 회귀 확인
## 수정할 파일
- src/services/token_service.py (라인 87-103)
- tests/auth/session_test.py (새 테스트 케이스 추가)
## 완료 기준
pytest tests/auth/ 전체 통과

에이전트는 작업을 수행하면서 [ ][x]로 업데이트한다. 루프가 중단되어도 다음 이터레이션이 시작되면 fix_plan.md를 읽어 어디까지 했는지 파악하고 이어서 진행한다. **루프 재개 가능성(resumability)**이 생긴다.

AGENTS.md: 1000페이지 매뉴얼이 아닌 목차

섹션 제목: “AGENTS.md: 1000페이지 매뉴얼이 아닌 목차”

AGENTS.md는 많은 프로젝트에서 “에이전트가 알아야 할 모든 것을 담은 거대한 문서”로 잘못 활용된다. 이것이 안티패턴이다.

┌──────────────────────────────┬───────────────────────────────────┐
│ 안티패턴 │ 올바른 패턴 │
├──────────────────────────────┼───────────────────────────────────┤
│ AGENTS.md에 모든 것 기술 │ AGENTS.md는 목차 역할만 │
│ (1000페이지 매뉴얼) │ (20~50줄의 인덱스) │
│ │ │
│ 내용: 코드 컨벤션, API 문서, │ 내용: "코드 컨벤션은 │
│ 아키텍처 설명, 팀 규칙, │ specs/conventions.md 참조" │
│ 배포 절차, 테스트 방법 등 │ "아키텍처는 specs/arch.md" │
│ 전부를 한 파일에 │ "현재 작업: specs/fix_plan.md" │
│ │ │
│ 문제: 컨텍스트 낭비, │ 장점: 필요한 파일만 JIT 로드, │
│ 정보 매몰, 유지보수 불가 │ 유지보수 쉬움, 변경 추적 가능 │
└──────────────────────────────┴───────────────────────────────────┘

AGENTS.md는 “어디서 무엇을 찾는지”만 알려준다. 실제 내용은 각 specs 파일에 분산 저장된다. 에이전트는 필요할 때 해당 파일을 로드한다 — JIT 검색(5-5절)의 원칙과 같다.

# AGENTS.md 올바른 예시
## 이 저장소에서 작업할 때
**현재 작업 지시**: specs/fix_plan.md
**프로젝트 요구사항**: specs/requirements.md
**코드 컨벤션**: specs/conventions.md
**아키텍처 결정**: specs/architecture.md
## 작업 완료 기준
모든 변경 사항은 `make test`로 검증 후 제출하라.
린트 오류가 없어야 한다: `make lint`
## 환경 설정
Python 3.11, Poetry, pytest 사용.
의존성 추가 시 반드시 pyproject.toml 업데이트.

기계적 검증: 루프를 닫는 자동화

섹션 제목: “기계적 검증: 루프를 닫는 자동화”

스펙 주도 루프의 완성은 자동화된 검증이다. 에이전트의 변경이 올바른지 판단하는 것을 사람이 아니라 도구가 한다.

┌─────────────────────────────────────────────────────────────────┐
│ 기계적 검증 파이프라인 │
└─────────────────────────────────────────────────────────────────┘
에이전트 코드 수정
① 린터 (즉각적)
make lint 또는 ruff check .
스타일·타입 오류 즉시 피드백
② 단위 테스트 (빠름, ~수십 초)
pytest tests/unit/
수정한 컴포넌트의 동작 검증
③ 통합 테스트 (느림, ~수분)
pytest tests/integration/
컴포넌트 간 상호작용 검증
④ CI 파이프라인 (선택, ~수분~수십 분)
GitHub Actions / Jenkins
전체 시스템 검증
모두 통과 → 에이전트 태스크 완료 선언
실패 → 오류 메시지를 컨텍스트에 추가, 수정 반복

Makefile이나 npm scripts로 검증 명령을 표준화하면 에이전트가 “어떤 명령으로 검증하는지” 외울 필요가 없다. AGENTS.md에 make test만 적으면 된다.

루프 시작
AGENTS.md 읽기 (목차 파악)
specs/fix_plan.md 읽기 (현재 목표 + 진행 상태 파악)
필요한 specs 파일 JIT 로드 (conventions.md 등)
코드 수정 + fix_plan.md 체크박스 업데이트
make lint && make test 실행
├── 실패 → 오류 분석, 수정, 재검증
└── 통과 → fix_plan.md 완료 표시, 루프 이터레이션 종료
(외부 while 루프: 다음 이터레이션 또는 수동 중단)

단순한 Ralph 루프로 충분하다면 굳이 specs 구조를 도입할 필요 없다. 다음 상황에서 스펙 주도 설계의 가치가 높아진다.

  • 다수의 에이전트 루프가 같은 저장소에서 작동할 때
  • 루프가 여러 날에 걸쳐 실행되고 재개가 필요할 때
  • 팀이 에이전트의 작업 범위와 제약을 공유해야 할 때
  • 규정 준수나 감사 목적으로 변경 이력이 필요할 때

스펙 주도 루프는 단순함(Ralph)과 체계(specs)의 균형이다. 다음 챕터에서는 이 모든 루프 패턴 중 무엇을 선택해야 하는지 결정하는 프레임워크를 다룬다.

참고 자료