본문 바로가기

AI 개발

AWS Kiro 2편—Specs Wave 실행·Steering 아키텍처·Autonomous Agent, 팀 프로덕션에서 살아남는 법

반응형

기초편에서 설치하고 첫 스펙 써봤다면, 이제부터가 진짜입니다. Kiro가 단순 코드 생성 도구와 달라지는 지점은 세 가지입니다. 스펙이 코드를 제어하는 방식, Steering이 팀 전체에 적용되는 방식, Autonomous Agent가 백그라운드에서 PR을 열어주는 방식. 이 세 가지를 프로덕션에 박아 넣는 법을 다룹니다.


핵심 요약

Specs Wave 실행은 tasks.md 의존성 그래프를 분석해서 병렬 실행을 자동화하고 Wave N까지 순차 완료합니다. Bugfix Spec은 버그 수정을 스펙 워크플로우로 처리하는 방식으로, bugfix.md가 회귀 방지 가드레일 역할을 합니다. Steering은 always/auto/fileMatch/manual 4가지 모드를 전략적으로 분리해서 컨텍스트 낭비를 없앱니다. AGENTS.md는 Kiro·Claude Code·Cursor가 모두 읽는 범용 규칙 파일이고, Skills 시스템은 SKILL.md 기반으로 재사용 가능한 에이전트 역량을 패키징합니다. Autonomous Agent는 백그라운드에서 스펙을 읽고 PR을 오픈하며, AgentCore 연동으로 멀티에이전트 오케스트레이션까지 가능합니다. Bedrock 비용은 모델 라우팅 전략으로 Nova/Sonnet을 선택적으로 써서 제어합니다.


실전 1 — Specs Wave 실행: 병렬 태스크 그래프 제대로 쓰기

기초편에서 tasks.md가 체크리스트로 끝났다면, 심화에서는 의존성 그래프로 씁니다. Kiro는 이 파일을 읽고 병렬 실행 가능한 Wave를 자동으로 구성합니다. 의존성 없는 태스크는 동시에 처리하고, 의존하는 태스크는 앞 Wave가 완료된 후에 실행합니다. 직렬로 쓰면 3일짜리 작업이 Wave를 활용하면 1.5일로 줄어드는 이유입니다.

tasks.md에 의존성을 명시하는 방법은 아래와 같습니다. 각 태스크 아래에 "의존성: 태스크 N"을 적어두면 Kiro가 알아서 Wave를 구성합니다.

## 구현 태스크

- [ ] 1. DB 스키마 생성 (users, tokens 테이블)
  - 의존성: 없음  ← Wave 1

- [ ] 2. JWT 유틸리티 함수 구현 (sign/verify/decode)
  - 의존성: 없음  ← Wave 1 (1과 병렬)

- [ ] 3. 환경변수 설정 (.env 구조 정의)
  - 의존성: 없음  ← Wave 1 (병렬)

- [ ] 4. UserRepository 구현 (findByEmail, findById)
  - 의존성: 태스크 1  ← Wave 2

- [ ] 5. AuthService.login() 구현
  - 의존성: 태스크 2, 4  ← Wave 3

- [ ] 6. AuthService.refresh() 구현
  - 의존성: 태스크 2, 4  ← Wave 3 (5와 병렬)

- [ ] 7. AuthController 라우트 정의
  - 의존성: 태스크 5, 6  ← Wave 4

- [ ] 8. 단위 테스트 작성
  - 의존성: 태스크 5, 6  ← Wave 4 (7과 병렬)

- [ ] 9. 통합 테스트
  - 의존성: 태스크 7, 8  ← Wave 5

Wave 실행 구조를 시각화하면 Wave 1에서 태스크 1·2·3이 동시 실행되고, 완료되면 Wave 2에서 태스크 4가 실행되는 방식으로 순차 진행됩니다. Quick Plan 옵션을 쓰면 스펙 승인 게이트 없이 3개 파일을 자동 생성하고 바로 Wave를 실행합니다.


실전 2 — Bugfix Spec: 버그도 스펙으로 잡는다

기존 방식은 "버그 고쳐줘"라고 말하면 에이전트가 관련 없는 코드까지 건드리는 문제가 있었습니다. Bugfix Spec 워크플로우는 버그를 묘사하면 Kiro가 근본 원인 분석, 수정 설계, 회귀 방지까지 단계적으로 안내하고, 결과물로 bugfix.md를 생성합니다. 이 파일이 에이전트에게 명확한 가드레일을 줍니다.

bugfix.md에서 핵심은 "변경되면 안 되는 것"을 명시하는 부분입니다. 에이전트가 수정 범위를 넘어서는 것을 이 섹션이 막아줍니다. 아래는 Lambda 환경에서 Refresh Token이 간헐적으로 401을 반환하는 버그를 Bugfix Spec으로 처리한 예시입니다.

# .kiro/specs/auth-refresh-bug/bugfix.md

## 버그 설명
Refresh Token으로 새 Access Token 요청 시
간헐적으로 401이 반환됨 (재현율 약 30%)

## 현재 동작 (Current Behavior)
- POST /auth/refresh 요청 시 Redis에서 Refresh Token 조회 성공
- 그럼에도 401 Unauthorized 반환
- 서버 로그: "Token validation failed: invalid signature"

## 기대 동작 (Expected Behavior)
- 유효한 Refresh Token 제출 시 200 + 새 Access Token 반환

## 근본 원인 분석 (Root Cause)
- JWT_SECRET이 멀티 인스턴스 환경에서 인스턴스마다 다른 값으로 로드되는 현상
- Lambda cold start 시 시크릿 재로딩 타이밍 이슈

## 수정 방향
- JWT_SECRET을 AWS Secrets Manager에서 캐싱 방식으로 로드
- 초기화 시점에 한 번만 로드, 이후 캐시 사용

## 변경되면 안 되는 것 (Must Not Change)
- 기존 발급된 토큰의 유효성 (마이그레이션 기간 동안)
- /auth/login 엔드포인트 응답 구조
- Refresh Token 만료 기간 (7일)

## 회귀 테스트 요구사항
- [ ] 멀티 인스턴스 환경에서 동일 토큰 100회 검증 테스트
- [ ] Secrets Manager 연결 실패 시 graceful degradation 확인

bugfix.md도 Git에 커밋하면 나중에 "왜 이렇게 고쳤는지"를 추적할 수 있습니다. 스펙 파일이 코드와 함께 버전 관리되기 때문에 팀 전체가 맥락을 공유할 수 있다는 게 Bugfix Spec 워크플로우의 핵심 가치입니다.


실전 3 — Steering 4가지 모드 전략: 컨텍스트 낭비 없애기

기초편에서 Steering을 단순히 "영구 컨텍스트"로 썼다면, 심화에서는 4가지 모드를 전략적으로 분리해서 씁니다. 모드를 잘못 쓰면 매 요청마다 관련 없는 규칙이 컨텍스트 윈도우를 잡아먹어서 비용이 늘어나고 응답 품질이 떨어집니다.

always — 항상 로드. TypeScript strict mode, any 타입 금지처럼 전체 프로젝트에 항상 적용해야 하는 코딩 컨벤션과 팀 표준에 씁니다.

# .kiro/steering/typescript-rules.md
---
inclusion: always
---

## TypeScript 규칙
- strict mode 필수
- any 타입 사용 금지
- 모든 함수 반환 타입 명시

fileMatch — 특정 파일 패턴에 매칭될 때만 로드합니다. React 컴포넌트 규칙을 .tsx 파일 편집할 때만 올려두면 백엔드 작업 중에 프론트엔드 규칙이 컨텍스트를 오염시키는 걸 막습니다.

# .kiro/steering/react-components.md
---
inclusion: fileMatch
patterns:
  - "src/components/**/*.tsx"
  - "src/pages/**/*.tsx"
---

## React 컴포넌트 규칙
- 함수형 컴포넌트만 사용 (클래스 컴포넌트 금지)
- props 타입은 interface로 선언
- 스타일: TailwindCSS만 (inline style 금지)
- 상태관리: Zustand (Redux 금지)

auto — Kiro가 컨텍스트를 보고 자동으로 로드 여부를 판단합니다. CDK 코드나 핸들러 파일을 편집할 때 AWS Lambda 규칙을 자동으로 불러오게 하는 식으로 씁니다.

manual — /security-audit 같은 슬래시 명령으로 명시적으로 호출할 때만 로드됩니다. 보안 감사나 성능 프로파일링처럼 평소에 올라가 있으면 모든 응답이 한쪽으로 치우치는 규칙에 적합합니다.

실전 권장 구조는 전역 3개(always) + 도메인별 5~8개(fileMatch) + 특수 2~3개(manual)입니다. always 파일을 너무 많이 만들면 매 요청마다 컨텍스트 윈도우를 낭비합니다. 팀 전체 공유가 필요하면 ~/.kiro/steering/에 글로벌 파일을 두고 MDM/그룹 정책으로 배포할 수 있습니다.


실전 4 — AGENTS.md: Kiro·Claude Code·Cursor 한 번에 제어

Kiro는 AGENTS.md 표준을 지원합니다. 글로벌 steering 위치(~/.kiro/steering/)나 워크스페이스 루트에 AGENTS.md를 추가하면 Kiro가 자동으로 읽습니다. Claude Code도, Cursor도 같은 파일을 읽기 때문에 하나만 잘 써두면 도구가 바뀌어도 동일한 규칙이 적용됩니다. 팀 규칙 변경 시 AGENTS.md 하나만 수정하면 전체 AI 도구가 동기화됩니다.

# AGENTS.md (프로젝트 루트)

## 절대 규칙 (모든 AI 도구 공통)
- 환경변수 하드코딩 금지 — .env 또는 Secrets Manager
- console.log 사용 금지 — logger 유틸리티 사용 (src/utils/logger.ts)
- any 타입 사용 금지
- 직접 DB 쿼리 금지 — 반드시 Repository 레이어 통해서

## 아키텍처 패턴
- Controller → Service → Repository 레이어 구조 준수
- 에러: Result<T, E> 패턴 (src/types/result.ts 참조)
- API 응답: { data: T | null, error: string | null, meta?: object }

## 금지 라이브러리
- moment.js → date-fns 사용
- lodash → 네이티브 ES2024 메서드 우선
- axios → fetch API 또는 ky

## 코드 생성 후 자가 점검
1. 새 의존성 추가 시 package.json에 명시됐는가?
2. 환경변수 새로 필요 시 .env.example에 추가됐는가?
3. 새 엔드포인트라면 docs/api.md에 추가됐는가?

Steering 파일과 다른 점은 AGENTS.md는 항상(always) 로드되고 inclusion 모드 옵션이 없다는 것입니다. Git으로 관리하면 PR 리뷰로 규칙 변경 이력을 추적할 수 있습니다.


실전 5 — Skills 시스템: 재사용 가능한 에이전트 역량 패키징

Skills는 재사용 가능한 에이전트 역량을 패키징하는 시스템입니다. Steering이 항상 적용되는 규칙이라면, Skills는 특정 작업 시 활성화되는 역량입니다. 글로벌 스킬은 ~/.kiro/skills/에 위치하며 모든 워크스페이스에서 사용할 수 있고, 워크스페이스 스킬과 이름이 같으면 워크스페이스 스킬이 우선 적용됩니다.

각 스킬은 SKILL.md를 기반으로 합니다. 코드 리뷰 스킬을 예로 들면, 언제 사용하는지, 체크리스트가 무엇인지, 출력 형식이 어떤지를 SKILL.md에 정의해두면 Kiro가 "이 PR 코드 리뷰해줘"라는 요청에서 자동으로 이 스킬을 활성화합니다.

# ~/.kiro/skills/code-review/SKILL.md

## 언제 사용하나요?
PR 리뷰 요청이 들어왔거나 코드 품질 점검이 필요할 때

## 리뷰 체크리스트
1. 보안: 인젝션, 인증 누락, 시크릿 노출
2. 성능: N+1 쿼리, 불필요한 루프, 메모리 누수
3. 가독성: 함수 길이 50줄 이하, 명확한 네이밍
4. 테스트: 엣지케이스 커버, Mock 적절성
5. 에러 처리: 모든 예외 처리, 사용자 친화 메시지

## 출력 형식
각 항목을 ✅ PASS / ⚠️ WARN / ❌ FAIL로 표시
WARN·FAIL은 구체적 수정 방법 포함

GitHub에서 스킬을 임포트하는 것도 가능합니다. 공개 레포 URL만 붙여넣으면 설치됩니다. 팀 스킬 저장소를 만들어 공유하면 팀 전체 에이전트 역량을 표준화할 수 있습니다.


실전 6 — Autonomous Agent: 백그라운드에서 PR 열어주는 에이전트

Kiro Autonomous Agent는 제품 스펙, ADR, 저장소를 읽고 아키텍처를 이해한 다음 코드를 작성·리팩토링하고 테스트를 작성하며 PR까지 엽니다. 목표를 주면 스스로 계획하고 분해하고 실행합니다.

가장 실용적인 시나리오는 백로그 태스크 자동 처리입니다. CodeCatalyst 이슈를 연결하면 에이전트가 이슈를 읽고 스펙을 생성한 뒤 Steering 파일을 로드하고 Wave 단위로 구현한 다음 완료 후 PR을 오픈합니다.

kiro agent run \
  --issue "codecatalyst://my-project/issues/142" \
  --steering ".kiro/steering/" \
  --output "pr"

Security Agent와 협업하는 멀티에이전트 패턴도 가능합니다. --after-impl 옵션으로 구현 완료 후 Security Agent를 자동 호출해서 취약점 리포트를 생성하게 할 수 있습니다.

Autonomous Agent가 적합한 작업과 부적합한 작업을 구분하는 게 중요합니다. 스펙이 명확하게 작성된 백로그 태스크, 반복적인 CRUD 엔드포인트 추가, 마이그레이션 스크립트 작성, 테스트 커버리지 보완은 적합합니다. 반대로 요구사항이 불명확한 탐색적 기능, 기존 아키텍처 대규모 리팩토링, 프로덕션 DB에 직접 영향을 미치는 작업은 사용하면 안 됩니다. Autonomous Agent가 열어준 PR은 반드시 인간이 리뷰해야 합니다.


실전 7 — Bedrock 비용 관리: 모델 라우팅 전략

Kiro는 추론 집약적 스펙 작업에는 Claude Sonnet을, 고처리량 코드 생성에는 Amazon Nova를 라우팅합니다. 이 라우팅을 이해하고 직접 설정하면 비용을 전략적으로 제어할 수 있습니다.

Claude Sonnet은 스펙 생성·분석, requirements.md 작성, 아키텍처 설계 판단, 버그 근본 원인 분석처럼 추론이 중요한 작업에 씁니다. Amazon Nova는 반복 코드 생성, 보일러플레이트 구현, 단위 테스트 작성, 단순 리팩토링처럼 처리량이 중요한 작업에 씁니다. 비용과 속도 면에서 Nova가 유리하고, 품질 면에서 Sonnet이 유리합니다.

# .kiro/config.yaml
model_routing:
  spec_generation:   claude-sonnet    # 스펙은 품질 우선
  code_generation:   nova-pro         # 코드 생성은 비용 우선
  test_generation:   nova-lite        # 테스트는 최저 비용
  security_review:   claude-sonnet    # 보안 판단은 품질 필수

cost_controls:
  daily_limit_usd: 50
  nova_preference: true
  log_model_usage: true

Hook은 저렴한 모델로, 스펙 리뷰 단계를 명확히 해서 불필요한 코드 생성을 방지하고, always 모드 Steering 파일 수를 최소화하는 것이 비용 최적화의 핵심입니다.


실전 8 — 팀 도입 체크리스트: Cursor에서 Kiro로 마이그레이션

Week 1에는 AGENTS.md 작성, Steering 파일 구조 설계(always/fileMatch 분리), 핵심 Hook 3개 설정(테스트 자동생성·보안스캔·API문서), 글로벌 Skills 라이브러리 초기 세팅을 합니다. Week 2에는 신규 기능 하나를 Spec 워크플로우로 전체 진행하면서 Wave 실행 결과 품질을 확인하고 Steering 규칙을 보완합니다. Week 3에는 모든 신규 기능에 Spec 워크플로우를 의무화하고 Autonomous Agent 파일럿을 돌립니다. Week 4에는 모델 라우팅 설정을 튜닝하고 PR 리뷰에서 스펙 파일 리뷰 문화를 정착시킵니다.

가장 큰 마이그레이션 장벽은 도구 적응이 아니라 "스펙 먼저 쓰는 문화"입니다. 코드부터 짜고 싶은 욕구를 Spec 리뷰 단계가 막아주는데, 처음엔 답답하지만 나중엔 자산이 됩니다. Kiro가 Cursor보다 유리한 팀은 AWS 스택을 쓰고, 협업 중심이고, 장기 유지보수가 많은 팀입니다. 1인 개발이나 빠른 프로토타입, 비 AWS 스택이라면 Cursor가 더 맞습니다.


마무리

Wave 실행은 tasks.md에 의존성을 명시하는 것만으로 병렬화가 가능해서 개발 속도를 실질적으로 단축합니다. Bugfix Spec은 "변경되면 안 되는 것" 명시로 에이전트 오버리치를 방지하고 회귀 가드레일을 만들어줍니다. Steering 4모드를 always/auto/fileMatch/manual로 분리하면 컨텍스트 낭비가 없어집니다. AGENTS.md 하나로 Kiro·Claude Code·Cursor를 동시에 제어할 수 있고, Skills로 팀 전체 에이전트 역량을 표준화할 수 있습니다. Autonomous Agent는 스펙 기반 PR 자동화를 가능하게 하지만, 탐색적 작업이나 대규모 리팩토링에는 쓰면 안 됩니다. 프로덕션 인프라 작업 시에는 반드시 인간 검토가 들어가야 합니다.


관련 글

반응형