Claude Code에 확인 방법을 먼저 준다, 프롬프트부터 검증 에이전트까지 네 단계
Tools21분 읽기

Claude Code에 확인 방법을 먼저 준다, 프롬프트부터 검증 에이전트까지 네 단계

맡기는 작업에 확인을 얼마나 단단히 걸지 네 질문으로 고른다. 한 번의 프롬프트, /goal, 8회 상한이 있는 Stop 훅, 검증 서브에이전트의 쓰임과 함정, 노력 수준과 CLAUDE.md 정리를 담았다.

금요일 저녁, 결제 모듈의 호출부 마흔 곳을 새 API로 옮기라고 Claude Code에 맡기고 퇴근합니다. 월요일 아침에 열어 보니 마지막 메시지는 “모든 호출부를 옮겼습니다”입니다. 그런데 npm test를 돌리자 테스트 세 개가 실패하고 한 파일은 타입 오류까지 냅니다(편집부가 만든 예시 장면입니다). 이 장면에서 모자랐던 것은 Claude의 실력이 아니라 “끝났다”를 판정할 기준이었습니다. 기준이 어디에도 적혀 있지 않으면 Claude는 일이 다 된 것처럼 보이는 순간에 멈추고, 그때부터는 사람이 검증 담당입니다.

Claude Code 설명서의 모범 사례 문서가 맨 앞에 두는 항목도 프롬프트 요령이 아니라 이것입니다. 통과 아니면 실패가 나오는 확인을 Claude가 직접 돌릴 수 있게 하라는 것입니다. 다만 확인을 “얼마나 단단히” 걸지는 작업마다 다릅니다. 오타 한 줄에 훅 스크립트를 짤 이유는 없고, 밤새 도는 이전 작업을 한 줄짜리 부탁으로 맡길 수도 없습니다. 이 글은 2026-10-27 기준 설명서(Claude Code 2.1.310)를 다시 읽고, 작업 성격에 따라 단계를 고르는 길을 질문 순서로 정리했습니다. 곁가지인 노력 수준, CLAUDE.md, 스킬은 단계를 정한 뒤 같이 손볼 항목으로 뒤쪽에 두었습니다.

네 가지 질문으로 단계를 가른다

설명서는 확인을 걸 수 있는 세기를 네 단계로 나눕니다. 한 번의 프롬프트, 세션 전체를 묶는 /goal, 스크립트가 판정하는 Stop 훅, 그리고 새 모델이 결과를 반박해 보는 검증입니다. 아래 그림은 이 네 단계를 질문 순서로 다시 그린 것으로, 왼쪽 위 질문에서 출발해 내 작업이 닿는 칸만 따라가면 됩니다.

질문 네 개를 따라 확인 만들기, 한 번의 프롬프트, /goal, Stop 훅으로 갈라지고 결과가 비싸면 새 컨텍스트 검토자가 더해지는 결정 트리 그림 1. 확인 수단이 없으면 만드는 것이 먼저이고, 이후로는 사람이 지켜보는지, 건너뛰면 안 되는지, 틀린 통과가 비싼지가 갈림길

그림에서 눈에 띄는 것은 4단계가 다른 단계와 나란한 선택지가 아니라 위에 얹는 덧칠이라는 점입니다. 2단계나 3단계를 거친 작업도 결과가 틀렸을 때 비싸다면 작업을 하지 않은 새 컨텍스트가 한 번 더 채점합니다. 반대로 1단계는 가장 약해 보여도 오늘 어떤 작업에서든 설정 없이 쓸 수 있습니다. 설명서의 정리가 이렇습니다. 프롬프트 방식은 어떤 작업에서도 되고, /goal과 Stop 훅 방식이 사람 없이 끝까지 정확히 가게 한다는 것입니다.

세 장치는 “다음 턴을 무엇이 시작시키는가”로 구분하면 헷갈리지 않습니다.

장치 다음 턴이 시작되는 때 멈추는 때
/goal 이전 턴이 끝났을 때(대화형에서는 대기 중 점검이나 자동 재시도가 올 때도) 평가 모델이 충족·불가능을 판정, 고쳐야 하는 오류, /goal clear
/loop 정한 시간 간격이 지났을 때 사용자가 멈추거나 Claude가 끝났다고 판단
Stop 훅 이전 턴이 끝났을 때 스크립트 또는 프롬프트가 판정

확인 수단이 없는 일에는 기준부터 쓴다

그림 1의 첫 질문에서 “아니오”가 나오면 단계를 고르기 전에 확인을 만들어야 합니다. 설명서가 말하는 확인은 대화 안에서 Claude가 읽을 수 있는 신호면 무엇이든 됩니다. 테스트 묶음, 빌드 종료 코드, 린터, 출력을 기준 파일과 대조하는 스크립트, 브라우저 스크린샷을 시안과 비교하는 것까지 들어갑니다. 설명서가 드는 바꿔 쓰기 세 가지가 이 감각을 잘 보여 줍니다.

상황 이렇게 시키면 이렇게 바꾼다
새 함수 이메일 검증 함수를 만들어 줘 함수를 만들고 입력별 기대값(올바른 주소는 true, 잘못된 것은 false)을 적은 테스트를 돌려라
화면 대시보드를 더 예쁘게 시안을 구현하고 결과를 스크린샷으로 찍어 시안과 비교해 차이를 나열하고 고쳐라
빌드 오류 빌드가 깨져 이 오류가 난다는 출력을 붙이고, 고친 뒤 빌드 성공을 확인하라. 오류를 숨기지 말고 근본 원인을 고쳐라

개발 작업이 아니어도 같은 틀이 통합니다. 내보낸 CRM 데이터로 주간 보고서를 만들라고 맡긴다면 필요한 것은 세 칸입니다. 할 일(이번 주 보고서 작성), 건드리지 않을 것(정해진 템플릿, 외부 발송), 끝났다는 기준(보고서의 모든 수치가 내보낸 데이터와 일치)입니다. 기준 칸이 비어 있으면 “보고서를 완성한다”처럼 판정할 수 없는 문장이 그 자리를 채웁니다.

  1. 끝 상태를 하나만 고른다. 테스트 결과, 종료 코드, 파일 수, 빈 큐처럼 숫자나 목록으로 떨어지는 것이어야 합니다.
  2. 증명하는 방법을 적는다. npm test가 0으로 끝난다, git status가 깨끗하다처럼 명령과 기대 결과를 짝지어 적습니다.
  3. 지나는 길에 바뀌면 안 되는 것을 적는다. 설정 파일, 다른 테스트 파일, 발송 같은 외부 동작이 해당합니다.
  4. 기준이 실제로 실패하는지 한 번 본다. 항상 참인 단언이나 아무것도 잡지 못하는 린트 규칙이면 통과는 아무 뜻도 없습니다.
  5. 증거를 요구한다. 성공했다는 말 대신 테스트 출력, 실행한 명령과 결과, 화면 스크린샷을 보여 달라고 적습니다.

마지막 단계의 효과는 자리를 비웠을 때 크게 드러납니다. 설명서도 증거를 읽는 편이 처음부터 다시 돌려 보는 것보다 빠르고, 지켜보지 않은 세션에서도 돌아와 읽을 근거가 남는다고 말합니다. 화면 비교가 필요한 일이라면 브라우저를 다루는 확장(Claude in Chrome)이 스크린샷을 직접 찍어 시안과 견주게 해 줍니다.

이렇게까지 꼼꼼히 쓰는 이유는 컨텍스트 창 때문입니다. 대화, 읽은 파일, 명령 출력이 모두 한 창에 쌓이고, 창이 찰수록 성능이 떨어지며 앞서 준 지시를 놓치기 쉽습니다. 확인 기준이 한 줄로 분명하면 Claude가 같은 결과를 반복해서 읽지 않아도 되므로 창이 덜 낭비됩니다. 이 글 뒷부분의 CLAUDE.md 줄이기, 노력 수준, 검증용 서브에이전트도 모두 같은 제약을 비켜 가는 방법입니다.

사람이 바로 보는 일은 프롬프트 한 줄로 끝낸다

그림 1에서 “지켜본다”로 빠지는 길이 1단계입니다. 확인을 같은 메시지에 적기만 하면 됩니다. “함수를 만들고 테스트를 돌려 실패하면 고쳐라” 정도면 충분하고, 설정도 비용도 없습니다. README 오타, 로그 한 줄 추가, 이름 바꾸기처럼 변경을 한 문장으로 설명할 수 있는 일이면 계획 모드조차 건너뛰라는 것이 설명서의 안내입니다. 계획 모드에는 오버헤드가 있다고 문서가 직접 적고 있습니다.

계획 모드가 어울리는 쪽은 반대입니다. 접근법이 불확실하거나 여러 파일을 건드리거나 낯선 코드를 고칠 때입니다. Shift+Tab을 눌러 모드를 돌리거나 claude --permission-mode plan으로 시작하거나 한 번만 쓸 때는 프롬프트 앞에 /plan을 붙입니다. Claude는 소스를 고치지 않고 읽고 조사해 계획을 쓰고, 계획을 승인하면 “자동 모드로 진행”, “편집을 하나씩 승인”, “계속 계획” 중에서 고르게 됩니다. Ctrl+G로 계획을 편집기에서 직접 고칠 수도 있습니다. 설명서가 그리는 흐름은 탐색, 계획, 구현, 커밋의 네 단계이고, 구현 단계의 프롬프트에 테스트를 돌리고 실패를 고치라는 확인이 들어갑니다.

Shift+Tab으로 도는 권한 모드는 이 선택과 얽혀 있습니다. 수동(Manual) 모드는 파일 편집과 셸 명령마다 묻습니다. 가장 안전하지만 열 번째 질문부터는 읽지 않고 누르게 됩니다. 편집 수락(Accept edits) 모드는 파일 편집과 mkdir, mv 같은 흔한 파일 명령은 묻지 않고 그 밖의 명령만 묻습니다. 계획(Plan) 모드는 승인 전까지 소스 편집이 막히고, 자동(Auto) 모드는 별도 분류 모델이 위험한 행동만 차단합니다. 자동 모드는 v2.1.283 이상의 터미널과 VS Code에서 시작 모드로 고를 수 있습니다. 지켜보는 작업은 수동이나 편집 수락으로, 자리를 비우는 작업은 자동 모드로 가는 것이 자연스럽고, 이 차이가 다음 절의 /goal과 이어집니다.

자리를 비우는 일에는 /goal을 건다

그림 1에서 “자리를 비운다”로 갈린 작업의 기본값이 /goal입니다. 설명서가 맞는 일로 드는 것은 모든 호출부가 컴파일되고 테스트가 통과할 때까지 모듈을 새 API로 옮기기, 설계 문서의 인수 기준이 모두 충족될 때까지 구현하기, 큰 파일을 크기 예산 이하의 모듈로 쪼개기, 라벨이 붙은 이슈 백로그의 큐가 빌 때까지 처리하기입니다. 공통점은 끝 상태가 숫자나 목록으로 떨어진다는 것이고, 서두의 금요일 저녁 장면이 정확히 첫 번째 경우입니다.

사용법은 한 줄입니다. /goal 뒤에 조건을 적으면 조건 자체가 지시가 되어 곧바로 한 턴이 시작되고, 이미 목표가 있으면 새 조건으로 교체됩니다. 세션당 하나만 켜지고 조건은 4,000자까지 쓸 수 있습니다. 인자 없이 /goal만 입력하면 조건, 경과 시간, 평가한 턴 수, 토큰 사용량, 평가 모델의 최근 판정 이유가 보이고, 판정 이유는 Ctrl+O로도 열립니다. 해제는 /goal clear(별칭 stop, off, reset, none, cancel)이고 /clear로 새 대화를 시작해도 사라집니다. 세션을 이어 열면 아직 활성인 목표가 복원되는데, v2.1.239부터는 --continue, --resume, 세션 선택 화면 어느 경로로 열어도 그렇습니다. 복원되는 것은 조건뿐이고 턴 수와 타이머, 토큰 기준선은 0에서 다시 셉니다.

평가 모델이 보는 것은 대화뿐이다

/goal의 정체는 세션 범위의 프롬프트형 Stop 훅입니다. 턴이 끝날 때마다 조건과 지금까지의 대화를 설정된 작은 빠른 모델에게 보내고, 모델은 세 판정 중 하나와 짧은 이유를 돌려줍니다. 미충족이면 Claude가 그 이유를 지침 삼아 다음 턴을 이어 가고, 충족이면 조건을 지우고 달성 기록을 남기며, 불가능이면 조건을 지우고 사유와 함께 실패 기록을 남깁니다. 일하는 모델과 판정하는 모델이 다르다는 점이 자동 모드와의 차이입니다. 자동 모드는 한 턴 안의 도구 호출 승인을 없앨 뿐 새 턴을 시작시키지 못하고 Claude가 끝났다고 판단하면 멈춥니다. 자동 모드가 도구 호출마다 묻는 것을 없애고 /goal이 턴마다 계속하라고 치는 것을 없애므로 둘은 함께 쓰는 짝입니다. 반대로 /goal은 권한 모드를 바꾸지 않아서, 수동 모드에서는 테스트 명령처럼 허용 목록에 없는 도구 호출마다 계속 묻고 자리를 비운 실행이 멈춥니다.

이 구조의 핵심은 평가 모델에게 도구가 없다는 것입니다. 파일을 읽거나 명령을 돌리지 못하고 대화에 드러난 내용만 봅니다. “테스트가 통과했다”는 사실이 Claude의 출력에 찍혀 있어야 판정이 서고, 찍히지 않은 일은 평가 모델에게는 일어나지 않은 일입니다. 조건을 쓸 때 “Claude 자신의 출력으로 증명할 수 있는 문장”이 기준이 되는 이유입니다.

판정이 서지 않는 조건

  • 보고서를 완성한다
  • 코드를 깔끔하게 정리한다
  • 테스트가 대충 돌아간다

대화만 봐도 판정이 서는 조건

  • test/auth 아래 테스트가 모두 통과하고 lint가 깨끗하다. 다른 테스트 파일은 고치지 않는다. 20턴 안에 못 끝내면 멈춘다
  • 모든 호출부가 새 API로 컴파일되고 npm test가 0으로 끝난다
  • git status가 깨끗하고 CHANGELOG에 이번 주 병합된 PR마다 항목이 있다

오른쪽 첫 줄에는 실행 시간을 묶는 요령도 들어 있습니다. 조건에 “20턴 뒤에 멈춘다” 같은 턴이나 시간 절을 넣으면 Claude가 매 턴 그 진행을 보고하고 평가 모델이 대화에서 읽어 판정합니다. 비용 상한도 같은 절이 맡습니다. 평가 한 번의 토큰은 작은 빠른 모델 요금이고 본 작업 비용에 비하면 보통 무시할 만하다고 설명서가 적습니다. 실제로 늘어나는 비용은 목표를 만족시키려고 Claude가 더 많은 턴을 도는 데서 나오므로, 턴 제한이 가장 직접적인 상한입니다. 평가 모델을 바꾸려면 ANTHROPIC_DEFAULT_HAIKU_MODEL을 설정하는데, 이 변수는 작은 빠른 모델을 쓰는 모든 곳(대화 요약 같은 백그라운드 기능과 haiku 별칭)에 똑같이 적용된다는 경고가 붙어 있습니다.

멈추는 경우의 세 갈래

밤새 돌려 놓았다면 아침에 목표가 어떤 상태인지 읽을 수 있어야 합니다. 턴이 실패했을 때 설명서의 분류는 이렇습니다.

/goal 설정 뒤 오류가 났을 때 나오는 상태 문구: 재시도, 일시 중지, 해제와 /goal clear 확인 문구 그림 2. 문구의 시작 부분은 설명서 기준이고 세션은 줄여 그렸다. 해제된 경우만 목표를 다시 입력해야 한다

그림의 붉은 줄만 사용자가 손대야 하는 경우입니다. 인증 실패(Claude Code가 자격 증명을 직접 관리할 때), 크레딧 소진, 자동 압축으로 못 푸는 컨텍스트 초과, 쓸 수 없는 모델이 그 원인이고, 원인을 고친 뒤 /goal로 조건을 다시 입력합니다. 서버 과부하나 연결 끊김처럼 시간이 지나면 풀리는 오류는 목표가 유지되고, 세 번 자동 재시도한 뒤에는 일시 중지됩니다. 요금 한도, 사용량 한도, 훅이 턴을 끝낸 경우처럼 재시도해도 같은 결과가 나올 오류는 처음부터 일시 중지이고, 사용량 한도가 풀릴 때 자동으로 이어 가는 대기 중이면 풀리는 시점에 작업이 재개됩니다. 이런 상태를 알려 주는 안내 줄은 v2.1.269 이상의 대화형 세션에서 나옵니다. 마지막으로 Claude가 도구를 쓰지 않고 평가 답변만 되풀이하며 몇 턴 진전이 없으면 Claude Code가 루프를 멈추고 경고를 찍은 뒤 목표를 그대로 둔 채 제어를 돌려주고, 다음 프롬프트부터 평가가 재개됩니다.

백그라운드 작업이 길어질 때

턴이 끝났는데 서브에이전트나 백그라운드 셸 명령이 아직 돌고 있으면 그 턴의 평가는 건너뜁니다. 백그라운드 작업이 모두 끝난 턴의 끝에서 평가하고, 결과가 도착하면 Claude Code가 새 턴으로 전달하므로 사용자가 깨울 필요는 없습니다. 기다림이 30분을 넘기면 점검(check-in)이 시작되어 돌아가는 작업 목록을 Claude에게 보여 주고, 진행 중이면 기다리고 멈춘 것은 고치거나 끝내라고 요청합니다. 간격은 30분, 1시간, 이후 2시간으로 늘어나고 첫 간격의 네 배에서 멈춥니다. 대화형 세션에서 Claude Code가 스스로 시작하는 대기 중 점검은 사용자 프롬프트 사이에 최대 세 번입니다. 이 상한은 v2.1.246에서 생긴 것으로 그 전에는 횟수 제한이 없었고, 대기 중 점검은 v2.1.236 이상, 점검 자체는 v2.1.234 이상에서 동작합니다. 첫 간격은 CLAUDE_CODE_GOAL_CHECKIN_MINUTES로 바꾸고 0이면 점검과 자동 재시도가 모두 꺼집니다.

스크립트에서 쓸 때는 claude -p "/goal ..."가 끝날 때까지 돌고, 기본 텍스트 출력은 끝나야 최종 답이 나오므로 멈춘 것처럼 보일 수 있습니다. --output-format stream-json --verbose를 붙이면 진행 메시지가 흘러나옵니다. 훅을 끈 설정(disableAllHooks, 관리 설정의 allowManagedHooksOnly)에서는 /goal이 이유를 알려 주고 동작하지 않으니, 평가기가 훅 체계의 일부라는 점을 기억해 두면 됩니다.

어기면 안 되는 확인은 Stop 훅으로

/goal의 판정은 모델이 내리므로 가끔 어긋납니다. 확인 대상이 대화에 찍히지 않는 실제 상태이거나 한 번도 건너뛰면 안 되는 검사라면 판정을 스크립트에 맡기는 것이 3단계입니다. Stop 훅은 Claude가 응답을 끝낼 때마다 실행되는 사용자 정의 명령이고, 종료 코드 2로 끝나면 Claude가 멈추지 못한 채 stderr에 쓴 문장을 다음 지시로 받습니다. 테스트가 깨져 있으면 턴을 끝내지 못하게 하는 예는 이렇습니다(프로젝트의 테스트 명령에 맞게 바꿔 쓰는 예시입니다).

#!/bin/bash
# .claude/hooks/tests-before-stop.sh  (chmod +x 필요)
INPUT=$(cat)                       # 훅 입력(JSON)이 표준 입력으로 들어온다
if ! OUT=$(npm test 2>&1); then
  echo "테스트가 실패했다. 아래 출력을 읽고 고친 뒤 다시 확인하라." >&2
  echo "$OUT" | tail -n 30 >&2      # 마지막 30줄만 되돌려 준다
  exit 2                            # 2 = 멈추지 말고 계속하라
fi
exit 0                              # 통과 = 턴이 끝나도 된다
{
  "hooks": {
    "Stop": [
      { "hooks": [ { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/tests-before-stop.sh" } ] }
    ]
  }
}

JSON 설정은 프로젝트의 .claude/settings.json에 넣고, 등록된 훅은 /hooks로 볼 수 있습니다. 종료 코드 대신 JSON으로 답할 수도 있습니다. {"decision": "block", "reason": "..."}는 멈추지 못하게 하고 사유를 Claude에게 전달하며, hookSpecificOutput.additionalContext는 “멈추기 전에 테스트를 돌려라” 같은 안내를 오류가 아닌 피드백으로 보여 줍니다. 종료 코드와 JSON은 한 훅에서 하나만 고릅니다. Windows에서 PowerShell 스크립트로 훅을 쓴다면 2.1.309 이전에는 종료 코드 2로 끝나도 막지 못하던 문제가 있었고 2.1.309에서 고쳐졌으니 버전을 확인해 볼 만합니다.

영원히 막지는 않는다

“테스트가 안 풀리면 훅이 Claude를 영원히 붙잡지 않을까”라는 걱정은 설계에 이미 들어 있습니다. Claude가 도구를 한 번도 쓰지 않은 채 Stop 훅이 연속 8번 차단하면 Claude Code가 다음 차단을 무시하고 턴을 끝냅니다. 도구를 한 번이라도 쓰면 세는 값은 0으로 돌아갑니다.

Stop 훅이 종료 코드 2로 막고, Claude가 도구를 쓰면 세는 값이 0으로 돌아가며, 도구 없이 8번째 차단에 이르면 Claude Code가 턴을 끝내는 순서 그림 3. 세는 값은 연속 차단 횟수라서, 고치는 동안에는 0으로 돌아가고 손을 놓은 채 반복할 때만 8에 닿는다

그림에서 읽을 것은 상한이 “느린 수정”이 아니라 “진전 없는 반복”을 겨냥한다는 점입니다. 입력으로 들어오는 stop_hook_active가 true이면 이미 훅 때문에 이어 가는 중이라는 뜻이고, 풀릴 가능성이 없는 조건을 붙들고 막지 않도록 스크립트가 이 값을 읽고 일찍 exit 0으로 끝나는 방식을 설명서가 보여 줍니다. 정말 여러 번 고쳐야 통과하는 확인이면 환경 변수 CLAUDE_CODE_STOP_HOOK_BLOCK_CAP으로 상한을 올립니다.

훅은 만드는 방식도 세 가지입니다.

종류 판정하는 쪽 맞는 일
command 셸 명령. 입력은 표준 입력, 결과는 종료 코드와 출력 같은 입력이면 항상 같은 판정을 하는 결정적 확인. 위 예가 이 방식
prompt 모델 한 번 호출. 훅 입력만 보고 ok 여부를 JSON으로 답함 Stop에서 ok가 거짓이면 이유가 Claude에게 가고 불가능으로 표시하면 멈춤을 허용. /goal이 이 방식
agent 도구를 쓰는 하위 에이전트. 파일을 읽고 명령을 돌려 실제 상태를 확인 기본 제한 시간 60초, 최대 50 도구 사용 턴. 실험 기능이라 동작이 바뀔 수 있어 운영에는 command를 권장

프롬프트형과 에이전트형 훅은 이벤트당 동시에 최대 12개까지 돌도록 2.1.302에서 제한되었으므로, 모델을 부르는 훅을 여러 개 겹쳐 두는 구성이라면 이 한도를 염두에 둬야 합니다. 정리하면 말로 쓴 조건으로 충분하고 설정 파일을 만지고 싶지 않을 때는 /goal, 같은 입력이면 같은 답이 나와야 하는 검사는 command 훅, 코드베이스의 실제 상태를 직접 열어 봐야 하는 판정은 에이전트형 훅이 알맞습니다.

작업한 쪽이 채점하지 않게 한다

스크립트가 판정해도 “무엇을 확인할지”는 작업한 쪽이 정한 것이라 사각이 남고, 작업한 에이전트가 자기 결과를 채점하면 편향도 남습니다. 결과가 틀렸을 때 비싼 일(결제, 권한, 데이터 이전)에 설명서가 권하는 것이 새 컨텍스트의 검토자입니다. 서브에이전트는 diff와 사용자가 준 기준만 보고 변경을 만든 추론 과정은 보지 못하므로, 결과를 처음부터 자기 기준으로 평가합니다. 기본 제공 /code-review 스킬은 현재 diff를 새 서브에이전트로 검토해 버그를 세션에 돌려주고, 계획 문서와 대조하고 싶으면 프롬프트를 직접 씁니다. 설명서가 드는 형식은 검토할 대상, 대조할 계획, 무엇을 지적 사항으로 칠지를 모두 적는 것입니다.

서브에이전트로 rate limiter diff를 PLAN.md와 대조해 검토하라.
모든 요구 사항이 구현됐는지, 적어 둔 경계 사례에 테스트가 있는지,
작업 범위 밖이 바뀌지 않았는지 본다. 취향 문제 말고 빠진 것만 보고하라.

마지막 줄이 이 프롬프트의 핵심입니다. 빈틈을 찾으라고 시킨 검토자는 작업이 멀쩡해도 뭔가를 보고하기 마련이고, 지적마다 따라가면 추상화 계층, 방어적 코드, 일어날 수 없는 경우의 테스트가 늘어나는 과잉 설계로 갑니다. 설명서는 정확성이나 명시된 요구 사항에 영향을 주는 빈틈만 표시하게 하고 나머지는 선택 사항으로 두라고 안내합니다. 세션을 둘로 나눠 한쪽이 구현하고 다른 쪽이 새 컨텍스트로 검토한 뒤 지적을 구현 쪽에 전달하는 방법도 같은 원리입니다. 동적 워크플로가 자기 발견을 새 모델로 반박해 보게 하는 구성도 4단계에 속합니다.

확인 단계의 끝에는 사용자가 직접 부르는 /verify가 있습니다. 앱을 실제로 빌드하고 띄워 변경이 의도대로 동작하는지 보며, 테스트나 타입 검사로 갈음하지 않습니다. 설정 없이도 README, package.json, Makefile에서 실행법을 짐작하지만, 데이터베이스나 환경 파일, 그래픽 세션, 여러 단계 빌드가 필요한 프로젝트에서는 짐작이 불안정하다고 문서가 적습니다. 한 번 성공한 방법은 .claude/skills/verify/SKILL.md에 기록되어 이후 실행의 기준이 됩니다. 2.1.309에서는 변경한 파일이 중첩된 패키지 안에 있을 때 그 패키지 자신의 스킬을 /verify와 /code-review가 찾지 못하던 문제도 고쳐졌습니다.

확인이 있는 작업은 노력 수준을 낮게 시작한다

네 단계 중 어디를 고르든 같이 정해야 하는 것이 노력 수준입니다. “think harder” 같은 문구로 생각 예산을 늘리던 습관은 설명서에서 정리되었습니다. Claude Code가 키워드로 인식하는 것은 ultrathink 하나이고, 이 단어는 그 턴에만 더 깊이 추론하라는 지시를 문맥에 덧붙일 뿐 API로 보내는 노력 수준은 바꾸지 않습니다. “think”, “think hard”, “think more”는 일반 프롬프트 문장으로 그대로 전달됩니다. 추론 깊이는 /effort가 조절합니다.

수준 설명서가 든 쓰임
low 결과를 일일이 보면서 가는 짧은 대화, 이름 바꾸기 같은 작은 변경
medium Opus 5.5·Sonnet 5.5·Haiku 5.5의 기본값. 범위가 분명한 일상 개발 작업
high 검증이 중요하거나 경계 사례가 많은 작업. 그 밖의 모델은 대부분 기본값
xhigh 더 깊은 추론, 더 많은 토큰. Opus 4.7의 기본값
max 자리를 비우고 맡길 어려운 문제(예: 취약점 찾기). 효과가 줄고 과하게 생각할 수 있으니 널리 쓰기 전에 시험

수준은 우선순위로 정해집니다. 환경 변수 CLAUDE_CODE_EFFORT_LEVEL, --effort, /effort로 직접 고른 값이 가장 앞서고, 그다음이 설정에 저장된 값(모델별 modelSettings 또는 effortLevel 키), 마지막이 모델 기본값입니다. 지원하지 않는 수준을 고르면 그 이하의 가장 높은 수준으로 내려가 실행되고(Opus 4.6에서 xhigh는 high), max는 환경 변수로 정하지 않는 한 현재 세션에만 적용됩니다. Opus 5.5는 시작 수준이 medium이며, 사용자 설정 파일의 최상위 effortLevel 키는 Opus 5.5에 적용되지 않으므로 /effort나 /model 선택으로 직접 정해야 합니다. 같은 키라도 프로젝트·로컬·관리 설정 파일에 있으면 모든 모델에 적용됩니다. 한 세션만 바꾸려면 슬라이더에서 s를 누르고(v2.1.257 이상), 스킬이나 서브에이전트는 frontmatter의 effort로 자기가 돌 때만 수준을 덮어씁니다.

설명서의 시험에서 높은 수준은 경계 사례를 더 많이 시험하고 더 많이 검증하는 대신 스스로 내리는 선택이 많았고, 낮은 수준은 출발점을 빨리 내놓아 결과를 보며 방향을 잡는 일에 맞았습니다. Anthropic의 테스트에서 Opus 5.5는 medium에서 코딩·지식 업무 평가의 Opus 5 high와 같거나 그 이상이라고 하므로, Opus 5에서 옮겨 왔다면 이전 수준을 그대로 가져오지 말고 medium에서 시작하라는 안내입니다. 이 글의 주제와 이으면 방향이 나옵니다. 통과 아니면 실패가 나오는 확인이 걸려 있으면 낮은 수준으로 빨리 돌려 실패한 것을 고치게 하는 편이 효율적이고, 확인 없이 한 번에 맞춰야 하는 작업이 높은 수준을 필요로 합니다. 한 턴만 깊게 생각시키고 싶을 때는 ultrathink를 씁니다. /effort에는 수준과 별개의 Ultracode 토글도 있습니다. 켜 두면 수준을 그대로 둔 채 의미 있는 작업마다 동적 워크플로를 짜서 돌리는 설정으로, 끄는 /effort ultracode off와 xhigh가 아닌 수준에서 켜 둔 채 유지하는 방식은 v2.1.284 이상에서만 됩니다. 두 가지는 바꿀 수 없습니다. Opus 5.5, Sonnet 5.5, Haiku 5.5에서는 생각 기능을 끌 수 없고, alwaysThinkingEnabled: false나 MAX_THINKING_TOKENS=0을 저장해도 효과가 없습니다.

CLAUDE.md는 짧게, 어길 수 없는 규칙은 훅으로

지침 파일은 확인 단계와 한 쌍입니다. “절대 메일을 보내지 말 것”처럼 어겨서는 안 되는 규칙을 CLAUDE.md에 문장으로 적어 두면 Claude가 따를 것이라고 기대할 뿐입니다. 설명서는 CLAUDE.md가 매 세션 시작에 읽히지만 강제 설정이 아니라 컨텍스트로 취급된다고 설명하고, 행동을 막으려면 PreToolUse 훅을 쓰라고 안내합니다. 훅은 정해진 시점에 항상 실행되는 셸 명령이라, LLM이 실행하기로 선택하는 것에 의존하지 않고 특정 동작이 반드시 일어나게 하는 결정적 제어입니다. 훅 안내서에는 .env, package-lock.json, .git/ 아래 파일의 편집을 훅 스크립트가 종료 코드 2로 막고 막은 이유를 Claude에게 되돌려 주는 예제가 있고, 판단이 필요한 조건이라면 모델이 평가하는 프롬프트형 훅을 쓸 수 있습니다.

CLAUDE.md에 남길 것은 설명서가 파일당 200줄 아래를 목표로 하라고 하는 만큼 가려야 합니다. 줄마다 “이 줄을 빼면 Claude가 실수할까?“를 묻고 아니라면 지웁니다. Claude가 같은 실수를 반복하면 파일이 너무 길어 규칙이 묻혔다는 신호이고, CLAUDE.md에 이미 있는 내용을 Claude가 되물으면 표현이 모호하다는 신호입니다.

넣을 것 뺄 것
Claude가 추측할 수 없는 명령 코드를 읽으면 알 수 있는 것
기본값과 다른 코드 스타일 언어의 표준 관례
테스트 방법과 선호하는 실행기 자세한 API 문서(링크로 대체)
브랜치 이름, PR 규칙 자주 바뀌는 정보
프로젝트 고유의 설계 결정 긴 설명, 튜토리얼, 파일별 설명
환경 변수 같은 개발 환경 특이점 “깨끗한 코드를 써라” 같은 당연한 말

@경로 가져오기로 파일을 나누면 정리는 되지만 컨텍스트는 줄지 않습니다. 가져온 파일도 그 CLAUDE.md와 함께 로드되고(최대 4단계까지 이어짐), 코드 조각 안의 @경로는 가져오기로 해석되지 않습니다. 일부 폴더에만 해당하는 지침은 경로 한정 규칙으로 옮깁니다. .claude/rules/ 아래에 규칙 파일을 만들고 맨 위에 paths를 적으면 그 파일을 다룰 때만 로드됩니다.

---
paths:
  - "src/api/**/*.ts"
---
# API 규칙
- 모든 엔드포인트는 입력 검증을 거친다
- 오류 응답은 표준 형식을 쓴다

paths가 없는 규칙 파일은 항상 로드되고, 있는 파일은 Claude가 일치하는 파일을 읽거나 편집할 때 로드됩니다. 지금까지 나온 파일이 어느 경로에 놓이고 언제 읽히는지를 한 장에 모으면 이렇습니다.

프로젝트 폴더 안에서 CLAUDE.md, settings.json, 훅 스크립트, 경로 한정 규칙, verify 스킬이 읽히는 시점을 보여 주는 파일 트리 그림 4. CLAUDE.md와 설정 파일은 매 세션, 훅 스크립트는 턴이 끝날 때, 규칙 파일과 스킬은 해당하는 때에만 읽힌다

그림에서 매 세션 컨텍스트에 들어오는 것은 CLAUDE.md뿐입니다(설정 파일은 훅 등록용이고 컨텍스트에 실리지 않습니다). 규칙 파일과 스킬은 해당하는 때에만 들어오므로, 길어진 CLAUDE.md의 줄 대부분은 이 둘로 옮길 수 있습니다. 강조는 어기는 한 줄에만 붙입니다. “중요”나 “반드시”를 여러 줄에 쓰면 아무것도 눈에 띄지 않는다고 설명서가 말합니다. 정리 도구도 있습니다. 체크인된 CLAUDE.md라면 /doctor가 코드에서 알 수 있는 내용의 삭제안을 주고, v2.1.283 이상에서는 /doctor prompt-audit이 CLAUDE.md와 .claude/ 아래 규칙·스킬·서브에이전트까지 훑어 옛 모델용으로 쓴 지시, 없는 파일을 가리키는 줄, 서로 모순되는 줄을 보고서로 보여 줍니다. 보고서만 만들고 적용은 사용자가 시킨 뒤에 합니다. 2.1.309부터는 너무 큰 중첩 CLAUDE.md를 읽다가 세션이 반복해서 압축되던 문제를 막기 위해 한도를 넘는 파일은 앞부분만 로드합니다.

저장소가 CLAUDE.md 대신 AGENTS.md를 쓴다면, 작업 디렉터리나 그 위에 CLAUDE.md가 없을 때 Claude Code가 AGENTS.md를 프로젝트 지침으로 읽습니다(v2.1.277 이상). 둘 다 있으면 CLAUDE.md만 읽으므로 개인용 CLAUDE.local.md를 추가하는 순간 AGENTS.md는 읽히지 않게 됩니다. 두 파일을 함께 읽게 하려면 CLAUDE.md에서 @AGENTS.md로 가져오거나 프로젝트 지침 설정을 claude-md-and-agents-md로 바꿉니다.

스킬은 껐을 때와 비교해 남긴다

스킬은 지침의 또 다른 자리이지만 만들기 전에 거치는 순서가 다릅니다. 설명서는 스킬이 제대로 일하는지 알려면 현실적인 프롬프트 몇 개를 새 세션에서 스킬이 있을 때와 꺼져 있을 때 각각 돌려 결과를 비교하라고 안내합니다. 새 세션이어야 스킬을 쓰며 남은 컨텍스트가 지침의 빈틈을 가리지 않습니다. 스킬이 발동한 것을 봤다고 해서 결과가 옳다는 뜻은 아니기 때문입니다. 개인·프로젝트 스킬은 skillOverrides에서 "off"로 끄고, 플러그인이 제공하는 스킬은 이 설정이 적용되지 않으므로 플러그인 없이 같은 실행을 반복하는 claude plugin eval로 비교합니다. 결과가 같다면 그 스킬은 토큰만 쓰는 셈입니다.

스킬 목록의 비용도 따져 볼 만합니다. 스킬마다 설명이 매 턴 컨텍스트에 올라가고(description과 when_to_use를 합쳐 1,536자에서 잘리므로 핵심 용도를 앞에 둘 것), 본문은 호출됐을 때만 읽혀 이후 대화에 남습니다. SKILL.md는 500줄 아래로 유지하라는 안내가 있습니다. 직접 부를 때만 쓰는 스킬은 disable-model-invocation: true로 설명을 컨텍스트에서 빼고, /skill-doctor(v2.1.252 이상)는 스킬별 비용과 사용 빈도를 보여 줘 한 번도 호출되지 않은 스킬을 끌 근거를 줍니다.

확인을 거는 만큼 확인 자체가 허술하면 위험도 함께 커집니다. 통과 조건이 약한 테스트이거나 평가 모델이 읽을 증거가 대화에 없다면 /goal은 “통과했다”고 오판정하거나 영원히 미충족이 됩니다. 단계를 올리기 전에 기준이 실제로 실패할 수 있는지를 한 번 보는 것이 가장 싼 보험입니다.

써 보고 일주일 뒤에 열어 볼 곳

  • 최근 일주일에 맡긴 작업 가운데 "끝났다는 기준"을 한 줄로 적어 둔 것이 몇 개인지 세어 본다. 기준이 없던 작업은 지켜본 작업이었는지 확인한다.
  • /goal을 건 작업이 있다면 /goal을 인자 없이 입력해 평가 횟수와 토큰 사용량을 열어 턴 제한이 실제로 상한 노릇을 했는지 본다.
  • CLAUDE.md의 줄 수를 세고, 어긴 적이 있는 규칙 한 줄을 골라 훅으로 옮길 수 있는지 본다.
  • 스킬 목록에서 한 번도 호출되지 않은 것을 /skill-doctor로 찾아 껐을 때 결과가 같은지 비교한다.
#Claude Code#/goal#CLAUDE.md#AI 에이전트#개발 도구