📚FOS Study
홈카테고리
홈카테고리

카테고리

  • AI 페이지로 이동
    • RAG 페이지로 이동
    • agents 페이지로 이동
    • langgraph 페이지로 이동
    • BMAD Method — AI 에이전트로 애자일 개발하는 방법론
    • Claude Code의 Skill 시스템 - 개발자를 위한 AI 자동화의 새로운 차원
    • Claude Code를 11일 동안 쓴 결과 — 데이터로 본 나의 사용 패턴
    • Claude Code 멀티 에이전트 — Teams
    • 하네스 엔지니어링 — 오래 실행되는 AI 에이전트를 위한 설계
    • 멀티모달 LLM (Multimodal Large Language Model)
    • AI 에이전트와 함께 MVP 만들기 — dooray-cli 사례
  • architecture 페이지로 이동
    • 캐시 설계 전략 총정리
    • 디자인 패턴
    • 분산 트랜잭션
  • css 페이지로 이동
    • FlexBox 페이지로 이동
  • database 페이지로 이동
    • mysql 페이지로 이동
    • opensearch 페이지로 이동
    • redis 페이지로 이동
    • 김영한의-실전-데이터베이스-설계 페이지로 이동
    • 커넥션 풀 크기는 얼마나 조정해야할까?
    • 인덱스 - DB 성능 최적화의 핵심
    • 역정규화 (Denormalization)
    • 데이터 베이스 정규화
  • devops 페이지로 이동
    • docker 페이지로 이동
    • k8s 페이지로 이동
    • k8s-in-action 페이지로 이동
    • monitoring 페이지로 이동
    • Envoy Proxy
    • Graceful Shutdown
  • go 페이지로 이동
    • Go 언어 기본 학습
  • http 페이지로 이동
    • HTTP Connection Pool
  • interview 페이지로 이동
    • 210812 페이지로 이동
    • 뱅크샐러드 AI Native Server Engineer
    • CJ 올리브영 커머스플랫폼유닛 Back-End 개발 지원 자료
    • 마이리얼트립 - Platform Solutions실 회원주문개발 Product Engineer
    • NHN 서비스개발센터 AI서비스개발팀
    • nhn gameenvil console backend 직무 인터뷰 준비
    • 면접을 대비해봅시다
    • 토스증권 Server Developer (Platform) 지원 자료
    • 토스증권 Server Developer (Product) 지원 자료
    • 토스뱅크 Server Developer (Product) 지원 자료
    • Tossplace Node.js Developer
    • 토스플레이스 Node.js 백엔드 컬처핏
  • java 페이지로 이동
    • jdbc 페이지로 이동
    • opentelemetry 페이지로 이동
    • spring 페이지로 이동
    • spring-batch 페이지로 이동
    • 더_자바_코드를_조작하는_다양한_방법 페이지로 이동
    • Java의 로깅 환경
    • MDC (Mapped Diagnostic Context)
    • OpenTelemetry 란 무엇인가?
    • Java StampedLock — 읽기 폭주에도 쓰기가 밀리지 않는 락
    • Virtual Thread와 Project Loom
  • javascript 페이지로 이동
    • Data_Structures_and_Algorithms 페이지로 이동
    • Heap 페이지로 이동
    • typescript 페이지로 이동
    • AbortController
    • Async Iterator와 제너레이터
    • CommonJS와 ECMAScript Modules
    • 제너레이터(Generator)
    • Http Client
    • Node.js
    • npm vs pnpm 선택기준은 무엇인가요?
    • `setImmediate()`
  • kafka 페이지로 이동
    • Kafka 기본
    • Kafka를 사용하여 **데이터 정합성**은 어떻게 유지해야 할까?
    • 메시지 전송 신뢰성
  • linux 페이지로 이동
    • fsync — 리눅스 파일 동기화 시스템 콜
    • tmux — Terminal Multiplexer
  • network 페이지로 이동
    • L2(스위치)와 L3(라우터)의 역할 차이
    • L4와 VIP(Virtual IP Address)
    • IP Subnet
  • react 페이지로 이동
    • JSX 페이지로 이동
    • VirtualDOM 페이지로 이동
    • v16 페이지로 이동
  • resume 페이지로 이동
    • CJ 올리브영 지원 문항
  • task 페이지로 이동
    • ai-service-team 페이지로 이동
    • nsc-slot 페이지로 이동
    • sb-dev-team 페이지로 이동
    • the-future-company 페이지로 이동
📚FOS Study

개발 학습 기록을 정리하는 블로그입니다.

바로가기

  • 홈
  • 카테고리

소셜

  • GitHub
  • Source Repository

© 2025 FOS Study. Built with Next.js & Tailwind CSS

목록으로 돌아가기
🤖AI

AI 에이전트와 함께 MVP 만들기 — dooray-cli 사례

약 22분
2026년 4월 3일
GitHub에서 보기

AI 에이전트와 함께 MVP 만들기 — dooray-cli 사례

배경

이미 사내에 공유된 dooray-cli 구현체가 있다는 것은 알고 있었습니다. 완전히 처음부터 구현한 것은 아니고, 기존에 만들어둔 dooray-mcp-server를 CLI로 포팅하면서 에이전트 하네스 엔지니어링을 실험해본 것입니다. 여기에 메일 연동이나 파일 첨부 같은 기능도 직접 추가해보며, 에이전트가 자율적으로 동작할 수 있는 환경을 구축하는 방법론을 정리한 것이 이 문서입니다.

결론부터

양질의 컨텍스트 → 하네스 엔지니어링으로 MVP 구축 → 기능 추가와 문서화

이 세 단계를 거치면 AI 에이전트가 사람의 개입 없이 MVP를 구현할 수 있습니다. 프롬프트 한 줄로 앱을 만드는 것이 아닙니다. 에이전트가 자율적으로 동작할 수 있는 환경을 체계적으로 구축하는 것입니다.

이 문서는 Claude Code로 dooray-cli(Dooray REST API CLI 도구)의 MVP를 구축한 실제 사례를 바탕으로, 이 방법론을 단계별로 설명합니다. 전체 코드 및 실행법은 GitHub 레포지터리에서 확인할 수 있습니다.

에이전트가 잘 동작하는 이유는 코드를 잘 짜서가 아니라, 실행 전에 문서가 충분히 정제되어 있기 때문입니다.


하네스(Harness)란?

테스트 하네스가 테스트의 실행 환경을 제공하듯, 에이전트 하네스는 에이전트의 자율 실행 환경을 제공하는 구조입니다.

하네스 = 실행 계획 + 완료 조건 + 컨텍스트 참조

구체적으로는 다음과 같습니다:

  • 실행 계획: 무엇을 어떤 순서로 만들 것인가 (Phase 분리)
  • 완료 조건: 각 Phase가 언제 끝난 것인가 (빌드 성공, CLI 실행 등 기계적 판단 가능한 조건)
  • 컨텍스트 참조: 에이전트가 어떤 문서를 읽고 실행해야 하는가

하네스가 없으면 에이전트는 "다음에 뭘 해야 하지?"를 매번 사람에게 물어야 합니다. 하네스가 있으면 에이전트가 스스로 판단하고 진행합니다.


전체 흐름

1. 양질의 컨텍스트        — 대화로 기술적 결정을 깊이 있게 쌓습니다
2. 하네스 엔지니어링      — 문서를 기반으로 Phase를 분리하고 에이전트가 자율 구현합니다
3. 기능 추가와 문서화     — 추가 기능 구현 시 문서를 누적·정제하며 에이전트의 판단력을 높입니다

각 단계는 이전 단계의 산출물에 의존합니다. 1이 부실하면 2에서 에이전트가 방향을 잃게 됩니다. 3은 MVP 이후 기능을 추가할 때마다 반복하는 루프입니다.

대상 독자

  • Claude Code를 사용하는 개발자
  • AI 에이전트로 프로젝트를 자동화하고 싶은 분
  • "프롬프트 한 줄로 앱을 만든다"가 아닌, 체계적 접근법이 궁금한 분

참고 자료

  • Claude Code로 앱 만들기 — 에이전트 하네스 활용법
  • 장기 애플리케이션 개발을 위한 하네스 설계

실제 생성된 산출물 경로

이 프로젝트에서 실제로 생성된 파일들입니다. 하네스 엔지니어링을 적용할 때 참고하시면 됩니다.

컨텍스트 문서 (docs/)

  • docs/prd.md — 제품 요구사항 정의
  • docs/flow.md — 사용자 흐름
  • docs/data-schema.md — 데이터 스키마 설계
  • docs/code-architecture.md — 코드 아키텍처
  • docs/adr.md — 기술적 결정 기록 (ADR)

하네스 구조

  • prompts/task-create.md — Task/Phase 생성 가이드
  • scripts/run-phases.py — Phase 순차 실행 스크립트
  • tasks/implement-dooray-cli/ — v0.1.0 구현 시 실제 사용된 8개 Phase 파일

스킬

  • .claude/skills/plan-and-build/SKILL.md — 컨텍스트 빌딩 → 하네스 실행까지의 자동화 스킬

1. 양질의 컨텍스트 — 대화로 쌓기

목적

에이전트가 "무엇을 왜 어떻게" 만들어야 하는지 이해할 수 있는 양질의 컨텍스트를 대화로 만듭니다. 이 Phase가 전체 프로세스에서 가장 중요합니다. 여기서 쌓은 컨텍스트의 품질이 자율 실행의 성패를 결정합니다.

실제 대화 워크플로우

컨텍스트 빌딩은 하나의 대화 세션에서 순차적으로 진행합니다. 각 단계마다 에이전트에게 역할을 부여하고, "더 논의할 부분 없어?"를 반복하며, 모호한 점이 완전히 해소될 때까지 다음 단계로 넘어가지 않습니다. 아래는 dooray-cli를 만들 때 실제로 오간 대화입니다.

Step 1: 구현 가능성 검증 + 역할 부여

👤 사용자

"dooray-mcp-server 구조를 파악해서 dooray-cli 프로젝트로 포팅을 해보고자해.

지금부터 위 요구사항을 구현하기 위한 설계를 시작할 것이다. 
첫 단계는 구현 가능성 검증이다. 이 서비스가 실제로 구현 가능할지 기술적으로 검증해야 한다.

너는 나의 공동창업자고, 우리의 목표는 빠르게 스타트업을 만들어 
다음 Y Combinator batch에 합격하는 거다. 그걸 위해서 우리는 빠르게 MVP를 출시하고, 
시장의 반응 보면서 여러 가설을 테스트해야 한다. 속도가 생명이다. 
그러면서도 안정적인 서비스를 만들어야 한다. 이 둘간의 트레이드오프를 명심해라.

그럼 지금부터 논의를 시작하자. 너가 주도적으로 구현 가능성을 점검하고, 
조금이라도 모호하거나 구체화해야 할 것이 있다면 나와 논의하자."

🤖 에이전트 응답 (발췌)

## 기술 검증 결과

결론: 구현 가능, 그리고 생각보다 훨씬 빠르게 만들 수 있어.

### 핵심 결정 사항 (지금 논의 필요)

1. 언어/스택 선택

| 옵션 | 장점 | 단점 |
|------|------|------|
| Kotlin + Clikt | 기존 코드 100% 재사용 | JVM 스타트업 느림 |
| Go + Cobra | 단일 바이너리, 빠른 스타트업 | API 클라이언트 새로 작성 |
| TypeScript + Commander | 빠른 개발, npm 생태계 | node 의존성 |

내 추천: Kotlin + Clikt — 기존 코드 재사용으로 MVP를 가장 빠르게 낼 수 있어.

왜 주효했는가:

  • 역할 부여 ("공동창업자") — 에이전트가 단순 실행자가 아닌 의사결정 참여자로 행동하게 만듭니다
  • 가치관 명시 ("속도 vs 안정성 트레이드오프") — 이후 모든 결정에서 이 기준이 적용됩니다
  • 주도성 부여 ("나와 논의하자") — 에이전트가 먼저 3가지 기술 스택을 비교 분석하고 추천까지 제시했습니다. 수동적으로 "어떤 스택 쓸까요?"가 아니라 능동적으로 판단한 것입니다

Step 2: 기술 스택 선정

에이전트가 Kotlin을 추천했지만, 사용자가 자신의 경험에 기반해 다른 선택을 합니다:

👤 사용자

"내 생각엔 typescript + commander가 좋을 것 같아 난 ts 환경에 익숙하거든
npm 환경에 업로드하여 전체 공유가 되게 하도록 하면 좋을 듯해
그리고 또 놓친 부분이 없는지 확인해봐줘"

🤖 에이전트 응답 — "놓친 부분" 요청에 5가지 추가 설계 사항을 스스로 발견

## 추가로 발견한 설계 결정 사항들

1. DOORAY_BASE_URL가 필수 — config 명령어 vs env var 선택 필요
2. Project 캐시 전략 — CLI는 매번 새 프로세스라 디스크 캐시 필요
3. Pagination 처리 — --all 자동 페이징 필요
4. npm 패키지명 — @bifos/dooray-cli (scoped)
5. 기본 프로젝트 기능 — DOORAY_PROJECT_ID

👤 사용자 — 각 항목에 대해 결정을 내림

"1번은 방식 B가 좋을듯하네 저렇게 설정을 하고 설정 파일로 저장하면 좋겠네
2. 좋아 저런 디스크 캐시 방식으로 저장하면 성능상 유리할 것 같아
3. 응 페이지네이션처리하는게 좋아보여
4. @bifos/dooray-cli가 좋겠네
5번은 저건 빼주면 될거 같아

오케이 좋아, 그리고 하나 더 고려해봤으면 하는 점이 있어 
제목이나, 프로젝트명을 넣어서 검색할 수 있는 기능도 있으면 좋겠어"

왜 주효했는가:

  • "놓친 부분 확인해줘" — 이 한 마디로 에이전트가 5가지 추가 설계 사항을 스스로 발견했습니다
  • 사용자는 각 항목에 대해 짧게 결정만 내립니다 — 에이전트가 분석하고, 사용자가 판단하는 역할 분담이 자연스럽게 이루어집니다

Step 3: "더 논의할 부분 없어?" — 품질 게이트의 위력

설계가 확정된 것 같을 때, 이 질문 하나로 4가지 크리티컬한 이슈가 추가로 드러났습니다:

👤 사용자

"더 논의 할 부분은 없어? 진짜 넘어가도 돼?"

🤖 에이전트 응답 — "사실 몇 가지 더 있어"

1. organizationMemberId 문제 (UX 크리티컬)
   → post 생성 시 --to에 숫자 ID 대신 이름/이메일 지원 필요
   → MemberResolver 필요

2. Post body 입력 UX
   → --body-file, --body -, $EDITOR 방식 중 선택 필요

3. Exit code 설계
   → 스크립트에서 쓰려면 성공:0, API오류:1, 인증실패:2, 파라미터오류:3 필요

4. API key 발급 안내
   → dooray config --help에 발급 URL 명시 필요

👤 사용자

"응 memberResolver가 필요해보이고, 그 파일도 project-cache 처럼 
json형태로 자료 저장이 되는게 좋지 않을까?
2. 업데이트할 때 불편하겠다. 더 좋은 플로우 있으면 고민해봐줘"

🤖 에이전트 — $EDITOR 방식 제안 + 3가지 추가 발견

## Update 플로우 제안: $EDITOR 방식 (kubectl edit, git commit과 동일 UX)

dooray post edit my-project 42
→ 현재 업무 조회 → 임시 파일 생성 (YAML frontmatter + 본문) → $EDITOR → API 호출

## 추가로 놓친 것들
a. Workflow 이름 표시 — raw ID가 아닌 이름으로 표시 필요
b. dooray cache clear 커맨드 필요
c. dooray doctor — config 검증 도우미
d. --no-color 플래그 — CI 환경 지원

왜 주효했는가: 이 단계가 전체 프로세스에서 가장 많은 가치를 만들었습니다. "더 논의할 부분 없어?"라는 질문 하나로 MemberResolver, $EDITOR 플로우, doctor 커맨드 등 MVP의 핵심 기능이 추가되었습니다. 이 질문이 없었다면 구현 중에 발견되어 설계 변경이 필요했을 것입니다.

Step 4: 데이터 + 아키텍처 설계 (역할 재전환)

👤 사용자

"데이터 스키마 설계랑 코드 아키텍처 설계를 같이 해볼거야. 
이제 다시 마이크로소프트 시니어 개발자 출신의 CTO로 돌아오면 돼. 
지금까지 논의된 앱을 구현하기 위한 전반적 설계를 해보고, 
조금이라도 좀 모호해서 나랑 논의해서 결정해야 할 것이 있다면 전부 알려줘. 
우리 가치관 기억하지? 최대한 간결하고 빠르게 출시하는거야. 이거 명심해!"

🤖 에이전트 응답 — config/cache 스키마 + 코드 구조를 한 번에 설계

## 데이터 스키마

~/.dooray/config.json    # apiKey, baseUrl
~/.dooray/cache.json     # projects (1h TTL) + members (1h) + workflows (24h)

## 핵심 해소: Post 식별 방법
Post 타입에 number: Int 필드가 있어. GitHub Issue number와 동일한 개념.
→ dooray post get my-project 42  (캐시 불필요, API 1회 호출로 해결)

## 코드 아키텍처
src/
  api/client.ts        # ky 기반 HTTP 클라이언트
  resolvers/           # 자연어 → ID 변환 레이어 (핵심)
  commands/            # CLI 커맨드 정의
  ...

왜 주효했는가:

  • 역할 재전환 ("MS 시니어 개발자 출신 CTO") — 사용자 관점에서 다시 기술 관점으로 전환합니다
  • 가치관 재확인 ("간결하고 빠르게") — 에이전트가 과도한 설계를 하지 않도록 제어합니다
  • postNumber로 업무를 식별하는 핵심 설계가 이 단계에서 에이전트에 의해 발견되었습니다

Step 5: 세부 기술 결정 (ky, tsup 등)

👤 사용자

"http client는 axios보단 ky를 사용하도록하자 너의 의견은 어떤지도 궁금하네
더 논의해야할 부분이 있다면 알려줘"

🤖 에이전트 — ky에 동의하되 기술적 근거를 제시

ky가 맞아. 이유:
- Native fetch 기반 → Node 18+ 환경에서 추가 의존성 없음
- 번들 크기 3KB vs axios 13KB (CLI 툴에서 유의미)
- 단, Node 18+ 필수. package.json에 engines: { node: ">=18" } 명시 필요.

마지막 결정 사항 1개 — 빌드 툴: tsc vs tsup
tsup 강력 추천: 단일 번들 출력, 설정 거의 필요 없음, esbuild 기반 10배 빠른 빌드

👤 사용자

"tsup으로 하자 esbuild가 최고지
더 논의할거 있나? 진짜 마지막으로 말야"

🤖 에이전트 — env var 폴백 제안

진짜로 다 됐어. 한 가지만 짚고 끝내자.
env var 폴백 — CI/스크립트 환경을 위해 config 파일 없어도 동작하게:
DOORAY_API_KEY=xxx dooray post list my-project

👤 사용자

"폴백은 없게해야해 DOORAY_API_KEY에 대한 폴백이 어떻게 있겠니 
없다면 dooray config를 세팅하라고 알려줘야해"

🤖 에이전트

맞아. 보안상 API key를 env var로 노출하는 건 안 좋아.
설계 완전 확정. 구현 시작한다.

왜 주효했는가: 에이전트가 마지막까지 놓친 부분(env var 폴백)을 제안했지만, 사용자가 보안 관점에서 거부했습니다. 에이전트의 제안을 무조건 수용하지 않고 판단하는 것도 품질 게이트의 일부입니다.

Step 6: 최종 문서 생성 — 구현 전에 반드시

👤 사용자 — 에이전트가 "구현 시작한다"고 했지만, 사용자가 멈춤

"잠시만 구현하기전에 이렇게하자

좋아. 고생했어. 이제 우리가 지금까지 논의한 내용을 바탕으로 문서 생성하자.
다음 문서들이 필요하다: prd, flow, data-schema, code-architecture, adr

이 문서는 AI 에이전트를 위한 것이다. 그들의 컨텍스트를 낭비하지 않도록, 
같은 내용도 더 간결하게 쓸 수 있도록 해야 한다. 간결한 문서를 추구하되, 
의사결정 의도와 같은 맥락적 정보가 아예 제거되어서도 안 된다."

🤖 에이전트 — 5개 문서 즉시 생성

docs/
  prd.md              # 제품 목적·범위·성공지표
  flow.md             # 주요 사용자 흐름
  data-schema.md      # config·cache 스키마 + 5개 Resolver 로직
  code-architecture.md # 디렉터리 구조·모듈 의존관계
  adr.md              # 9개 기술 결정 (TypeScript·ky·tsup·캐시·postNumber 등)

왜 주효했는가:

  • "구현 시작한다"를 멈추고 문서부터 — 이것이 하네스 엔지니어링의 핵심입니다. 대화에서 쌓은 컨텍스트를 문서로 정제하지 않으면, 다음 대화에서 에이전트는 이 맥락을 잃습니다
  • 문서의 대상을 명시 ("AI 에이전트를 위한 것") — 사람을 위한 장황한 문서가 아닌, 에이전트가 효율적으로 소비할 수 있는 간결한 문서를 생성하게 만듭니다
  • 간결함과 맥락 보존의 균형 — "간결하되 의사결정 의도는 보존"이라는 기준이 있어야 에이전트가 적절한 수준의 문서를 생산합니다

대화 워크플로우의 핵심 패턴

위 단계들을 관통하는 3가지 패턴입니다:

1. 역할 부여로 관점을 전환합니다

단계역할관점
구현 가능성공동창업자비즈니스 + 기술
사용 흐름구글 시니어 UX리서처사용자 경험
데이터/아키텍처MS 시니어 개발자 CTO기술 설계
기술 평가구글 시니어 엔지니어코드 품질

역할을 부여하면 에이전트가 해당 관점에서 깊이 있게 분석하고, 그 관점에서만 보이는 문제를 제기합니다.

2. "더 논의할 거 없어?"를 반복합니다

모든 단계의 끝에서 이 질문을 던집니다. 에이전트는 효율을 위해 "충분하다"고 빨리 넘어가려는 경향이 있습니다. 이 질문이 품질 게이트 역할을 합니다.

3. 논의 → 결정 → 기록을 순환합니다

대화에서 논의 → "이걸로 가자" 결정 → 문서에 반영 → 다음 주제

문서에 반영되지 않은 결정은 다음 대화에서 잊혀집니다. 반드시 기록해야 합니다.

산출물

이 Phase에서 만들어진 문서는 다음과 같습니다:

문서내용역할
docs/prd.md한 줄 정의, 문제, 타겟, 범위에이전트의 "왜"
docs/adr.md기술 결정 + 이유 + 재검토 시점에이전트의 "어떻게"
docs/code-architecture.md디렉토리 구조, 모듈 의존에이전트의 "어디에"
docs/data-schema.mdconfig, 캐시, resolver 스키마에이전트의 "무엇을"
docs/flow.md사용자 흐름에이전트의 "어떤 순서로"

2. 하네스 엔지니어링 — MVP 구축

하네스의 핵심 구성 요소

1. Phase 정의      — 무엇을 만들 것인가 (범위)
2. 실행 순서        — 어떤 순서로 만들 것인가 (의존성)
3. 완료 조건        — 언제 끝난 것인가 (검증)
4. 컨텍스트 참조    — 어디를 보고 만들 것인가 (문서)

dooray-cli의 Phase 분리

phases:
  - name: "v0.1.0 — Core CRUD"
    scope:
      - config/doctor/cache 커맨드
      - project 조회 (목록, 멤버, 워크플로우)
      - post CRUD (목록, 검색, 조회, 생성, 수정, 완료, 상태변경)
      - comment CRUD (목록, 추가, 수정, 삭제)
      - wiki (목록, 페이지 조회, 생성, 수정)
    context:
      - docs/prd.md (MVP 범위)
      - docs/code-architecture.md (디렉토리 구조)
      - docs/data-schema.md (캐시, config 스키마)
      - docs/adr.md (기술 결정)
    completion:
      - pnpm run build 성공
      - dooray --help 출력 확인
      - dooray doctor 실행 성공 (API 연결 검증)
      - dooray post list <project> 실행 성공

Phase 분리의 핵심 원칙

  1. 각 Phase는 독립 배포 가능해야 합니다 — v0.1.0 없이 v0.2.0은 불가하지만, v0.2.0 없이 v0.1.0은 완전히 동작합니다
  2. 완료 조건은 자동 검증 가능해야 합니다 — "코드가 깔끔한가"가 아니라 "빌드 성공 + CLI 실행 성공"처럼 기계적으로 판단 가능한 조건이어야 합니다
  3. 컨텍스트 참조를 명시해야 합니다 — 에이전트가 어떤 문서를 읽고 실행해야 하는지 알려줘야 합니다

SKILL.md로 하네스 구성

Claude Code에서는 스킬 파일로 하네스를 구성할 수 있습니다.

.claude/skills/
  plan-and-build/
    SKILL.md        # 하네스 정의 (Phase 목록, 실행 순서, 완료 조건)

스킬 파일 예시 (.claude/skills/plan-and-build/SKILL.md):

---
name: plan-and-build
description: docs/ 폴더의 문서를 기반으로 Phase별 순차 구현을 실행
---

# plan-and-build

## 실행 절차

1. docs/ 폴더의 모든 문서를 읽어 프로젝트 컨텍스트를 파악한다
2. 현재 구현 상태를 파악한다 (git log, 디렉토리 구조)
3. 다음 미완성 Phase를 식별한다
4. 해당 Phase의 scope에 따라 코드를 구현한다
5. 완료 조건을 검증한다 (빌드, CLI 실행)
6. 검증 통과 시 다음 Phase로 진행한다
7. 모든 Phase 완료 시 종료한다

## 규칙

- 각 Phase 시작 전 반드시 context에 명시된 문서를 읽는다
- 완료 조건을 모두 통과해야 다음 Phase로 넘어간다
- 완료 조건 실패 시 자동으로 디버깅을 시도한다
- 3회 연속 실패 시 사용자에게 개입을 요청한다

심플 하네스 세팅 예시 — 처음부터 만들기

모든 프로젝트가 SKILL.md를 사용할 필요는 없습니다. 다음은 대화 시작 시 직접 전달하는 심플한 하네스 세팅 예시입니다.

중요: 아래 프롬프트에서 참조하는 prompts/task-create.md나 scripts/run-phases.py는 처음에 존재하지 않아도 됩니다. dooray-cli를 만들 때도 이 파일들은 없는 상태에서 시작했습니다. 이 프롬프트를 에이전트에게 전달하면, 에이전트가 필요한 파일들을 직접 생성합니다. 하네스 인프라 자체를 에이전트에게 구축하게 하는 것이 핵심입니다.

다음 과정에 따라 작업 논의 및 구현을 진행하자:

1. 먼저 /docs 하위 경로의 문서들을 적절히 읽어 이 프로젝트의 기획, 디자인, 
   아키텍처, 설계의도를 파악한다. 필요시 여러 Explore 에이전트를 병렬로 사용한다.
2. 이번 작업을 구현하기 위해 더 구체화해야할 점, 기술적으로 논의해야할 점이 
   있다면 사용자에게 제시한 후 논의를 이어간다.
3. 사용자가 충분히 논의했다고 판단 후 구현계획 작성을 지시하면, 
   가장 먼저 /prompts/task-create.md 파일의 내용을 정확히 숙지한다. 
   이후 해당 방식으로 생성하기 위한 구현 계획을 여러 phase로 나뉜 초안을 작성하고, 
   논의점까지 포함하여 사용자에게 피드백을 요청한다.
4. 사용자가 충분히 논의했다고 판단 후 task 생성을 지시하면, 
   /prompts/task-create.md의 형식의 절차에 맞게 task와 phase 파일들을 생성한다.
5. scripts/run-phases.py를 실행해서 각 phase를 순차적으로 실행한다.
6. scripts/run-phases.py 종료 후, 종료 코드에 따라 사용자에게 알림을 보낸다:
   - exit 0 (성공): 모든 phase 완료. "✅ Task {name} 완료 (N phases)"
   - exit 1 (오류): phase 실행 중 오류 발생. "❌ Task {name} phase {n} 실패: {error}"
   - exit 2 (blocked): 사용자 개입 필요. "⚠️ Task {name} phase {n} blocked: {reason}"

실제로 dooray-cli에서는 위 프롬프트를 전달한 후 에이전트에게 추가로 요청했습니다:

👤 사용자

"이런 간단한 에이전트 하네스를 설정할 수 있게 워크플로가 계속하여 실행될 수 있게 
위 지침대로 파일을 만들어줄래? 현재 없는 파일이 /prompts/task-create.md이고 
scripts 파일들도 없어. 계속 실행 가능하며 안전한 에이전트 하네스망을 간단하게 구축해줄 수 있겠어?"

🤖 에이전트 — 하네스 인프라를 직접 생성

prompts/task-create.md     # Claude가 task 만들 때 읽는 가이드
scripts/run-phases.py      # phase 실행기 (exit 0/1/2 + 알림)
tasks/                     # task 파일들이 위치할 디렉터리

이 세팅의 핵심은 논의 → 계획 → 실행 → 알림이라는 흐름을 하나의 프롬프트로 정의한다는 점입니다. 파일이 없어도 괜찮습니다 — 에이전트가 만들어줍니다. 프로젝트 상황에 맞게 자유롭게 변형하여 자신만의 하네스를 구축해보세요.

실행 중 진행 상황 파악

하네스가 실행되는 동안 사용자가 완전히 손을 놓고 있어야 하는 것은 아닙니다. 진행 상황을 파악하는 두 가지 방법이 있습니다:

1. 산출물로 파악 — 하네스 실행 중 생성되는 파일들을 통해 현재 어디까지 진행되었는지 알 수 있습니다. tasks/{name}/index.json의 phase별 status 필드가 completed/in_progress/pending로 표시되며, 각 phase에서 생성된 코드와 빌드 결과물도 직접 확인할 수 있습니다.

2. 에이전트에게 직접 질문 — 실행 중인 대화에서 에이전트에게 "지금 어디까지 진행했어?"라고 물어볼 수 있습니다. 에이전트는 현재 phase, 완료된 작업, 남은 작업을 정리해서 알려줍니다. 막히는 부분이 있으면 이 시점에서 방향을 조정할 수도 있습니다.

에이전트가 자율적으로 동작할 수 있는 이유

에이전트가 코드를 잘 짜서가 아닙니다. 에이전트가 참조할 수 있는 문서가 충분히 정제되어 있기 때문입니다.

자율 실행이 가능했던 핵심 요인은 다음과 같습니다:

1. 문서가 "왜"를 포함합니다

# BAD — 무엇만 기록
"HTTP 클라이언트로 ky를 사용한다"

# GOOD — 왜를 함께 기록 (ADR)
"HTTP 클라이언트로 ky를 사용한다
 이유: fetch 기반으로 경량이고 axios 대비 번들 크기 작음
 재검토 시점: interceptor가 필요해지면 axios 검토"

"왜"가 있으면 에이전트가 엣지 케이스에서 스스로 판단할 수 있습니다. 예를 들어 파일 업로드에서 ky의 redirect 처리가 안 될 때, ADR에 "ky는 fetch 기반"이라는 맥락이 있으므로 fetch를 직접 사용하는 우회를 스스로 시도할 수 있습니다.

2. 완료 조건이 기계적입니다

# BAD — 주관적 완료 조건
"파일 다운로드 기능이 잘 동작하면 완료"

# GOOD — 기계적 완료 조건
"pnpm run build 성공 + dooray post file download tc-ocr 454 <file-id> 실행 시 파일 저장됨"

에이전트는 "잘 동작하는지"를 판단할 수 없지만, "빌드 성공 여부"와 "명령 실행 결과"는 판단할 수 있습니다.

3. 실패 시 복구 경로가 있습니다

dooray-cli에서 실제 발생한 사례입니다:

문제: 파일 다운로드 API가 404를 반환
원인: /files/{id}/downloads 경로가 아니라 /files/{id}?media=raw 였음
복구: 에이전트가 다양한 URL 패턴을 시도 → 정상 경로 발견 → ADR에 기록

이것이 가능했던 이유는 API 문서가 컨텍스트에 포함되어 있었기 때문입니다. 에이전트가 "이 API는 ?media=raw와 ?media=meta를 사용한다"는 정보를 문서에서 찾아 스스로 해결했습니다.

실행 프롬프트

하네스가 준비되면 실행은 간단합니다:

/plan-and-build

또는 직접 지시:

"docs/ 폴더를 모두 읽고, Phase 분리에 따라 v0.1.0부터 순차적으로 구현해줘.
각 Phase마다 빌드 검증하고, 실패하면 디버깅해서 통과시켜."

3. 기능 추가와 문서화 — MVP 이후의 루프

목적

MVP가 완성된 이후 새로운 기능을 추가할 때, 문서를 먼저 정제하고 → 구현 → 결과를 다시 문서에 반영하는 루프를 반복합니다. 문서가 누적될수록 에이전트의 판단력이 올라가고, 사람의 개입은 점점 줄어듭니다.

dooray-cli의 기능 추가 사례

v0.2.0 — 메일 연동

[대화 4] "메일 연동도 하고 싶은데"
         → IMAP/SMTP 기술 논의
         → Dooray IMAP 서버 한계 발견 (SINCE 미지원, SORT 미지원)
         → ADR-012, ADR-013 기록
         → docs/flow.md에 메일 흐름 추가

[대화 5] 에이전트가 구현 + 디버깅
         → imapflow UID 파라미터 이슈 자체 해결
         → tsup external 설정 이슈 자체 해결
         → npm publish v0.2.0

v0.3.0 — 파일 첨부

[대화 6] "파일 첨부 기능을 추가하고 싶어" + API 문서 제공
         → 307 리다이렉트 패턴 논의
         → ADR-015 기록

[대화 7] 에이전트가 구현
         → 다운로드 404 오류 → ?media=raw 경로 자체 발견
         → 업로드 ky redirect 이슈 → fetch 직접 사용으로 우회
         → 실제 API 테스트 전부 통과
         → npm publish v0.3.0

기능 추가 시 문서화 루프

새로운 기능을 추가할 때마다 다음 루프를 반복합니다:

┌─────────────────┐
│ 기능 논의        │ ← "메일 연동도 하고 싶은데"
└────────┬────────┘
         ▼
┌─────────────────┐     ┌──────────────┐
│ 기술적 결정      │──▶  │ ADR에 기록    │
└────────┬────────┘     └──────────────┘
         ▼
┌─────────────────┐     ┌──────────────┐
│ 에이전트 구현    │──▶  │ docs/ 업데이트│
└────────┬────────┘     └──────────────┘
         ▼
┌─────────────────┐
│ 검증 + 배포      │
└─────────────────┘

문서 검토 프롬프트

기능 추가 후 문서가 최신 상태인지 반드시 확인합니다:

검토 요청

"docs 폴더를 전체적으로 모두 확인한 거 맞아? 
docs 폴더를 순차적으로 먼저 읽고 업데이트 진행한 거야?"

왜 주효했는가: 에이전트는 효율을 위해 관련 파일만 읽는 경향이 있습니다. "전체를 확인했느냐"고 명시적으로 물어야 놓친 파일(이 경우 prd.md, flow.md)을 발견할 수 있습니다.

기술적 평가 요청

"api/types.ts 파일이 점점 커지고 있는데 types 폴더를 만들어서 분리하는 건 어때?
구글 시니어 엔지니어로서 기술적 평가를 부탁할게"

왜 주효했는가: 역할을 부여하면 에이전트가 찬성/반대 양면을 분석하고, 임계점 기준(예: 800줄)과 재검토 시점까지 제안합니다. 결과를 ADR로 기록하면 향후 같은 논의를 반복하지 않습니다.

결정 → 기록 루프

"오케이 그럼 아직 분리하지 않아도 되겠네. 이 논의까지 포함해서 docs 폴더를 업데이트하자"

패턴: 논의 → 결정 → 문서 반영. 이 루프를 모든 기술적 결정에 적용합니다.

문서가 누적되면서 달라지는 점

  1. 대화가 진행될수록 사람의 개입이 줄어듭니다 — v0.1.0은 논의 비중이 컸지만, v0.3.0은 API 문서만 전달하면 에이전트가 자체 해결합니다
  2. 문서가 누적되면서 에이전트의 판단력이 올라갑니다 — ADR, 스키마, 아키텍처 문서가 쌓일수록 에이전트가 맥락을 더 잘 이해합니다
  3. 디버깅도 자율적으로 수행합니다 — 에러 → 원인 분석 → URL 패턴 시도 → 해결 → ADR 기록까지 자동으로 이루어집니다

실제 사례: dooray-cli 타임라인

v0.1.0 — Core CRUD (하나의 대화 세션)

컨텍스트 빌딩 (~20회 대화)

👤 사용자

"dooray-mcp-server 구조를 파악해서 dooray-cli 프로젝트로 포팅을 해보고자해.
너는 나의 공동창업자고, 우리의 목표는 빠르게 스타트업을 만들어
다음 Y Combinator batch에 합격하는 거다. 속도가 생명이다."

에이전트가 3가지 기술 스택(Kotlin+Clikt, Go+Cobra, TypeScript+Commander)을 비교 제안했고, 사용자가 TypeScript를 선택한 뒤 "더 논의할 부분은 없어?"로 추가 이슈를 끌어냈습니다.

🤖 에이전트 ("더 논의할 부분 없어?"에 대한 응답)

사실 몇 가지 더 있어.

1. organizationMemberId 문제 (UX 크리티컬)
   → post 생성할 때 숫자 ID를 직접 입력해야 함 → MemberResolver 필요
2. Post body 입력 UX
   → 긴 마크다운을 CLI flag로 쓰는 건 현실적으로 불가능 → $EDITOR 방식 제안
3. Exit code 설계
   → 스크립트에서 쓰려면 성공/API오류/인증실패/파라미터오류 구분 필요
4. API key 발급 안내
   → 새 유저 온보딩 시 dooray config --help에 명시 필요

이 패턴을 반복하며 ky vs axios 비교, tsup 빌드 설정, 캐시 TTL 전략 등을 확정한 뒤, 모든 결정을 문서로 정리했습니다.

👤 사용자

"지금까지 논의한 내용을 바탕으로 문서 생성하자.
prd, flow, data-schema, code-architecture, adr 문서가 필요하다.
AI 에이전트를 위한 것이다. 컨텍스트를 낭비하지 않도록 간결하게 쓰되,
의사 결정 의도와 같은 맥락적 정보가 제거되어서도 안 된다."

→ docs/ 하위에 5개 문서 생성 완료

하네스 실행 (~25분, 8 phases)

👤 사용자

"응 task 파일 생성하고 해당 페이즈를 계속해서 실행해줘
내가 개입이 필요할때만 알려줘"

에이전트가 8개 Phase(프로젝트 초기화 → Config/Cache → API 클라이언트 → Formatters → Post 읽기 → Post 쓰기 → Wiki → 통합 검증)를 순차 실행하여 약 25분 만에 전체 구현을 완료했습니다. Phase 4부터 실제 API 호출이 필요한데, 에이전트가 기존 MCP 서버 .env에서 config를 미리 설정해두어 끊김 없이 진행했습니다.

→ npm publish v0.1.0

v0.2.0 — Mail (같은 대화 세션)

👤 사용자

"이제 나 메일 연동도 하고 싶은데 말야
메일을 읽어서 이번주 해야할 업무나 알림등을 연동하기 좋아보여서 말야
그런데 공식적으로 지원하는 API는 없어

두레이의 IMAP, SMTP 연동 설정 값들을 활용하여 스크립트로
이메일 전송/확인이 가능한 것 같습니다.
구글 시니어 엔지니어로써 생각해봐줘"

🤖 에이전트

시니어 엔지니어 관점에서 정리해볼게요.

## IMAP/SMTP 방식 분석

### 가능한 것
- IMAP으로 메일 읽기: 받은편지함, 안읽은 메일, 날짜 필터링
- SMTP로 메일 보내기: 두레이 메일 주소로 발송
- Node.js 라이브러리: imapflow (IMAP), nodemailer (SMTP) — 둘 다 성숙한 라이브러리

### 먼저 확인이 필요한 것
1. 두레이 IMAP 서버 정보 — 호스트, 포트, TLS 설정
2. 인증 방식 — ID/PW인지, 앱 비밀번호인지, OAuth인지
3. 메일 구조 — 두레이 알림 메일의 제목/본문 패턴이 일정한지

사용자가 IMAP 서버 정보(imap.dooray.com:993)를 제공한 뒤, 에이전트가 IMAP 연결 검증 → SINCE 미지원 발견 → 우회 전략 수립 → 구현 → SMTP 발송까지 자율적으로 완료했습니다.

→ ADR-012(IMAP 한계), ADR-013(SMTP 설정) 기록 → npm publish v0.2.0

v0.3.0 — File Attachment (같은 대화 세션)

👤 사용자

"이제 이걸 처리해볼까 하는데
우리는 업무나, 댓글에 파일을 첨부할 수 있는 기능이 있어
이 파일 첨부와, 다운로드를 cli로 처리할 수 있으면 좋을듯한데 말야
그러면 ai agents에게 첨부파일을 확인해서 분석까지 맡길 수 있을듯해서 말야"

사용자가 Dooray 파일 API 문서를 제공하자, 에이전트가 307 리다이렉트 패턴을 파악하고 구현을 시작했습니다. 다운로드에서 404 오류가 발생하자 에이전트가 자체적으로 디버깅했습니다:

🤖 에이전트 (디버깅 과정)

307 리다이렉트 처리에 문제가 있다. ky가 non-2xx를 에러로 처리하는 것 같다. 디버깅해보자.

→ 핵심을 찾았다! ?media=raw 파라미터를 사용하는 패턴이다.
  다운로드는 /files/{file-id}?media=raw, 메타데이터는 ?media=meta.

→ ?media=raw가 307 리다이렉트를 반환한다. 리다이렉트 URL로 실제 다운로드가 되는지 확인하자.

에이전트가 404 → ?media=raw 경로 발견 → 307 리다이렉트 수동 처리 → 업로드는 ky의 redirect 이슈로 fetch 직접 사용 우회까지 자율적으로 해결했습니다.

→ ADR-015(307 리다이렉트) 기록 → npm publish v0.3.0


핵심 원칙 요약

1. 문서가 코드보다 먼저

코드를 작성하기 전에 PRD, ADR, 아키텍처 문서를 먼저 만듭니다. 에이전트가 참조할 수 있는 컨텍스트가 없으면 자율 실행은 불가능합니다.

2. "왜"를 기록합니다

모든 기술적 결정은 ADR로 기록합니다. 결정뿐 아니라 이유와 재검토 시점을 함께 기록해야 에이전트가 엣지 케이스에서 판단할 수 있습니다.

3. Phase는 독립 배포 단위로

각 Phase가 끝나면 독립적으로 동작하는 제품이어야 합니다. 이래야 중간에 실패해도 이전 Phase의 결과물은 보존됩니다.

4. 완료 조건은 기계적으로

"잘 동작하면 완료"가 아니라 "빌드 성공 + 이 명령 실행 시 이 결과"처럼 에이전트가 자동으로 판단할 수 있는 조건을 정의합니다.

5. 놓친 점은 반드시 물어봅니다

에이전트는 효율을 추구하느라 일부를 건너뛸 수 있습니다. "전체 다 확인했어?"라고 명시적으로 물어야 빠진 부분을 발견할 수 있습니다.

6. 논의 → 결정 → 기록 루프

기술적 논의가 끝나면 반드시 결정을 내리고, 결정을 문서에 반영합니다. 문서에 없는 결정은 다음 대화에서 잊혀집니다.


시작하기

여러분의 프로젝트에 하네스 엔지니어링을 적용해 MVP를 만들려면 다음과 같이 진행하시면 됩니다:

Step 1: Claude Code와 대화하면서 양질의 컨텍스트 쌓기

에이전트에게 역할을 부여하고, 기술적 결정을 깊이 있게 논의합니다. 핵심은 "더 논의할 부분 없어?"를 반복하여 에이전트가 놓친 이슈를 끌어내는 것입니다.

"나는 [문제]를 해결하기 위해 [도구]를 만들려고 해.
너는 나의 공동창업자고, 우리의 목표는 빠르게 MVP를 출시하는 거다.
지금부터 구현 가능성을 점검하고, 모호하거나 구체화해야 할 것이 있다면 논의하자."

기술 스택, 데이터 스키마, 에러 처리, UX 플로우 등 모든 결정이 확정될 때까지 대화를 이어갑니다. 결정이 확정되면 문서로 정리합니다:

"지금까지 논의한 내용을 바탕으로 문서 생성하자.
prd, flow, data-schema, code-architecture, adr 문서가 필요하다.
AI 에이전트를 위한 것이다. 간결하게 쓰되, 의사 결정 의도는 유지해줘."

Step 2: 하네스 세팅

논의가 끝나고 문서가 준비되면, 에이전트에게 하네스 구조를 만들어달라고 요청합니다. prompts/task-create.md나 scripts/run-phases.py 같은 파일이 아직 없어도 괜찮습니다 — 에이전트에게 요구사항을 설명하면 이 파일들을 함께 만들어줍니다.

"이제 구현을 Phase로 나누자.
각 Phase는 독립 배포 가능하고, 완료 조건은 기계적으로 정의해줘.
Phase를 순차 실행하는 스크립트와 task 생성 가이드도 함께 만들어줘."

Step 3: 실행

"task 파일 생성하고 해당 페이즈를 계속해서 실행해줘.
내가 개입이 필요할 때만 알려줘."

실행 중 진행 상황은 두 가지로 파악할 수 있습니다:

  • 산출물 확인: 생성되는 파일, 빌드 로그, Phase 완료 상태를 직접 확인
  • 에이전트에게 질문: "지금 어디까지 진행됐어?" — 현재 상태를 즉시 알려줍니다

Step 4: 기능 추가 시 문서 루프 반복

"[새 기능]을 추가하고 싶은데. [역할]로써 기술적으로 검토해봐줘."
→ 논의 + ADR 기록 → 구현 → docs/ 업데이트

이것이 전부입니다. 문서의 품질이 곧 결과물의 품질입니다.

AI 카테고리의 다른 글 보기수정 제안하기

댓글

댓글을 불러오는 중...
  • AI 에이전트와 함께 MVP 만들기 — dooray-cli 사례
  • 배경
  • 결론부터
  • 하네스(Harness)란?
  • 전체 흐름
  • 대상 독자
  • 참고 자료
  • 실제 생성된 산출물 경로
  • 1. 양질의 컨텍스트 — 대화로 쌓기
  • 목적
  • 실제 대화 워크플로우
  • Step 1: 구현 가능성 검증 + 역할 부여
  • 기술 검증 결과
  • 핵심 결정 사항 (지금 논의 필요)
  • Step 2: 기술 스택 선정
  • 추가로 발견한 설계 결정 사항들
  • Step 3: "더 논의할 부분 없어?" — 품질 게이트의 위력
  • Update 플로우 제안: $EDITOR 방식 (kubectl edit, git commit과 동일 UX)
  • 추가로 놓친 것들
  • Step 4: 데이터 + 아키텍처 설계 (역할 재전환)
  • 데이터 스키마
  • 핵심 해소: Post 식별 방법
  • 코드 아키텍처
  • Step 5: 세부 기술 결정 (ky, tsup 등)
  • Step 6: 최종 문서 생성 — 구현 전에 반드시
  • 대화 워크플로우의 핵심 패턴
  • 산출물
  • 2. 하네스 엔지니어링 — MVP 구축
  • 하네스의 핵심 구성 요소
  • dooray-cli의 Phase 분리
  • Phase 분리의 핵심 원칙
  • SKILL.md로 하네스 구성
  • plan-and-build
  • 실행 절차
  • 규칙
  • 심플 하네스 세팅 예시 — 처음부터 만들기
  • 실행 중 진행 상황 파악
  • 에이전트가 자율적으로 동작할 수 있는 이유
  • 1. 문서가 "왜"를 포함합니다
  • BAD — 무엇만 기록
  • GOOD — 왜를 함께 기록 (ADR)
  • 2. 완료 조건이 기계적입니다
  • BAD — 주관적 완료 조건
  • GOOD — 기계적 완료 조건
  • 3. 실패 시 복구 경로가 있습니다
  • 실행 프롬프트
  • 3. 기능 추가와 문서화 — MVP 이후의 루프
  • 목적
  • dooray-cli의 기능 추가 사례
  • v0.2.0 — 메일 연동
  • v0.3.0 — 파일 첨부
  • 기능 추가 시 문서화 루프
  • 문서 검토 프롬프트
  • 검토 요청
  • 기술적 평가 요청
  • 결정 → 기록 루프
  • 문서가 누적되면서 달라지는 점
  • 실제 사례: dooray-cli 타임라인
  • v0.1.0 — Core CRUD (하나의 대화 세션)
  • 컨텍스트 빌딩 (~20회 대화)
  • 하네스 실행 (~25분, 8 phases)
  • v0.2.0 — Mail (같은 대화 세션)
  • IMAP/SMTP 방식 분석
  • 가능한 것
  • 먼저 확인이 필요한 것
  • v0.3.0 — File Attachment (같은 대화 세션)
  • 핵심 원칙 요약
  • 1. 문서가 코드보다 먼저
  • 2. "왜"를 기록합니다
  • 3. Phase는 독립 배포 단위로
  • 4. 완료 조건은 기계적으로
  • 5. 놓친 점은 반드시 물어봅니다
  • 6. 논의 → 결정 → 기록 루프
  • 시작하기
  • Step 1: Claude Code와 대화하면서 양질의 컨텍스트 쌓기
  • Step 2: 하네스 세팅
  • Step 3: 실행
  • Step 4: 기능 추가 시 문서 루프 반복