프롬프팅의 근본 원칙
소스 코드를 보면 Claude Code의 시스템 프롬프트에는 명확한 작업 철학이 내장되어 있습니다. 이 철학을 이해하면 프롬프트를 어떻게 써야 하는지 자연스럽게 따라옵니다.
Claude Code가 내부적으로 지키는 3대 원칙
① 최소주의(Minimalism)
요청한 것만 한다. 추가 기능, 리팩토링, 문서화를 절대 스스로 하지 않는다. "세 줄의 비슷한 코드가 성급한 추상화보다 낫다"가 원칙이다.
② 읽고 나서 행동(Read-First)
코드를 보지 않고는 수정 제안을 하지 않는다. 파일을 먼저 Read 도구로 읽고, 이해한 후에 변경한다.
③ 안전 우선(Safety-First)
비가역적 작업(push, 삭제, PR)은 반드시 사용자에게 확인한다. "의심하면 멈추고 물어라"가 기본이다.
프롬프팅의 골든 룰: Claude Code는 요청한 것 정확히 그것만 합니다. 따라서 "무엇을 원하는지"를 구체적으로, "무엇을 원하지 않는지"도 명시하는 것이 가장 중요합니다.
이 원칙이 당신의 프롬프트에 미치는 영향
| Claude의 내부 원칙 | 당신이 해야 할 것 | 당신이 하지 말아야 할 것 |
|---|---|---|
| 최소주의 | 원하는 추가 작업을 명시적으로 요청 | "이것도 해주면 좋겠는데"식 기대 |
| 읽고 나서 행동 | 관련 파일 경로를 힌트로 제공 | "어딘가에 있는 파일" 식의 모호한 참조 |
| 안전 우선 | 자동화하려면 CLAUDE.md에 사전 승인 기록 | 매번 "그냥 해"라고 반복하기 |
CLAUDE.md: 가장 강력한 프롬프트 채널
CLAUDE.md는 모든 세션에 자동으로 시스템 프롬프트에 포함되며, 코드에서 "이 지침은 기본 행동을 OVERRIDE하며 정확히 따라야 합니다"라고 명시되어 있습니다. 즉, CLAUDE.md에 적은 것은 사실상 시스템 프롬프트의 연장선입니다.
CLAUDE.md 작성 법칙
"이 줄이 없으면 Claude가 실수할까?" 테스트
모든 줄에 이 질문을 하세요. "아니오"면 삭제합니다. CLAUDE.md는 길수록 나빠집니다 — 해결하는 것보다 더 많은 혼란을 만들기 때문입니다.
구체적인 명령을 적어라
"코드를 깔끔하게 작성하세요" ❌ → "TypeScript에서 2칸 들여쓰기, type 선호 (interface 대신)" ✅
Claude가 이미 아는 것은 적지 마라
표준 언어 규칙, 일반적인 개발 관행, npm test나 cargo build 같은 표준 명령은 생략합니다.
긴 참조는 @include로 분리하라
API 문서나 아키텍처 설명이 길면 @docs/api-reference.md로 참조합니다. CLAUDE.md 자체는 짧고 핵심적으로 유지합니다.
실전 예시: 좋은 CLAUDE.md vs 나쁜 CLAUDE.md
# CLAUDE.md
항상 클린 코드를 작성하세요.
에러 핸들링을 잘 하세요.
변수명은 의미 있게 지으세요.
모든 함수에 docstring을 작성하세요.
테스트를 작성하세요.
보안에 신경 쓰세요.
성능을 고려하세요.
→ 모든 줄이 Claude가 이미 아는 일반 상식. 토큰만 낭비하고 효과는 제로.
# CLAUDE.md
## Build & Test
- `pnpm build` — TypeScript 컴파일
- `pnpm test:unit -- --run` — 단일 실행
- `pnpm test:unit -- -t "test name"` — 특정 테스트
- `pnpm lint:fix` — lint + auto-fix
## Code Style
- `type` 선호 (interface 대신)
- barrel export (index.ts) 금지
- 에러는 `AppError` 클래스만 사용
## PR Rules
- 브랜치: `feat/`, `fix/`, `chore/` 접두사
- 커밋: Conventional Commits 형식
- merge 전 `pnpm lint && pnpm test:unit` 통과 필수
→ Claude가 코드만 봐서는 알 수 없는 프로젝트 고유 규칙만 포함.
파일 계층 활용하기
| 파일 | 용도 | 예시 내용 |
|---|---|---|
CLAUDE.md | 팀 공유 규칙 | 빌드 명령, 코드 스타일, PR 규칙 |
.claude/rules/testing.md | 주제별 분리 | 테스트 전략, 모킹 규칙, 커버리지 기준 |
CLAUDE.local.md | 개인 설정 (gitignored) | "간결하게 답해줘", 로컬 DB URL, 개인 환경변수 경로 |
~/.claude/CLAUDE.md | 전역 개인 설정 | "한국어로 답변해", 선호 코드 스타일 |
프로 팁: /init 명령어를 실행하면 Claude가 코드베이스를 분석해서 CLAUDE.md를 자동 생성해줍니다. 여기서 시작해서 다듬는 것이 처음부터 쓰는 것보다 효율적입니다.
요청 문구의 기술
같은 의도라도 프롬프트를 어떻게 쓰느냐에 따라 결과 품질이 크게 달라집니다. Claude Code 내부 동작 원리에 맞춘 최적의 문구 패턴을 정리했습니다.
패턴 1: 구체적 위치 + 구체적 행동
Claude는 파일을 먼저 읽고 나서 수정하도록 프로그래밍되어 있습니다. 파일 경로를 명시하면 불필요한 탐색 단계를 줄일 수 있습니다.
"인증 버그를 고쳐줘"
→ Claude가 어떤 인증? 어떤 버그? 를 파악하느라 많은 파일을 탐색해야 합니다.
"src/auth/validate.ts의 42번 줄에서 세션 만료 시 user가 undefined인데 user.id에 접근하는 NPE를 고쳐줘"
→ 파일, 줄 번호, 증상, 원인이 모두 명시되어 즉시 수정 가능.
패턴 2: 의도 설명 + 제약 조건
Claude의 최소주의 원칙 때문에, 원하는 범위를 명확히 해야 합니다.
프롬프트:
UserService에 이메일 중복 검사를 추가해줘.
- src/services/userService.ts의 createUser 메서드에 추가
- 중복이면 DuplicateEmailError를 던져줘 (src/errors.ts에 정의)
- 기존 테스트 파일(src/services/__tests__/userService.test.ts)에 테스트 추가
- 다른 파일은 수정하지 마
이메일 검증 기능 만들어줘
→ "이메일 검증"이 형식 검증인지, 중복 검사인지, SMTP 확인인지 불명확. 어디에 만들지, 테스트도 할지 모호함.
패턴 3: 단계적 요청 (Step-by-step)
복잡한 작업은 한 번에 요청하기보다, 단계를 나눠서 요청하는 것이 품질이 좋습니다.
# 1단계: 현황 파악
현재 인증 시스템의 구조를 파악해줘. 관련 파일과 흐름을 정리해줘.
# 2단계: (Claude의 분석을 확인한 후)
좋아, 그러면 세션 기반 인증을 JWT로 마이그레이션하는 계획을 세워줘.
변경할 파일 목록과 각 파일에서 뭘 바꿀지 정리해줘.
# 3단계: (계획을 확인한 후)
계획대로 진행해줘. `src/auth/` 디렉토리부터 시작해.
패턴 4: 네거티브 지시 (하지 마)
Claude의 최소주의에도 불구하고, 특정 행동을 명시적으로 금지하면 더 정확해집니다.
이 함수를 리팩토링해줘.
- 기존 public API(함수 시그니처)는 바꾸지 마
- 새로운 dependency는 추가하지 마
- 테스트 파일은 건드리지 마
- 주석 추가하지 마
패턴 5: 컨텍스트 제공
에러 메시지, 로그, 스크린샷을 함께 붙여넣으면 Claude가 스스로 디버깅하는 시간을 크게 줄입니다.
이 테스트가 실패해:
$ npm test -- --run src/auth/validate.test.ts
FAIL src/auth/validate.test.ts
✕ should reject expired sessions (15ms)
TypeError: Cannot read property 'id' of undefined
at validateSession (src/auth/validate.ts:42:15)
at Object.<anonymous> (src/auth/validate.test.ts:28:5)
고쳐줘.
→ 에러 메시지, 파일 경로, 줄 번호가 모두 포함되어 정확한 수정이 가능합니다.
작업 범위 조절의 기술
Claude Code는 "요청한 것만 한다"가 원칙이므로, 원하는 범위를 정확히 전달하는 것이 핵심입니다.
범위 확장: 추가 작업을 명시적으로 요청
src/api/users.ts에 DELETE /users/:id 엔드포인트를 추가해줘.
추가로:
- 해당 엔드포인트의 단위 테스트도 작성해줘
- src/api/routes.ts의 라우터에도 등록해줘
- 관리자 권한 체크를 미들웨어로 넣어줘
→ "추가로:" 이하가 없었다면 Claude는 users.ts만 수정하고 끝냈을 것입니다.
범위 축소: 특정 영역만 제한
이 함수의 성능을 개선해줘.
단, 이 함수의 시그니처와 반환값은 바꾸지 마.
다른 파일은 건드리지 마.
Effort 레벨 활용
Claude Code는 /effort 명령어로 응답의 깊이를 조절할 수 있습니다.
| 레벨 | 사용 시점 | 예시 프롬프트 |
|---|---|---|
| low | 간단한 질문, 한 줄 수정 | "이 변수명을 snake_case로 바꿔줘" |
| medium (기본) | 일반적인 구현, 버그 수정 | "이 API 엔드포인트에 인증 추가해줘" |
| high | 심층 분석, 대규모 리팩토링 | "전체 인증 아키텍처를 분석하고 개선안을 제시해줘" |
피드백 전략: "기억"에 남는 지시
Claude Code에는 자동 메모리 시스템이 있습니다. 구체적인 피드백을 주면 자동으로 저장되어 다음 세션에서도 반영됩니다.
자동 저장되는 피드백 유형
"아 그거 말고"
"다시 해봐"
"좀 더 잘 해줘"
→ 너무 모호해서 무엇을 기억해야 할지 파악 불가.
"이 프로젝트에서는 DB 모킹하지 마. 지난번에 모킹된 테스트가 통과했는데 프로덕션 마이그레이션에서 터졌어"
"import 정렬 바꾸지 마, Prettier가 자동으로 해"
"응, 하나의 PR로 묶는 게 맞아"
→ 구체적 행동 + 이유가 포함되어 feedback 메모리로 자동 저장됩니다.
효과적 피드백 공식
[하지 마 / 이렇게 해] + [구체적 대상] + [이유]
예시들:
"테스트에서 setTimeout 모킹하지 마 — vi.useFakeTimers()를 써"
"에러 메시지를 한국어로 쓰지 마 — 이 프로젝트는 영어 에러 메시지를 쓴다"
"console.log 대신 logger.debug를 써 — 프로덕션에서 로그 레벨 제어가 필요해서"
"그래, findAll보다 findMany가 이 프로젝트에서 맞아" (긍정 피드백도 저장됨)
내부 동작: Claude는 교정 피드백("하지 마")뿐 아니라 확인 피드백("응 그게 맞아")도 메모리에 저장합니다. 특이한 접근법을 승인했다면, Claude가 그 결정을 기억하고 반복합니다.
컨텍스트 관리 전략
Claude Code는 대화가 길어지면 자동으로 요약(Compact)합니다. 하지만 전략적으로 컨텍스트를 관리하면 더 정확한 결과를 얻을 수 있습니다.
3가지 컨텍스트 관리 도구
| 명령어 | 효과 | 사용 시점 |
|---|---|---|
/compact | 대화를 9개 섹션으로 요약 | 긴 작업 중 컨텍스트가 가득 찰 때 |
/clear | 대화 초기화 (모든 맥락 삭제) | 완전히 새로운 작업 시작 시 |
/context | 현재 컨텍스트 사용량 확인 | 컨텍스트가 얼마나 남았는지 궁금할 때 |
컨텍스트 절약 패턴
짧은 작업은 하나의 세션에서:
# 같은 영역의 연속 작업 → 같은 세션
"이 함수 리팩토링해줘"
→ "좋아, 이 함수의 테스트도 업데이트해줘"
→ "lint 에러도 고쳐줘"
완전히 다른 작업은 새 세션에서:
# 인증 모듈 작업 완료 후 → /clear
"이제 결제 모듈 보자. src/payment/ 구조를 파악해줘"
Compact 지시사항을 CLAUDE.md에 추가:
## Compact Instructions
요약할 때 테스트 출력과 코드 변경 사항에 집중해줘.
에러 메시지는 전문을 포함해줘.
주의: /compact는 요약이지 삭제가 아닙니다. 요약 과정에서 세부 사항(특히 코드 스니펫)이 일부 생략될 수 있으므로, 중요한 코드 변경이 있었다면 compact 전에 해당 내용을 커밋해두는 것이 좋습니다.
복합 작업 프롬프팅
큰 작업을 효과적으로 처리하는 고급 프롬프팅 기법입니다.
기법 1: Plan 모드 활용
복잡한 구현 전에 먼저 계획을 세우도록 유도합니다.
결제 시스템을 Stripe에서 Toss Payments로 마이그레이션해야 해.
먼저 계획부터 세워줘:
1. 영향받는 파일 목록
2. 각 파일에서 뭘 바꿔야 하는지
3. 마이그레이션 순서 (의존성 고려)
4. 테스트 전략
구현은 내가 계획을 확인한 다음에 시작해.
기법 2: Agent 활용 (병렬 탐색)
Claude Code는 서브에이전트를 이용해 여러 조사를 동시에 수행할 수 있습니다.
이 모노레포에서 다음 세 가지를 병렬로 조사해줘:
1. packages/api/에서 인증 관련 코드 구조
2. packages/web/에서 로그인 플로우
3. packages/shared/에서 공통 타입 정의
각각 파일 경로와 핵심 함수를 정리해줘.
→ Claude가 내부적으로 Agent 도구를 사용하여 각 조사를 서브에이전트에게 위임합니다.
기법 3: 반복 작업 자동화
비슷한 패턴의 수정을 여러 파일에 적용할 때:
src/api/routes/ 아래 모든 라우터 파일에서:
1. express의 Router를 @hono/hono의 Hono로 교체
2. req.params를 c.req.param()으로 변경
3. res.json()을 c.json()으로 변경
4. 미들웨어 형식도 Hono 호환으로 변경
먼저 users.ts 하나만 변환해서 보여줘.
내가 확인하면 나머지도 같은 패턴으로 변환해.
→ 먼저 하나의 예시를 확인한 후 나머지를 진행하는 "파일럿 패턴"이 안전합니다.
기법 4: /commit과 /review 활용
# 구현 완료 후 — 커밋
/commit
# 커밋 전 — 변경 사항 셀프 리뷰
/review
# 보안 관점 리뷰
/security-review
# 커밋 + 푸시 + PR 한 번에
/commit-push-pr
도구를 극대화하는 프롬프트
Claude Code의 도구 선택은 시스템 프롬프트에 의해 결정됩니다. 하지만 프롬프트 방식에 따라 도구 활용 효율을 높일 수 있습니다.
검색 효율 높이기
"이 프로젝트에서 인증 관련 코드를 찾아줘"
→ 너무 광범위해서 많은 Grep/Glob 호출이 필요.
"src/ 아래에서 verifyToken 함수가 호출되는 모든 위치를 찾아줘"
→ 구체적 함수명 + 검색 범위로 Grep 한 번이면 됨.
Bash 직접 실행 유도하기
외부 서비스 인터랙션이나 CLI 도구 실행이 필요할 때:
# Docker 컨테이너 관련
"docker compose up -d로 로컬 DB를 시작하고, 마이그레이션을 실행해줘"
# 외부 CLI 도구
"gh pr list --state open으로 열린 PR 목록을 가져와줘"
# 빌드 & 테스트
"pnpm build && pnpm test:unit -- --run 실행해서 결과 알려줘"
! 접두사로 직접 명령 실행
인터랙티브한 명령이 필요할 때 사용자가 직접 실행할 수 있습니다:
# 프롬프트에서 직접 실행 (결과가 대화에 포함됨)
! gcloud auth login
! aws sso login --profile dev
! docker compose logs api --tail 50
MCP 도구 연동
# GitHub MCP가 연결되어 있을 때
"이 커밋과 관련된 GitHub 이슈를 찾아줘"
"PR #42에 달린 리뷰 코멘트를 확인하고 반영해줘"
# DB MCP가 연결되어 있을 때
"users 테이블의 스키마를 확인하고,
새 migration 파일을 만들어서 email_verified 컬럼을 추가해줘"
안티패턴: 이렇게 하지 마세요
Claude Code 소스를 분석해서 발견한, 프롬프팅에서 효과가 떨어지거나 역효과를 내는 패턴들입니다.
🚫 "적당히 알아서 해줘"
Claude는 최소주의를 따르므로, "알아서"의 범위를 추측하지 않습니다. 결과가 기대보다 적을 가능성이 높습니다.
🚫 한 번에 모든 것 요청
"프로젝트 전체를 리팩토링하고, 테스트 작성하고, 문서 업데이트하고, CI 파이프라인도 고쳐줘" → 범위가 너무 넓어 결과 품질 저하.
🚫 cat/grep/find 명시
"cat으로 파일 읽어줘" → Claude는 어차피 Read 도구를 사용합니다. 명령어 지정보다 의도를 말하세요. "이 파일 보여줘"가 낫습니다.
🚫 반복적인 "그냥 해"
위험한 작업에 대한 확인 프롬프트가 뜨는 건 안전장치입니다. 자동화하려면 CLAUDE.md에 사전 승인을 적으세요.
🚫 CLAUDE.md에 소설 쓰기
40,000자 이상의 CLAUDE.md는 효과가 떨어집니다. 핵심만, 짧게, @include로 분리하세요.
🚫 같은 실패를 반복 재시도
Claude 내부에 "동일 실패 재시도 금지" 규칙이 있습니다. 에러가 나면 "다시 해봐" 대신 에러 원인에 대한 힌트를 주세요.
안티패턴 → 개선패턴 변환표
| 안티패턴 | → 개선 |
|---|---|
| "이 코드 좀 개선해줘" | "이 함수의 시간복잡도를 O(n²)→O(n)으로 줄여줘" |
| "테스트 추가해줘" | "createUser의 이메일 중복 케이스 테스트를 추가해줘" |
| "이거 왜 안 돼?" | "이 에러가 나와: [에러 텍스트]. 어떤 원인인지 분석해줘" |
| "전체적으로 리뷰해줘" | "/review (또는) src/auth/ 디렉토리의 보안 관점 리뷰해줘" |
| "이전에 한 것처럼 해줘" | "지난번에 users.ts에서 한 것처럼 Hono 라우터로 변환해줘" |
| "다시 해봐" | "timeout이 아니라 connection refused야. DB가 실행 중인지 확인해줘" |
프롬프트 치트시트
바로 복사해서 쓸 수 있는 프롬프트 템플릿 모음입니다.
🐛 버그 수정
[파일경로]의 [줄번호] 근처에서 [증상]이 발생해.
원인은 [추정 원인]인 것 같아.
[어떻게 고쳐야 하는지] 수정해줘.
관련 테스트도 확인해줘.
✨ 새 기능 추가
[기존파일]에 [기능]을 추가해줘.
요구사항:
- [구체적 동작 1]
- [구체적 동작 2]
- 에러 시 [에러 처리 방식]
제약:
- [건드리지 말 것]
- [사용하지 말 것]
테스트도 작성해줘: [테스트파일 경로]
♻️ 리팩토링
[파일/함수]를 리팩토링해줘.
목표: [왜 리팩토링하는지]
방향: [어떤 패턴/구조로]
지키기:
- public API(함수 시그니처) 유지
- 기존 테스트 통과
- [기타 제약]
🔍 코드 분석
[디렉토리/모듈]의 구조를 분석해줘.
알고 싶은 것:
- 주요 파일과 각 역할
- 데이터 흐름 (입력 → 처리 → 출력)
- 외부 의존성
- [특정 관심사]
📋 프로젝트 초기 설정
/init
# 또는 수동으로:
이 프로젝트를 분석해서 CLAUDE.md를 작성해줘.
특히:
- 비표준 빌드/테스트 명령
- 팀 코드 스타일 규칙
- 중요한 아키텍처 결정
- 자주 하는 실수를 방지할 수 있는 규칙
🔄 Git 워크플로우
# 스테이지된 변경사항 커밋
/commit
# 변경사항 리뷰 → 커밋 → 푸시 → PR
/review
/commit-push-pr
# 특정 파일만 diff 확인
/diff src/auth/
💬 일상 대화 패턴
# 설명 요청
"이 코드가 뭐 하는 건지 설명해줘: src/auth/middleware.ts"
# 비교
"JWT와 세션 기반 인증의 장단점을 이 프로젝트 맥락에서 비교해줘"
# 환경 실행 (! 접두사)
! docker compose ps
! curl http://localhost:3000/health
마지막 조언: 프롬프팅은 기술이 아니라 소통입니다. Claude Code를 "뛰어난 주니어 개발자"로 생각하세요 — 무엇을 해야 하는지 정확히 알려주면 훌륭하게 수행하지만, 모호한 지시에는 최소한의 안전한 해석을 합니다. 구체적으로, 명시적으로, 그리고 필요하면 단계적으로 소통하세요.