결론부터: Claude Fable 5로 pulsecheck이라는 CLI를 0에서 만들었습니다. YAML에 적어 둔 URL·API 엔드포인트가 살아 있는지 일괄 확인하고, 결과를 JSON으로 떨어뜨려 cron이나 알림 스크립트에 바로 붙일 수 있습니다. 글은 두 갈래입니다. 먼저 이 도구가 어떤 문제를 푸는지, 완성품은 어떻게 쓰는지(아래 설명·스크린샷). 이어서 일곱 단계로 Claude Code 안에서 AI가 어떤 코드를 썼고, 어디는 반드시 사람이 정해야 하는지 복기합니다. 용도만 빠르게 보려면 스크린샷까지; 직접 따라 하려면 1단계부터.
pulsecheck은 무엇에 쓰나?
한 줄 요약: 여러 URL/API가 지금 정상 응답하는지 브라우저나 curl을 하나씩 치지 않고 확인합니다.
전형적 흐름: 운영에서 지켜볼 주소를 config.yaml에 넣습니다(/health, /ping 등). cron으로 5분마다 pulsecheck을 돌리면, 503이나 타임아웃이 나온 항목이 있을 때 종료 코드가 1이 되어 기존 알림·모니터링 파이프라인이 잡아냅니다. 가벼운 순찰 스크립트이지, 풀 모니터링 플랫폼은 아닙니다 — 대시보드·SMS 없이 「이 URL 묶음이 지금 살아 있나」만 JSON으로 보고합니다.
쓰임새: 실전 시나리오 세 가지
Go·YAML·JSON 이야기는 잠깐 미뤄 두고, 「이 서비스들이 아직 살아 있나」를 아는 게 핵심입니다. 아래 세 경우가 pulsecheck을 만든 이유입니다.
- 정기 순찰 — 헬스체크 URL이 5~20개(결제 콜백, 공개 API, 내부 게이트웨이). 예전엔
for url in ...; do curl ...셸 루프로 유지보수가 힘들고 리포트 형식도 들쭉날쭉했습니다. pulsecheck은 설정 한 파일을 읽고 구조화된 JSON을 냅니다. cron만 걸면 됩니다. - 배포·온콜 전 수동 확인 — 배포 전 한 줄:
./pulsecheck -config prod.yaml -o /tmp/pre-deploy.json. 전부 green(종료 코드 0)일 때만 배포; 하나라도 red(종료 코드 1)면 멈춥니다. - 알림용 「프로브」 — Prometheus 풀스택이 과할 때, 종료 코드로 기존 스크립트에 연결: 1이면 Webhook
curl이나 메일. JSON은 사후 로그용.
하지 않는 일: 시계열 트렌드, SMS 알림, 멀티테넌트 콘솔 — Datadog·클라우드 모니터링 영역입니다. pulsecheck은 지금 이 URL 묶음이 통하는지만 봅니다.
완성 스크린샷
아래는 pulsecheck을 전부 끝낸 뒤 Mac 터미널에서 돌린 실제 화면입니다. 설정 읽기, URL 프로브, JSON 출력 — 한 사이트가 503이라 종료 코드는 1입니다.
./pulsecheck -config config.example.yaml -o report.json; 오른쪽 report.json에 각 URL의 상태 코드, 지연, 건강 여부(ok).로컬에서 똑같이 돌리려면 세 줄이면 됩니다.
./pulsecheck -config config.example.yaml -o report.json echo $? # 1 = 비정상 URL 있음 cat report.json # 리포트 확인
입력 / 출력 / 기술 형태
용도를 이해했다면 기술적으로 어떻게 도는지 봅니다. 「curl 여러 번 + 한 장 리포트」를 컴파일 가능·cron 친화 CLI로 만든 형태입니다.
| 축 | 설명 | 예시 |
|---|---|---|
| 입력 | 검사할 URL 목록이 있는 YAML | config.example.yaml |
| 출력 | JSON 헬스 리포트 + 프로세스 종료 코드 | report.json; 0=전부 green, 1=실패 있음 |
| 전형적 사용 | cron 순찰; 배포 전 수동 확인; 종료 코드로 알림 | 5분마다 */5 * * * * pulsecheck ... |
| 스택 | Go 1.22 단일 바이너리 | GUI·DB 없음 |
유지보수하는 건 YAML 한 파일뿐입니다. 프로브·집계는 pulsecheck이 합니다. 예시:
targets: - https://api.example.com/health - https://status.example.com/ping
완성 후 저장소는 Go 약 400줄, 구조는 다음과 같습니다.
pulsecheck/ ├── cmd/pulsecheck/main.go # 진입점: -config -o ├── internal/checker/checker.go # HTTP 전송, 지연 기록 ├── internal/config/config.go # YAML 파싱 ├── config.example.yaml ├── Makefile · README.md └── .github/workflows/ci.yml
후반: 7단계에서 AI가 쓴 것
여기까지로 pulsecheck이 무엇인지, 왜 쓰는지는 정리됐습니다. 이제 만드는 과정입니다. Claude Fable 5 + Claude Code로 빈 폴더에서 v0.1.0 tag까지, AI가 어떤 파일을 냈고 사람이 꼭 끼어든 단계는 어디인지 봅니다.
역할 한 줄: AI는 코드·테스트; 사람은 「무엇을 할지/안 할지」·Review 반려·최종 출시 서명. 아래 7단계는 Prompt를 그대로 복사해 재현할 수 있습니다. 모델은 Claude Code의 Fable 5면 충분합니다(Opus까지 갈 필요 없음 — 티어 비교 참고).
환경 준비
- Go 1.22+ —
go version으로 확인 - Claude Code CLI — 모델 Claude Fable 5(일상 Agent 루프에 충분, 모델 티어 비교)
- 빈 디렉터리 —
mkdir pulsecheck && cd pulsecheck && git init - (선택) GitHub 저장소 — 6단계에서 원격 CI; 로컬만 먼저 해도 됨
1단계: 저장소·요구사항
당신이 할 일: 고통을 세 문장으로 적고 SPEC.md로 고정합니다. 직접 쓰거나 말로 풀어 AI에 확장시켜도 되지만, 비목표는 사람이 반드시 잘라냅니다(안 그러면 Web UI·DB가 붙습니다).
Read the requirements below and draft SPEC.md. Do not add any feature not listed: - Tool name pulsecheck, Go 1.22 CLI - Read URL list from YAML config, concurrent HTTP GET - Write JSON report to path specified by -o - Fields: url, status_code, latency_ms, ok - Default timeout 5s, overridable via PULSECHECK_TIMEOUT - Exit codes: 0 all green, 1 any failure, 2 config error - Non-goals: no GUI, no DB, no Docker, no alert push
AI 산출물: SPEC.md. 확인할 것: 임의 기능 추가 여부; 검수 명령에 go test ./...가 있는지.
검수: cat SPEC.md — 「필수 / 비목표 / 종료 코드」 세 절이 있는지.
2단계: 프로젝트 골격
당신이 할 일: AI에게 뼈대만, 비즈니스 로직은 아직 시킵니다. 이 단계는 Fable 5가 거의 다 합니다.
Read SPEC.md and init Go module github.com/you/pulsecheck. Create project skeleton only, business logic returns stubs: - cmd/pulsecheck/main.go parses -config and -o - internal/config reads YAML - internal/checker empty impl - Makefile: test, lint, build - .github/workflows/ci.yml placeholder Require go build ./... to pass; no real HTTP logic yet.
AI 산출물: 위 디렉터리 트리 8개 파일. 소요 약 6분.
검수:
go build ./... ./pulsecheck -h # usage 표시
3단계: 프로브 로직·테스트
당신이 할 일: 테스트 먼저, 구현 나중을 요구합니다. 프로젝트에서 가장 「진짜 개발」 같은 단계 — AI가 go test를 돌리고, 실패하면 고쳐 green까지 반복합니다.
In internal/checker: 1. Write checker_test.go first with httptest for 200, 500, timeout 2. Implement checker.go: HTTP GET, record status_code and latency_ms 3. Loop go test ./... until all pass 4. Wire main.go: config → checker → write JSON to -o path
AI 산출물: 핵심 프로브 코드. 로직 요지(발췌):
func CheckURL(ctx context.Context, client *http.Client, url string) Result { start := time.Now() req, _ := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) resp, err := client.Do(req) if err != nil { return Result{URL: url, OK: false, LatencyMs: time.Since(start).Milliseconds()} } defer resp.Body.Close() ok := resp.StatusCode >= 200 && resp.StatusCode < 300 return Result{ URL: url, StatusCode: resp.StatusCode, LatencyMs: time.Since(start).Milliseconds(), OK: ok, } }
실측에서 Fable 5는 go test를 3라운드 돌렸고, 2라운드에 「타임아웃이 HTTP client에 안 들어감」 버그를 스스로 고쳤습니다. 사람은 코드를 안 건드렸습니다.
검수:
go test ./... -v # 테이블 드리븐 12케이스 전부 green
4단계: Review 수정
당신이 할 일: Code Reviewer 역할로 이슈 목록을 주고 AI가 고치게 합니다. 직접 고치면 AI가 피드백을 반영하는지 검증이 안 됩니다.
Apply these review comments; go test ./... must stay green: 1. Rename JSON field latency to latency_ms per SPEC 2. Use worker pool for multiple URLs, default max 10 concurrent 3. stdout only prints JSON report path hint; warn logs go to stderr
AI 산출물: worker pool, 필드 rename, 로그 분리. 사람: 이 세 가지를 고칠지 판단 — AI가 대신 못 합니다.
검수: go test ./... 여전히 green; URL 몇 개 돌려 JSON 필드명 확인.
5단계: 설정 파일·README
당신이 할 일: 운영이 copy-paste로 쓸 문서와 샘플 설정을 AI에 씁니다.
Generate config.example.yaml and README.md: - Install: go install or go build - Usage examples, exit code table (0/1/2) - cron example: run every 5 minutes and append logs - Do not invent subcommands that do not exist
AI 산출물:
targets: - https://api.example.com/health - https://status.example.com/ping
검수: example URL을 접근 가능한 주소로 바꾼 뒤 「완성 스크린샷」 절 명령으로 돌려 report.json 필드가 빠지지 않았는지.
6단계: GitHub Actions 연동
당신이 할 일: GitHub에 push하고 AI가 CI를 채우고, 실패 시 스스로 고치게 합니다.
Complete .github/workflows/ci.yml: - go test -race ./... - golangci-lint run - use go 1.22 If lint fails, read logs, fix, and recommit.
첫 lint에서 unused import가 났고, Fable 5가 CI 로그를 읽고 스스로 지웠습니다. 16GB Mac에서 -race가 Swap을 유발하면 race는 GitHub Runner나 Cloud Mac 노드로 — Claude Code 실행 환경 고르는 것과 같은 논리입니다.
검수: GitHub에서 CI 전부 green.
7단계: 검수 후 tag 출시
당신이 할 일: 마지막은 반드시 사람 손 — smoke test, tag. CHANGELOG 초안은 AI가 써도 되지만 출시 서명은 당신 몫입니다.
go test ./... make build ./pulsecheck -config config.example.yaml -o /tmp/report.json cat /tmp/report.json | jq . git add -A && git commit -m "feat: pulsecheck v0.1.0" git tag -a v0.1.0 -m "first release: YAML-driven HTTP health probe" git push && git push --tags
여기까지 오면 요구사항부터 출시까지 끝입니다. cron에 걸고 모니터링에 붙일 수 있는 CLI, 전 과정 약 52분.
v0.1 이후 확장 아이디어
v0.1에서 일부러 빼 둔 것: Slack 알림, Prometheus exporter, Docker 이미지. 새 Issue 열고 Fable 5에 맡기면 됩니다 — 소규모는 먼저 닫고, 그다음 반복.
단계별: AI가 한 일
프로젝트를 마친 뒤 보면 7단계 역할은 이렇게 정리됩니다.
| 단계 | AI (Fable 5) | 사람 필수 |
|---|---|---|
| 1 요구사항 | 구어를 SPEC 구조로 확장 | 비목표 삭제, 종료 코드 확정 |
| 2 골격 | 8개 파일, go build 통과 | Go 버전·모듈명 확인 |
| 3 구현 | 테스트 + checker + main 연결 | Spec 커버리지 확인 |
| 4 Review | 체크리스트대로 수정 | Review 의견 작성 |
| 5 문서 | README + config 샘플 | copy-paste로 실제 통과 |
| 6 CI | workflow + lint 수정 | 「green」의 정의 |
| 7 출시 | CHANGELOG 초안 | smoke test, tag |
코딩 산출물의 약 78%는 AI가 작성했습니다. 요구사항 가위질, Review 판단, tag 서명은 모델을 바꿔도 사람 몫입니다.
시나리오 선택 행렬
| 당신이… | 추천 | 이유 |
|---|---|---|
| AI와 첫 「끝까지」 소규모 프로젝트 | 본문 7단계 + 단계별 검수 명령 | 「AI가 강한가」 추상 논쟁보다 완성품이 빠름 |
| 운영/내부 CLI (pulsecheck 유사) | Go + Fable 5 Agent 루프 | 테스트 자가 실행, 테이블 드리븐 검수에 맞음 |
| 대외 SaaS / 사용자 데이터 | AI는 초안만 + Opus 보안 Review | 출시 책임을 Agent에만 맡기기 어려움 |
| 기존 저장소 일부 기능 | ② 건너뛰고 Issue에서 Agent 진입 | 골격은 이미 있음 |
| 16GB Mac + 장시간 CI | Agent는 로컬, race/빌드는 Cloud Mac | Swap을 모델 느림으로 오해하지 않게 |
| 일주일 안에 데모 | Spec 비목표 먼저 잠그고 Agent | scope 팽창으로 출시 못 하는 상황 방지 |
추천 조합 (겹쳐 쓰기)
- 1인 개발 — Fable 5로 ②~⑥; Cursor Tab으로 출시 전 미세 수정; Opus는 대외 서비스 Review만.
- 소규모 팀 — 저장소 템플릿에 7단계 checklist; 새 도구는 pulsecheck 플로우 복제; Agent는 Claude Code 프로덕션 워크플로에 연결.
- token 절약 — Spec 다듬기·CHANGELOG는 Gemini Flash; 코딩 루프는 Fable 5; 라우팅은 OpenRouter 가격 구조 참고.
MCP를 겹칠 때: MCP가 Issue·모니터링 컨텍스트를 끌어오고 Fable 5가 저장소를 수정합니다. ⑦ 출시 서명은 여전히 사람 권장입니다.
흔한 실수
- 실수 1: 무엇을 만들지 안 정하고 채팅 시작 — AI는 뭉뚱그린 제안만 줍니다. pulsecheck처럼 한 줄 목표부터.
- 실수 2: 2단계에서 비즈니스 로직까지 시킴 — 골격·구현이 섞이면 뒤에서 테스트가 어려움.
- 실수 3: 4단계 Review 생략 — JSON 필드명, stdout 오염 같은 디테일이 「완성품」에 남음.
- 실수 4: 7단계 없이 tag — smoke test 없으면 출시 아님.
- 실수 5: 16GB에서 race + Agent 동시 — 느려진 건 메모리; CI는 Runner / Cloud Mac으로.
FAQ
pulsecheck은 어떤 문제를 푸나?
「URL 묶음이 지금 접속 가능한가」 — 셸 curl 루프나 무거운 모니터링 없이. 개인·소규모 팀·배포 전 빠른 프로브에 맞습니다.
UptimeRobot·Prometheus와 뭐가 다른가?
pulsecheck은 내 머신에서 도는 가벼운 CLI, 설정이 내 손안, SaaS 의존 없음. 후자는 풀 모니터링 — 기능·비용 큼. 본문은 전자, 충분하고 코드도 내가 고칠 수 있게.
저장소를 clone하면 되나?
본문은 실측 복기 + 재현 튜토리얼입니다. 7단계 Prompt로 동등 구현을 만들면 되고, diff 한 줄까지 맞출 필요는 없습니다.
어느 단계에서 AI가 가장 많이 했나?
3단계(테스트·구현)와 2단계(골격)는 Fable 5가 거의 전부; 1·7단계는 사람 비중이 큽니다.
Cursor Tab 자동완성과 뭐가 다른가?
Tab은 단일 파일 수정에 강함; 끝까지 가려면 Claude Code 다중 파일 + 테스트 실행. Copilot vs Cursor 실측 참고.
마무리
완성품: pulsecheck — YAML의 URL을 읽어 일괄 온라인 여부 확인, report.json 출력(위 스크린샷). 과정: Claude Fable 5로 빈 디렉터리에서 v0.1.0 tag까지 7단계; Go 코드·테스트 대부분은 AI, 사람은 범위·Review·출시. 「AI가 소규모를 할 수 있나」만 보려면 스크린샷과 입출력 표면으로 충분하고, 직접 하려면 1단계 Prompt부터 복사하면 됩니다.
ZavCloud · Cloud Mac
Cloud Mac에서 pulsecheck CI 돌리기
Mac mini M4 전용 인스턴스: Claude Code로 코드 작성, GitHub Actions는 같은 macOS 노드에서 test -race — 6단계가 16GB 로컬 RAM에 막히지 않게.
요금·플랜 보기