Claude Code 인사이트로 워크플로우 최적화하기

"ㅇㅇ 적용해" 두 글자로 시작한 바이브코딩 최적화 여정

·12분 읽기·조회 14

TL;DR

  • 136개 세션, 1,344개 메시지에 대한 /insights 리포트에서 잘못된 접근 38건, 버그 코드 30건, 요청 오해 19건 등 주요 마찰 포인트 발견
  • "이거 적용해줘" 한마디로 CLAUDE.md 8개 규칙, tsc 훅, preflight-deploy 스킬, 커스텀 에이전트까지 바이브코딩으로 구축
  • 인사이트 리포트가 제안한 것을 하나하나 읽지 않고, Claude에게 "뭐가 좋아? 적용해"라고 맡기는 워크플로우
  • "데이터에서 문제를 찾고, AI에게 해결을 맡기고, 자동화로 재발을 막는" 바이브코딩 개선 루프 확립

왜 이걸 했는지

Claude Code를 5주 동안 사용하면서 계속 같은 짜증이 반복됐습니다.

"아니 왜 또 상위 디렉토리에서 git을 실행해?" "그 API 키는 지난번에 줬잖아." "빌드가 깨지는 걸 왜 배포 시점에서야 알려주는 거야?"

감으로 짜증나는 건 알겠는데, 정확히 얼마나 자주, 어떤 유형으로 발생하는지는 몰랐습니다. 그래서 Claude Code의 /insights 명령을 실행했습니다.

이 명령은 지정한 기간 동안의 모든 세션 로그를 분석해서 사용 패턴, 마찰 포인트, 개선 제안을 담은 리포트를 생성합니다. 제 경우 136개 세션, 1,344개 메시지가 분석 대상이었습니다.


데이터가 보여준 것

숫자로 본 마찰 포인트

인사이트 리포트가 마찰 유형별로 건수를 집계해줍니다.

마찰 유형 발생 건수 의미
잘못된 접근 38건 잘못된 디렉토리, 도구, 범위로 시작
버그 코드 30건 빌드 실패가 배포 시점에서야 발견
요청 오해 19건 세션 간 컨텍스트 손실, 반복 설명
사용자 액션 거부 10건 Claude가 시작한 작업을 중단시킴

가장 많은 38건이 "잘못된 접근"이었습니다. Claude가 랜딩 페이지만 수정하면 되는데 전체 사이트 리디자인을 시작한다거나, 제가 명시적으로 요청한 Gemini 이미지 생성 스킬 대신 MCP 도구를 사용한다거나 하는 경우입니다.

두 번째로 많은 30건은 "버그 코드"입니다. DB 컬럼이 NULL 대신 DEFAULT false로 되어 있어서 동의 플로우가 안 되거나, 연도가 2026이 아니라 2016으로 설정되거나, isomorphic-dompurify가 Vercel에서 500 에러를 일으키거나 -- 이런 것들이 배포 직전이 아니라 코드 편집 시점에서 잡혔어야 했습니다.

잘 되고 있던 것들

리포트가 마찰만 보여주는 건 아닙니다. 잘 되고 있는 것들도 나옵니다.

  • 멀티 파일 변경 36건 성공: 12개 파일에 걸쳐 4개 관리자 기능을 한 세션에서 완성하는 식의 작업이 잘 되고 있었습니다
  • Task/TaskUpdate 370회 호출: 복잡한 작업을 서브태스크로 쪼개서 병렬 처리하는 패턴이 자연스럽게 자리 잡았습니다
  • 완전 달성률 50%, 대부분 달성 24%: 전체의 74%가 목표에 근접하거나 완전히 달성

문제는 나머지 26%에서 시간이 과도하게 소모된다는 것이었습니다. 마찰을 줄이면 그 시간을 되찾을 수 있습니다.


"뭐가 좋아? 적용해" -- 바이브코딩으로 최적화하기

리포트를 받고 나서 제가 한 건, 제안된 내용을 하나하나 읽는 게 아니었습니다. 솔직히 그렇게 세세하게 읽지 않았습니다. 대신 이렇게 물었습니다.

그중에 내가 적용하면 좋은 거 뭐가 있을까? 스킬이나 뭐 프롬프트나

Claude가 인사이트 데이터를 분석해서 우선순위를 매겨줬습니다. "CLAUDE.md에 규칙 추가하는 게 가장 효과 크고, tsc 훅이 그 다음, preflight-deploy 스킬도 만들면 좋겠다"는 식으로요.

그래서 저는 딱 두 글자만 쳤습니다.

ㅇㅇ 적용해

이 한마디로 Claude가 알아서:

  1. ~/.claude/CLAUDE.md 파일을 생성하고 8개 규칙을 작성
  2. .claude/settings.json에 tsc 훅을 설정
  3. preflight-deploy 스킬 파일을 생성
  4. 이 모든 파일을 올바른 경로에 배치

이게 바이브코딩의 핵심입니다. "무엇을 할지"는 데이터가 알려주고, "어떻게 할지"는 AI에게 맡기는 겁니다.

글로벌 vs 프로젝트 -- 잘못 넣으면 바로 잡기

그런데 Claude가 처음에 규칙을 프로젝트 단위 파일(MEMORY.md)에 넣었습니다. 이건 제가 원하는 게 아니었습니다.

아니.. 그 내가 자주하는 실수 보완하는 건데.. 당연히 글로벌에 넣어야지. 니가 제대로 잘 판단해봐

이 피드백 한 줄로 Claude가 구조를 수정했습니다. 프로젝트 파일에서 규칙을 빼고, 글로벌 ~/.claude/CLAUDE.md로 옮겼습니다. 바이브코딩에서 중요한 건 "처음부터 완벽한 프롬프트"가 아니라, "빠르게 방향을 잡아주는 피드백"입니다.


글로벌 CLAUDE.md -- 세션이 바뀌어도 규칙은 유지되게

이렇게 만들어진 ~/.claude/CLAUDE.md는 모든 프로젝트, 모든 세션에서 Claude Code가 읽는 글로벌 규칙입니다.

인사이트 리포트의 마찰 유형과 1:1로 대응하는 규칙이 들어갔습니다.

## Scope Discipline
- Do NOT expand scope beyond what the user explicitly asks
- If the user says 'landing page', do not redesign the entire site
- Apply changes completely the first time

## Project Structure Navigation
- Run `ls package.json` to confirm the correct working directory before proceeding
- Never run git commands from parent directory

## Environment & Keys
- Never ask the user to re-provide API keys or environment variables
- Check Vercel, .env files, or the deployment platform first

"Scope Discipline"은 잘못된 접근 38건 중 범위 확장 문제를, "Project Structure Navigation"은 잘못된 디렉토리 문제를, "Environment & Keys"는 API 키 재요청 문제를 직접 겨냥합니다.

핵심은 "구체적인 상황 + 구체적인 행동"으로 규칙을 쓰는 것입니다. "코드를 잘 작성해주세요" 같은 모호한 규칙은 효과가 없습니다. "랜딩 페이지라고 하면 전체 사이트를 리디자인하지 마세요"처럼, 실제로 발생했던 문제를 기반으로 구체적으로 쓰면 Claude가 정확히 따릅니다.


tsc 훅 -- "빌드 돌려봐" 안 해도 되게

버그 코드 30건 중 상당수는 TypeScript 타입 에러였습니다. 빌드를 돌려야 발견되는데, 기능을 다 만들고 나서야 빌드를 하니까 에러가 쌓여있는 겁니다.

Claude Code의 훅(Hook) 기능으로 이걸 해결했습니다. Edit이나 Write로 파일을 수정할 때마다 npx tsc --noEmit이 자동으로 돌아갑니다.

{
  "hooks": {
    "postToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "npx tsc --noEmit 2>&1 | head -20"
          }
        ]
      }
    ]
  }
}

head -20으로 출력을 20줄로 제한한 건, 에러가 많을 때 컨텍스트가 타입 에러 메시지로 넘치는 걸 방지하기 위해서입니다.

이 훅의 효과는 즉각적입니다. Claude가 파일을 수정하면 바로 다음 줄에 타입 에러가 표시되니까, Claude가 스스로 에러를 보고 고칩니다. "빌드 돌려봐" 같은 말을 할 필요가 없어졌습니다.


preflight-deploy 스킬 -- 배포를 한 단어로

배포 전에는 타입 체크보다 더 많은 검증이 필요합니다. 올바른 디렉토리인지 확인, 빌드 검증, console.log 잔재 확인, 하드코딩된 localhost URL 검출, 환경변수 누락 체크, 커밋, 푸시 -- 이걸 매번 수동으로 지시하는 건 현실적이지 않습니다.

/preflight-deploy라는 커스텀 스킬을 만들었습니다. Claude Code에서 이 한 단어를 입력하면 아래 단계가 순차적으로 실행됩니다.

### 1. 프로젝트 구조 확인
- git 루트 디렉토리 찾기, package.json 확인

### 2. 빌드 검증
- npm run build 실행, 실패 시 수정 후 재시도

### 3. 코드 품질 스캔
- console.log 잔재, localhost URL, 환경변수 누락 체크

### 4. 커밋 & 푸시
- 변경사항 스테이징 -> 커밋 메시지 생성 -> push

스킬 파일은 마크다운으로 작성된 프롬프트입니다. Claude Code가 이 파일을 읽고 각 단계를 자율적으로 실행합니다. "기능 구현 -> 배포"까지의 과정에서 빠뜨리기 쉬운 단계들을 자동으로 챙겨줍니다.


컨텍스트 관리 -- "이것도 조사해서 적용해줘"

CLAUDE.md, 훅, 스킬까지 만들고 나니, 추가로 궁금한 것들이 생겼습니다. 역시 하나하나 찾아보는 대신 Claude에게 한꺼번에 던졌습니다.

토큰 덜 쓰고 컨텍스트 관리 잘하는 방법도 조사해서 알려줘 최신 클로드코드 자료 위주로

70-75일때 컴팩트 자동으로 되게 설정할 수 있어? 그리고 클리어하면 대화내용 다 날라가? 왜냐면 내가 나중에 대화내용 보면서 개발블로그 쓸 거라 보존해야해. 그리고 컨텍스트 사용량 실시간으로 보여주는 플러그인이 있는지도 조사. 그리고 서브에이전트를 알아서 쓸 수 있도록 어디 설정해주면 좋겠어.

이 한 번의 메시지로 Claude가 3개의 리서치 에이전트를 병렬로 돌려서 조사하고, 결과를 바탕으로 다음을 적용했습니다.

statusline -- 컨텍스트 사용량을 눈으로 확인

#!/bin/bash
input=$(cat)
MODEL=$(echo "$input" | jq -r '.model.display_name // "?"')
PCT=$(echo "$input" | jq -r '.context_window.used_percentage // 0' | cut -d. -f1)
COST=$(echo "$input" | jq -r '.cost.total_cost_usd // 0')

# 사용률에 따라 색상 변경: 초록 -> 노랑 -> 빨강
if [ "$PCT" -ge 80 ]; then COLOR='\033[31m'
elif [ "$PCT" -ge 60 ]; then COLOR='\033[33m'
else COLOR='\033[32m'; fi

FILLED=$((PCT / 10)); EMPTY=$((10 - FILLED))
BAR=$(printf "%${FILLED}s" | tr ' ' '#')$(printf "%${EMPTY}s" | tr ' ' '-')
echo -e "${MODEL} | ${COLOR}[${BAR}] ${PCT}%${RESET} | \$${COST}"

터미널 하단에 항상 Opus | [######----] 60% | $2.34 같은 형태로 모델명, 컨텍스트 사용률, 비용이 표시됩니다. 60% 이상이면 노란색, 80% 이상이면 빨간색으로 바뀝니다.

codebase-researcher 에이전트 -- 컨텍스트를 지키는 파수꾼

"이 함수가 어디서 쓰이는지 찾아줘"라고 하면 20개 파일의 코드가 컨텍스트에 올라옵니다. 그러면 앞에서 논의했던 맥락이 밀려나가죠.

커스텀 에이전트를 만들어서 대규모 검색을 별도 컨텍스트에서 처리하게 했습니다.

---
name: codebase-researcher
description: Use PROACTIVELY when searching across 3+ files.
tools: Read, Grep, Glob, Bash
model: sonnet
---

## Rules
1. Search thoroughly but report concisely
2. Maximum 50 lines in your final summary
3. If you find more than 20 matches, summarize patterns instead of listing all

서브에이전트가 100개 파일을 뒤져도, 메인 컨텍스트에 돌아오는 건 50줄 이내의 요약입니다. model: sonnet으로 코드 검색에는 빠르고 저렴한 모델을 씁니다.

세션 로그 보존

/clear를 해도 JSONL 로그는 디스크에 남는다는 걸 확인하고, cleanupPeriodDays: 99999로 자동 삭제를 막았습니다. 이 글도 세션 로그에서 나온 겁니다.


실전 컨텍스트 관리 패턴

이렇게 도구를 세팅하고 나면, 실전에서는 이런 패턴으로 씁니다.

/compact -- 70-75% 정도에서 수동으로 실행합니다. 80%를 넘기면 Claude의 응답 품질이 눈에 띄게 떨어집니다.

/clear -- 작업 전환할 때 씁니다. JSONL 로그는 디스크에 남으니까 기록이 사라지는 게 아닙니다.

모델 전환 -- Shift+Tab으로 Sonnet과 Opus를 전환합니다. 일상적인 코드 수정은 Sonnet으로 충분하고, 복잡한 아키텍처 설계나 버그 추적은 Opus가 낫습니다.

"작업 시작 -> statusline으로 컨텍스트 확인 -> 70%에서 /compact -> 대규모 검색은 서브에이전트에 위임 -> 작업 전환 시 /clear" -- 이게 하나의 루틴이 됐습니다.


배운 것

바이브코딩 관점

"읽지 말고 맡겨라." 인사이트 리포트의 제안을 하나하나 읽고 판단하는 대신, "뭐가 좋아? 적용해"라고 했습니다. Claude가 우선순위를 매기고, 파일을 만들고, 경로에 배치하는 것까지 했습니다. 바이브코딩은 "내가 다 이해하고 지시하는 것"이 아니라 "방향만 잡아주고 결과를 확인하는 것"입니다.

빠른 피드백이 완벽한 프롬프트보다 낫습니다. Claude가 규칙을 프로젝트 파일에 넣었을 때, "아니, 글로벌에 넣어야지"라는 한 줄 피드백으로 바로 잡았습니다. 처음부터 "글로벌 CLAUDE.md 파일을 ~/.claude/ 경로에 만들고 다음 규칙을 넣어줘"라고 정밀하게 프롬프트를 쓸 필요가 없었습니다.

자동화의 계층을 만드세요. 훅은 가장 빈번한 검증(타입 체크)을, 스킬은 중간 빈도의 워크플로우(배포)를, 에이전트는 상황에 따라 다른 복잡한 작업(코드 탐색)을 담당합니다. 이 계층 구조를 "만들어줘"라고 하면 Claude가 알아서 적절한 레벨에 배치합니다.

개발 관점

CLAUDE.md는 설정 파일이지 README가 아닙니다. "이 프로젝트는 Next.js를 사용합니다" 같은 설명이 아니라, "git 명령 실행 전에 ls package.json으로 디렉토리를 확인하세요" 같은 행동 지침을 써야 합니다. 실제로 발생했던 마찰을 기반으로 규칙을 만들면 효과가 큽니다.

컨텍스트 관리는 성능 관리입니다. 컨텍스트 창이 80%를 넘어가면 Claude의 응답 품질이 떨어집니다. statusline으로 실시간 모니터링하고, 70%에서 /compact를 실행하는 습관이 중요합니다.

서브에이전트 위임으로 컨텍스트를 보호하세요. 메인 세션에서 대규모 검색을 하면 검색 결과가 컨텍스트를 차지합니다. 서브에이전트에 위임하면 50줄 이내의 요약만 돌아오니까 메인 컨텍스트가 깨끗하게 유지됩니다.


다음 단계

이번에 만든 설정들의 효과를 체감하고 있지만, 아직 개선할 부분이 남아 있습니다.

  • 테스트 자동화: 지금은 타입 체크만 훅으로 걸어두었는데, 유닛 테스트도 커밋 전에 자동 실행되도록 확장할 계획입니다
  • 인사이트 정기 실행: 한 달에 한 번 /insights를 돌려서 마찰 패턴의 변화를 추적하려고 합니다
  • 프로젝트별 CLAUDE.md 고도화: 글로벌 규칙 외에, 프로젝트별로 자주 발생하는 마찰을 프로젝트 CLAUDE.md에 추가하는 작업을 계속할 예정입니다

"ㅇㅇ 적용해" 두 글자로 시작한 최적화가, 훅, 스킬, 에이전트, statusline까지 하나의 시스템이 됐습니다. AI 코딩 도구가 더 똑똑해져도, "데이터로 문제를 찾고 -> AI에게 해결을 맡기고 -> 자동화로 재발을 막는" 이 루프는 변하지 않을 것 같습니다. 결국 바이브코딩을 잘하는 건, 모든 걸 직접 하려는 게 아니라 적절한 타이밍에 적절한 방향을 잡아주는 것이니까요.