Code 실전

Claude Code로 자율 검증 파이프라인 구축하기 — Plan-Execute-Verify 루프 실전 적용

seunghyeonlab 2026. 4. 29. 12:21

hero

코드 한 줄 짜는 데 AI를 쓰는 시대는 지났다. 이제는 에이전트가 스스로 테스트를 실행하고, 실패 로그를 읽고, 수정안을 제시하는 단계까지 왔다. 이 글은 Claude Code를 단순 채팅 도구가 아니라 자율 검증 엔진으로 전환하는 과정을 직접 구축한 경험 기반으로 정리한다. CI/CD 연동까지 실제 작동하는 파이프라인을 만들고 싶은 개발자라면 바로 적용 가능한 내용이다.

전체 파이프라인 흐름


1. CLAUDE.md — 에이전트의 판단 기준을 심는 파일

처음 Claude Code를 프로젝트에 붙였을 때 가장 먼저 경험한 문제는 컨텍스트 오해였다. 같은 함수명이 다른 모듈에서 다른 의미로 쓰이는 상황에서 에이전트가 잘못된 구현을 반복해서 제안했다. 수동으로 매번 설명을 추가하는 건 한계가 있었다.

해결책은 CLAUDE.md 파일을 프로젝트 루트에 두는 것이었다. 이 파일은 에이전트가 프로젝트를 시작할 때 가장 먼저 읽는 설계도 역할을 한다.

# 프로젝트 컨텍스트

## 아키텍처 원칙
- 모든 비즈니스 로직은 `src/domain/` 하위에만 작성
- `src/api/`는 라우팅과 직렬화만 담당, 로직 포함 금지
- 외부 의존성은 반드시 인터페이스로 추상화

## 테스트 실행
- 단위 테스트: `npm test -- --testPathPattern=unit`
- 통합 테스트: `npm test -- --testPathPattern=integration`
- 커버리지 확인: `npm run test:coverage`

## 코딩 컨벤션
- 함수명: camelCase, 동사 시작 (fetchUser, validateOrder)
- 에러 처리: try-catch 금지, Result 타입 사용
- 주석: 왜(why)만 작성, 무엇(what)은 코드로 표현

이 파일 하나로 에이전트의 엉뚱한 제안 빈도가 눈에 띄게 줄었다. 특히 아키텍처 제약을 명시한 뒤로는 Claude가 src/api/ 안에 비즈니스 로직을 섞는 실수를 스스로 피하기 시작했다.

CLAUDE.md 가 에이전트 판단에 미치는 영향


2. Plan-Execute-Verify 루프 — 스스로 고치는 에이전트

단순히 "이 기능 만들어줘"라고 시키는 건 가장 낮은 단계의 활용이다. 진짜 자동화는 에이전트가 테스트를 먼저 작성하고, 실패 로그를 읽고, 스스로 수정하는 루프를 도는 구조다.

내가 실제로 사용하는 프롬프트 패턴은 다음과 같다.

역할: 너는 TDD 방식으로 개발하는 시니어 엔지니어다.

작업 순서:
1. 요구사항을 분석하고 테스트 케이스를 먼저 작성해라
2. `npm test` 를 실행하고 결과를 확인해라
3. 테스트가 실패하면 에러 메시지를 분석하고 구현 코드를 수정해라
4. 모든 테스트가 통과할 때까지 2-3을 반복해라
5. 통과 후 커버리지 리포트를 확인하고 미달 영역을 보완해라

요구사항: [여기에 기능 명세]

실제 실패 케이스를 보면 이런 식이다.

# Claude가 실행한 첫 번째 테스트 결과
$ npm test -- --testPathPattern=unit

FAIL src/domain/order/orderService.test.ts
  ● createOrder › 재고 부족 시 에러 반환

    expect(received).toEqual(expected)

    Expected: {"ok": false, "error": "INSUFFICIENT_STOCK"}
    Received: {"ok": false, "error": "STOCK_ERROR"}

    at Object.<anonymous> (src/domain/order/orderService.test.ts:42:5)

이 로그를 받은 Claude는 다음 사이클에서 에러 코드 불일치를 찾아내고 구현 코드의 상수값을 수정한다. 사람이 직접 찾으면 5분 걸릴 작업이 30초 안에 해결된다.

Plan-Execute-Verify 반복 구조


3. CI/CD와의 결합 — Git Hook으로 자동 트리거

수동으로 프롬프트를 입력하는 단계에서 한 발 더 나아가면, Git 이벤트에 연동해 파이프라인이 자동으로 돌아가게 만들 수 있다.

.git/hooks/pre-push 파일을 작성한다.

#!/bin/bash

echo "🔍 변경 파일 분석 중..."

# 변경된 파일 목록 추출
CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD | grep -E '\.(ts|tsx|js|jsx|py)$')

if [ -z "$CHANGED_FILES" ]; then
  echo "변경된 소스 파일 없음. 훅 종료."
  exit 0
fi

echo "분석 대상: $CHANGED_FILES"

# Claude Code CLI로 테스트 생성 및 실행 트리거
claude --print "다음 파일들의 변경사항을 분석하고 관련 테스트를 실행해라: $CHANGED_FILES" \
  --allowedTools "Bash,Read,Write,Edit" \
  | tee /tmp/claude-review.log

# 테스트 결과 확인
if grep -q "FAIL" /tmp/claude-review.log; then
  echo "테스트 실패 감지. 푸시 차단."
  exit 1
fi

echo "모든 테스트 통과. 푸시 진행."
exit 0

권한 설정을 빠뜨리면 훅이 실행되지 않는다.

chmod +x .git/hooks/pre-push

실제로 이 훅을 적용한 뒤 가장 큰 변화는 엣지 케이스 조기 발견이었다. null 입력값이나 빈 배열 처리 같은 부분을 사람이 놓치는 경우가 많은데, Claude가 변경 코드를 보고 자동으로 경계 조건 테스트를 생성해서 실행한다.

Git Hook 자동 트리거 흐름


4. 운영 팁과 주의할 함정

실제 운영하면서 마주친 문제들을 정리했다.

상황 문제 해결책
테스트 파일이 없는 레거시 코드 Claude가 테스트 대상을 찾지 못함 CLAUDE.md에 테스트 디렉터리 명시
통합 테스트가 외부 DB에 의존 로컬 훅에서 실패 훅에서 단위 테스트만 실행, 통합은 CI에 위임
Claude 응답이 너무 길어서 로그 파싱 어려움 결과 판별 실패 --print 출력을 구조화된 포맷으로 요청
Mac vs Linux 줄바꿈 차이 훅 스크립트 오작동 #!/bin/bash + set -euo pipefail 명시

Docker 환경에서는 훅 경로 문제가 생길 수 있다. 볼륨 마운트 시 .git/hooks/가 컨테이너 안에서 실행 권한을 잃는 경우가 있으니 Dockerfile에 아래 라인을 추가한다.

RUN git config core.hooksPath .githooks

그리고 .githooks/ 디렉터리를 버전 관리에 포함시키면 팀 전체가 같은 훅을 공유할 수 있다.


마무리

Claude Code를 자율 검증 엔진으로 전환하는 핵심은 세 가지다. CLAUDE.md로 컨텍스트를 주입하고, Plan-Execute-Verify 루프로 에이전트가 스스로 수정하게 만들고, Git Hook으로 사람 개입 없이 파이프라인을 트리거한다. 이 구조가 작동하기 시작하면 개발자의 역할은 코드 한 줄 한 줄에서 설계와 검증 기준 수립으로 이동한다.

다음 글에서는 이 파이프라인에 n8n을 연결해서 Slack 알림과 자동 PR 생성까지 붙이는 과정을 다룬다.


🐦 X에서 더 빠르게: @baegseungh7061
📚 이 시리즈 더 보기: Code 실전
💌 새 글 알림: X 팔로우 또는 블로그 RSS 구독