클로드 코드 완전 자동화 #4 — 한번 명령으로 모든 것을 자동으로
CLAUDE.md 작업 규칙 + allowedTools + headless 모드를 조합해 한 줄 명령으로 프로젝트 전체를 자동 관리하는 방법과 현실적 한계.
한 줄 요약: CLAUDE.md에 작업 규칙을 정의하고, allowedTools + headless 모드를 조합하면 한 줄 명령으로 프로젝트 전체를 자동 관리할 수 있다. 단, 완전 무인 자동화의 현실적 한계도 있다.
"한번 실행하면 알아서 다 해주면 안 되나?" — Claude Code를 쓰다 보면 자연스럽게 이 질문에 도달한다. 이론적으로는 가능하다. CLAUDE.md에 해야 할 일을 정의하고, 권한 설정을 열어두고, 셸 스크립트로 실행하면 된다. 이 글에서는 그 아키텍처를 설계하고, 현실에서 막히는 지점과 해결 방법을 함께 정리한다.
완전 자동화의 꿈과 현실
사용자가 원하는 것은 명확하다. 한 번 명령하면 Claude가 알아서 코드를 분석하고, 버그를 수정하고, 테스트를 돌리고, 커밋까지 완료하는 것. 실제로 이 시나리오는 상당 부분 구현 가능하다.
하지만 Claude는 AI 에이전트다. 판단이 필요한 순간이 반드시 온다.
| 상황 | Claude의 판단 | 자동화 가능 여부 |
|---|---|---|
| 파일 내용 읽기 → 수정 | 기계적 처리 가능 | 완전 자동화 가능 |
| 테스트 실패 → 원인 분석 → 수정 | 대부분 처리 가능 | 대부분 자동화 가능 |
| 두 가지 방향 중 어느 것이 더 나은가 | 임의 선택 또는 질문 | 지침 없으면 멈춤 |
| 의도치 않은 에러 발생 | 멈추거나 잘못된 방향 진행 | 감시 필요 |
| API 응답 형식이 바뀐 외부 의존성 | 판단 불가 | 사람 개입 필요 |
핵심은 Claude가 판단을 내려야 하는 순간을 최소화하는 것이다. CLAUDE.md에 판단 기준을 미리 정의해두면 Claude는 질문 없이 진행할 수 있다.
자동화 아키텍처 설계
완전 자동화 파이프라인은 3개 레이어로 구성된다.
| 레이어 | 파일 | 역할 |
|---|---|---|
| 작업 규칙 | CLAUDE.md | Claude에게 무엇을 어떻게 해야 하는지 정의 |
| 권한 설정 | .claude/settings.json | 어떤 도구를 승인 없이 사용할 수 있는지 지정 |
| 실행 스크립트 | automate.sh | Claude 호출, 결과 확인, 커밋, 반복 논리 |
이 3가지가 갖춰지면 bash automate.sh 한 줄로 전체 파이프라인이 돌아간다.
레이어가 분리되어 있는 이유는 역할이 다르기 때문이다. CLAUDE.md는 "무엇을 할지", settings.json은 "무엇을 허용할지", 스크립트는 "어떤 순서로 실행할지"를 담당한다. 세 가지를 하나의 스크립트에 몰아넣으면 수정이 어려워진다.
CLAUDE.md로 자동 작업 지시하기
CLAUDE.md에 "세션 시작 시 자동으로 수행할 작업" 섹션을 넣으면 Claude는 매번 그 지침을 읽고 작업을 시작한다. 인터랙티브 모드든 headless 모드든 동일하게 적용된다.
핵심은 판단 기준을 글로 남기는 것이다. "에러가 나면 어떻게 해라", "모르는 경우 이 방법으로 처리해라"를 명시할수록 Claude가 중간에 멈추지 않는다.
CLAUDE.md — 자동 작업 지시 섹션 예시## 세션 시작 시 자동 수행 작업 이 섹션의 지시사항은 Claude Code 세션 시작 직후 순서대로 실행한다. ### 1단계: 상태 확인 - `git status`로 변경된 파일 목록 확인 - `git log --oneline -5`로 최근 커밋 히스토리 확인 - `node --check posts/*.js`로 JS 구문 오류 확인 ### 2단계: 문제 처리 - 구문 오류가 있는 파일은 즉시 수정 후 재검증 - 수정이 불가능한 에러는 ERRORS.md에 기록하고 계속 진행 - 판단이 애매한 경우 보수적으로 처리 (수정하지 않고 기록) ### 3단계: 커밋 - 수정 사항이 있으면 커밋 메시지 형식: `[fix]: {파일명} 구문 오류 수정` - 수정 사항이 없으면 커밋하지 않음 ### 판단 기준 - 모르는 게 있으면 가장 보수적인 방향으로 처리하고 계속 진행 - 사용자에게 질문하지 말고 NOTES.md에 기록 후 다음 작업 진행
"모르는 게 있으면 질문하지 말고 NOTES.md에 기록 후 진행"이라는 지시가 핵심이다. 이 문장 하나로 headless 실행 중 Claude가 중간에 멈추는 상황의 상당수를 막을 수 있다.
CLAUDE.md에 포함하면 좋은 판단 기준들은 다음과 같다.
- 에러가 나도 다음 작업은 계속 진행할지 여부
- 파일을 삭제해야 할 상황이 생기면 어떻게 할지 (백업 후 삭제 vs 삭제 금지)
- 외부 API를 호출해야 할 상황이 생기면 어떻게 할지
- 커밋 메시지 형식과 커밋 타이밍
- 완료 후 어디에 결과를 기록할지
원커맨드 자동화 스크립트 만들기
셸 스크립트는 Claude 호출, 결과 로깅, 커밋, 에러 처리를 순서대로 묶어준다. claude -p headless 모드를 이용해 Claude를 도구처럼 호출한다.
automate.sh — 기본 원커맨드 자동화 스크립트#!/bin/bash # 사용법: bash automate.sh # 목적: Claude Code로 프로젝트 상태 점검 → 수정 → 커밋 자동화 set -e # 에러 발생 시 즉시 중단 LOG_FILE="auto_run_$(date +%Y%m%d_%H%M%S).log" WORK_DIR="$(pwd)" echo "[$(date)] 자동화 시작" | tee -a "$LOG_FILE" # 1단계: 권한 설정 확인 if [ ! -f ".claude/settings.json" ]; then echo "[WARN] .claude/settings.json 없음. 기본 권한으로 실행" | tee -a "$LOG_FILE" fi # 2단계: Claude 실행 (CLAUDE.md의 지시에 따라 자동 작업) claude -p "CLAUDE.md의 '세션 시작 시 자동 수행 작업'을 순서대로 실행해줘. \ 모르는 게 있으면 NOTES.md에 기록하고 다음 작업을 계속 진행해줘." \ --allowedTools "Read,Edit,Write,Bash(node *),Bash(git status),Bash(git log *),Bash(git add *),Bash(git commit *)" \ 2>&1 | tee -a "$LOG_FILE" EXIT_CODE=$? # 3단계: 결과 확인 if [ $EXIT_CODE -eq 0 ]; then echo "[$(date)] 완료. 로그: $LOG_FILE" | tee -a "$LOG_FILE" else echo "[$(date)] 에러 발생 (exit code: $EXIT_CODE). 로그 확인: $LOG_FILE" exit $EXIT_CODE fi
.claude/settings.json — 자동화용 권한 설정{ "permissions": { "allow": [ "Read", "Edit", "Write", "Bash(node *)", "Bash(git status)", "Bash(git log *)", "Bash(git add *)", "Bash(git commit *)", "Bash(git diff *)" ], "deny": [ "Bash(rm -rf *)", "Bash(curl *)", "Bash(wget *)", "Bash(git push *)" ] } }
이 설정의 핵심 포인트 두 가지다.
- git push는 deny 목록에 넣는다. 자동화가 아무리 잘 되어도 외부 저장소 push는 사람이 확인 후 하는 것이 안전하다. 로컬 커밋까지만 자동화하고 push는 수동으로 한다.
- curl, wget은 deny 목록에 넣는다. Claude가 외부 서버로 데이터를 전송하는 것을 막는다. 외부 API가 필요하다면 특정 도메인만 허용하도록 범위를 좁힌다.
더 복잡한 파이프라인이 필요하다면, 스크립트를 단계별로 분리해서 각 단계 사이에 검증 로직을 추가한다.
단계별 분리 스크립트 예시#!/bin/bash # 단계별 자동화 — 각 단계 사이에 검증 삽입 LOG="pipeline_$(date +%Y%m%d).log" run_step() { local STEP_NAME=$1 local PROMPT=$2 local TOOLS=$3 echo "[STEP] $STEP_NAME 시작" | tee -a "$LOG" claude -p "$PROMPT" --allowedTools "$TOOLS" 2>&1 | tee -a "$LOG" if [ $? -ne 0 ]; then echo "[ERROR] $STEP_NAME 실패. 파이프라인 중단" | tee -a "$LOG" exit 1 fi echo "[STEP] $STEP_NAME 완료" | tee -a "$LOG" } # 1단계: 구문 검사 및 수정 run_step "구문검사" \ "posts/*.js 파일 전체의 JS 구문을 node --check로 확인하고 에러가 있으면 수정해줘" \ "Read,Edit,Bash(node *)" # 2단계: 변경사항 커밋 run_step "커밋" \ "수정된 파일이 있으면 git add 후 '[fix]: 자동 구문 수정' 메시지로 커밋해줘" \ "Bash(git status),Bash(git add *),Bash(git commit *)" echo "파이프라인 완료" | tee -a "$LOG"
현실적 한계와 해결책
완전 자동화는 이론적으로는 완성되었지만, 실제 운영에서 다음 4가지 한계를 반드시 고려해야 한다.
1. 토큰 한도
Claude는 한 번의 요청에서 처리할 수 있는 토큰 수에 한도가 있다. 파일 수가 많거나 파일 내용이 길면 중간에 컨텍스트가 잘릴 수 있다.
해결: 작업을 배치로 나눈다. 한 번에 전체 프로젝트가 아니라 디렉토리 단위, 파일 10개 단위로 분리해서 실행한다.
2. 컨텍스트 길이 제한
긴 대화 이후 Claude는 초반 컨텍스트를 잊는다. headless 모드에서는 각 실행이 독립적이라 문제가 적지만, CLAUDE.md가 매우 길면 정작 중요한 지시가 컨텍스트에서 밀려날 수 있다.
해결: CLAUDE.md에서 자동화와 관련 없는 내용은 별도 파일로 분리한다. 자동화 지시는 CLAUDE.md 상단에 배치한다.
3. 예상치 못한 에러 시 멈춤
Claude가 처리하기 어려운 에러가 생기면 응답 없이 멈추거나, 반복적으로 같은 시도를 하다가 실패할 수 있다.
해결: 스크립트에 타임아웃을 설정한다. timeout 300 claude -p ...처럼 5분 이상 응답이 없으면 강제 종료하고 로그를 남긴다.
4. 비용 문제
자동화를 설정해두면 실수로 큰 작업을 반복 실행하거나, 루프에 빠져 과도한 API 요청이 발생할 수 있다.
해결: Anthropic 콘솔에서 월 지출 상한을 설정한다. 스크립트에 실행 횟수 카운터를 넣어 최대 실행 횟수를 제한한다.
막히는 케이스 1 — Claude가 응답 없이 멈출 때: headless 모드에서 Claude가 clarification을 요청하면 응답 대기 상태로 무한 멈춘다. CLAUDE.md에 "모르는 게 있으면 질문하지 말고 NOTES.md에 기록 후 다음 작업 진행"을 명시하고, 스크립트에 timeout 300을 추가해 강제 종료 시간을 지정한다.
막히는 케이스 2 — 파일이 너무 많아 토큰 초과: claude -p "posts/*.js 전체를 처리해줘"처럼 넓은 범위를 한번에 지시하면 토큰 한도를 초과할 수 있다. 파일 목록을 셸에서 직접 나눠서 claude -p "posts/3001.js와 posts/3002.js를 처리해줘"처럼 배치로 분리해서 실행한다.
막히는 케이스 3 — git push가 자동으로 실행될 때: settings.json에 Bash(git push *)를 allow 목록에 넣으면 Claude가 push를 자동 실행할 수 있다. deny 목록에 명시적으로 추가해두는 것이 안전하다. push는 항상 사람이 결과를 확인 후 수동으로 한다.
막히는 케이스 4 — 루프에 빠져 API 비용이 폭발할 때: 스크립트에 재시도 로직을 넣으면 Claude가 같은 에러를 반복 처리하다 비용이 급증할 수 있다. 최대 재시도 횟수를 3회 이하로 제한하고, 실패 시 알림을 보낸 후 중단하는 로직을 반드시 포함한다.
실전 팁 — 자동화 범위를 단계적으로 넓히기
한번에 완전 자동화를 구현하려다 실패하는 경우가 많다. 작은 것부터 자동화하고 범위를 넓혀가는 것이 안전하다.
1단계: 읽기 전용 자동화
먼저 --allowedTools "Read"만으로 시작한다. Claude가 파일을 읽고 상태 보고서만 생성하게 한다. 이 단계에서 CLAUDE.md의 지시가 의도대로 동작하는지 확인한다.
2단계: 편집 자동화 추가
"Read,Edit,Write"로 파일 편집까지 허용한다. 셸 명령은 아직 열지 않는다. 파일 편집 결과를 며칠간 모니터링한다.
3단계: 특정 셸 명령 추가
"Bash(node *)","Bash(npm run test)"처럼 필요한 명령만 하나씩 추가한다. 전체 셸을 열지 않고 명시적으로 허용한 명령만 통과시킨다.
4단계: git 커밋 자동화
충분히 안정적으로 동작하는 것을 확인한 후 git add, git commit을 허용한다. git push는 이 단계에서도 허용하지 않는다.
로그 관리
자동화 실행 시 반드시 로그를 남긴다. 로그 없이 자동화를 돌리면 나중에 무슨 일이 있었는지 추적이 불가능하다.
실패 시 알림 설정 예시 (macOS)#!/bin/bash # macOS 알림 + 로그 파일 기록 LOG="auto_$(date +%Y%m%d_%H%M%S).log" # Claude 실행 timeout 300 claude -p "CLAUDE.md의 자동 작업을 실행해줘" \ --allowedTools "Read,Edit,Write,Bash(node *),Bash(git add *),Bash(git commit *)" \ 2>&1 | tee -a "$LOG" EXIT_CODE=${PIPESTATUS[0]} if [ $EXIT_CODE -eq 0 ]; then # 성공 알림 osascript -e 'display notification "자동화 완료" with title "Claude Code"' else # 실패 알림 (macOS) osascript -e "display notification \"실패 (exit: $EXIT_CODE). 로그 확인: $LOG\" with title \"Claude Code 오류\"" # 실패 시 로그를 별도 파일로 복사 cp "$LOG" "FAILED_$(date +%Y%m%d_%H%M%S).log" fi