들어가며
회사에서 Claude Code를 도입하고 나서 처음엔 생산성이 확 올라갔다.
근데 쓰면 쓸수록 두 가지가 계속 신경 쓰였다. 하나는 세션이 길어질수록 답변 품질이 떨어진다는 것, 또 하나는 API 비용이 생각보다 많이 나온다는 것이었다. 아침에 물어볼 때랑 오후에 물어볼 때 결과물이 달랐고, 분명히 잘 됐던 패턴인데 나중엔 맥락을 못 잡는 경우도 생겼다.
처음엔 그냥 모델이 원래 이런가 싶었다. 근데 찾아보니 원인은 컨텍스트를 제대로 관리하지 않고 있었던 것이다. Claude Code가 어떻게 동작하는지 제대로 이해하지 못한 채 그냥 채팅하듯 쓰고 있었다. 공식 문서랑 기술 블로그들을 찾아보면서 그 내용들을 이 글에 정리해뒀다.
Claude Code를 이미 쓰고 있는데 뭔가 비효율적인 것 같다는 느낌이 드는 사람한테 도움이 됐으면 한다.
1. Claude Code란
Claude Code는 Anthropic이 만든 터미널 기반 AI 코딩 에이전트다.
파일 읽기·쓰기, bash 명령어 실행, 멀티파일 리팩토링을 자율적으로 수행하는 에이전트다. 처음 써봤을 때 가장 놀란 부분은 직접 파일을 수정한다는 것이었다. ChatGPT 같은 도구는 제안을 해주면 직접 복사 붙여넣기를 해야 하는데 Claude Code는 내가 승인만 하면 실제로 코드베이스에 쓴다. 편한 만큼 잘못됐을 때 되돌리는 게 중요하다는 걸 나중에 깨달았다. 그래서 Plan Mode가 있는 거고, Rewind 기능이 있는 것이다.
일반 AI 어시스턴트 vs Claude Code
일반 AI 어시스턴트Claude Code인터페이스채팅 UI터미널 네이티브코드 적용복붙 필요직접 파일 수정컨텍스트단일 파일코드베이스 전체작업 범위단발성 제안멀티스텝 자율 실행
설치는 Node.js 18+ 환경에서
npm install -g @anthropic-ai/claude-code
claude # 최초 실행 시 API 키 설정
2. 컨텍스트(Context)의 정확한 의미
정의
컨텍스트 = Claude가 응답을 생성할 때 "지금 이 순간 참조할 수 있는 텍스트의 총합"
Claude는 대화 사이에 아무것도 기억하지 않는다. 매 응답마다 하나의 입력 뭉치를 받아 처리한다. 그 뭉치 전체가 컨텍스트다.
이걸 이해하고 나서 많은 게 설명됐다. 세션이 길어질수록 이 뭉치가 커지고, 커질수록 Claude가 더 많은 걸 읽어야 한다. 비용이 올라가는 것도, 답변이 이상해지는 것도 다 여기서 시작되는 것이다.
컨텍스트 창(Context Window)의 구성
/context 명령어를 실행하면 실제로 이렇게 분류된다:
Context Usage — claude-opus-4-651k / 200k tokens (26%)
System prompt: 2.6k tokens (1.3%) ← Claude Code 자체 지침
System tools: 17.6k tokens (8.8%) ← 내장 툴 정의
MCP tools: 0.9k tokens (0.5%) ← 연결된 MCP 서버
Custom agents: 0.9k tokens (0.5%) ← 정의한 서브에이전트
Memory files: 0.3k tokens (0.2%) ← 자동 저장된 메모리
Skills: 0.1k tokens (0.0%) ← 로드된 스킬 메타데이터
Messages: 30.5k tokens (15.3%) ← 대화 이력 + 읽은 파일
─────────────────────────────────────────
Free space: 114.0k tokens (57.0%)
Autocompact buffer: 33.0k tokens (16.5%) ← 예약 공간
중요: 시스템 프롬프트, 툴 정의, MCP 연결만으로도 세션 시작 전에 이미 20k+ 토큰을 소비한다.
컨텍스트 창 크기
모델컨텍스트 창비고Claude Opus 4.61,000,000 tokens2026.03 기준 일반 제공Claude Sonnet 4.61,000,000 tokens2026.03 기준 일반 제공기타 모델200,000 tokens
2026년 3월 13일부로 Opus 4.6, Sonnet 4.6의 1M 컨텍스트 창이 추가 요금 없이 정식 제공된다.
이전에는 200k 초과분에 대해 2× 요금이 부과됐다.
왜 컨텍스트 관리가 중요한가
Claude는 매 응답마다 컨텍스트 전체를 처음부터 끝까지 읽는다.
따라서 컨텍스트가 클수록
- 처리 비용이 선형적으로 증가
- 응답 속도가 느려짐
- 관련 없는 정보가 섞이면 응답 품질이 저하됨 (Context Rot)
공식 문서의 정의: 더 많은 컨텍스트가 자동으로 더 좋은 건 아니다. 토큰 수가 늘어날수록 정확도와 재현율이 저하되는 현상을 컨텍스트 로트(Context Rot)라고 한다. 이게 내가 겪던 문제의 이름이었다. 세션이 길어질수록 답변이 이상해지는 게 모델 문제가 아니라 컨텍스트 로트였던 것이다. 생각해보면 당연한 얘기인데, Claude Code를 쓰면서 이걸 의식한 적이 한 번도 없었다.
3. 프로젝트 파일 구조
Claude Code가 인식하는 전체 파일 구조
your-project/
├── CLAUDE.md # 팀 공유 프로젝트 지침 (git 관리)
├── CLAUDE.local.md # 개인 지침 (.gitignore 권장)
│
└── .claude/
├── settings.json # 공유 설정 (권한, 툴, hooks) (git 관리)
├── settings.local.json # 개인 설정 (.gitignore 권장)
│
├── rules/ # 조건별 분리 규칙
│ ├── code-style.md # 해당 파일 건드릴 때만 로드
│ └── security.md
│
├── skills/ # 슬래시 커맨드 + 자동 호출 (권장)
│ └── review-pr/
│ └── SKILL.md
│
├── commands/ # 레거시 슬래시 커맨드 (여전히 동작)
│ └── deploy.md
│
└── agents/ # 서브에이전트 정의
└── code-reviewer/
└── AGENT.md
글로벌 설정 위치 (모든 프로젝트에 적용)
~/.claude/
├── CLAUDE.md # 전역 지침
├── settings.json # 전역 설정
└── skills/ # 전역 스킬
4. CLAUDE.md
역할
CLAUDE.md는 매 세션 시작 시 자동으로 컨텍스트에 로드된다. Claude가 프로젝트 규칙, 기술 스택, 명령어를 미리 알게 되어 매번 설명할 필요가 없다. 이 파일이 없으면 Claude는 매번 코드베이스를 탐색해서 빌드 명령어가 뭔지, 어떤 라이브러리를 쓰는지 파악해야 한다.
근데 여기서 함정이 있다. 처음에 CLAUDE.md를 쓸 때 많이 넣을수록 좋겠지라고 생각했는데 아니었다. 이 파일은 매 메시지마다 컨텍스트에 들어온다. 줄 하나가 토큰이고, 그게 모든 메시지에 곱해진다. 길게 쓰면 쓸수록 매 응답마다 불필요한 걸 읽고 있는 것이다.
기본 구조 템플릿
# Project: [프로젝트명]
## Commands- Build: npm run build
- Lint: npm run lint -- --fix
- Test: npm test
- Dev: npm run dev
## Architecture- Frontend: Next.js 15 (App Router) + TypeScript
- Backend: Spring Boot 3.x + Java 17
- DB: PostgreSQL + JPA
- State: Zustand (전역), TanStack Query (서버)
## Code Conventions- TypeScript strict mode 필수
- Default export 사용 금지
- 커밋 포맷: feat/fix/chore(scope): description
- 컴포넌트: PascalCase, 유틸 함수: camelCase
## Key Directories- `src/components/` — 공통 UI 컴포넌트
- `src/features/` — 기능별 모듈
- `src/utils/` — 공통 유틸리티
- `docs/` — 상세 문서 (@docs/architecture.md 참고)
작성 원칙
포함해야 할 것
- 빌드/테스트/배포 명령어
- 핵심 기술 스택
- 코딩 컨벤션 (네이밍, 포맷, 커밋)
- 절대 하지 말아야 할 것 ("No default exports", "No var")
- 주요 디렉토리 구조
포함하지 말아야 할 것
- 긴 코드 스니펫 (빠르게 outdated됨)
- 특정 워크플로우 전체 절차 → Skills로 분리
- README에 이미 있는 내용 중복
길이 제한
- 루트 CLAUDE.md는 200줄 이하 권장
- 세부 내용은
@docs/architecture.md형태로 참조 - CLAUDE.md가 README보다 길면 잘못된 것
/init으로 초안 자동 생성
claude
> /init
Claude가 프로젝트 구조, 빌드 시스템, 테스트 프레임워크를 스캔해서 초안을 생성한다. 생성 후 불필요한 줄을 삭제하는 게 처음부터 쓰는 것보다 빠르다. 모든 줄이 컨텍스트 비용이라는 걸 기억할 것.
계층적 로드
CLAUDE.md는 계층적으로 로드된다
~/.claude/CLAUDE.md— 전역 (모든 프로젝트)프로젝트루트/CLAUDE.md— 프로젝트 전체src/CLAUDE.md— 해당 디렉토리 작업 시 추가 로드src/components/CLAUDE.md— 더 깊은 중첩 가능
5. Skills — 재사용 가능한 워크플로우
Skills vs 이전 Commands
.claude/commands/(레거시)와 .claude/skills/(현재 권장)는 동일하게 슬래시 커맨드를 생성하지만, Skills는 추가 기능을 제공한다.
공부하면서 알게 된 건데, 이전에 .claude/commands/에 뭔가 만들어두고 있었다면 그게 사실상 Skills의 구버전이다. 기능은 동일하게 작동하니까 당장 마이그레이션할 필요는 없고, 새로 만드는 건 Skills 형식으로 하면 된다.
Commands (레거시)Skills (현재)슬래시 커맨드OOClaude 자동 호출XO (description 기반)서브파일 지원XO (references/, scripts/)허용 툴 제한XO (frontmatter)
SKILL.md 구조
---name: review-prdescription: PR diff를 가져와 보안·로직 오류 리뷰. 코드 변경 후 자동 호출.allowed-tools: Read, Grep, Glob, Bash(git diff:*)argument-hint: "[PR번호]"user-invocable: true # /review-pr 커맨드로 호출 가능 (기본: true)disable-model-invocation: false # Claude 자동 호출 허용 (기본: false)---
## 지침
$ARGUMENTS에 해당하는 PR diff를 `gh pr diff $ARGUMENTS`로 가져와라.
리뷰 항목:1. 로직 오류 및 엣지 케이스 누락2. 보안 취약점 (SQL Injection, XSS 등)3. 누락된 에러 핸들링
**스타일, 네이밍 컨벤션은 언급하지 마라.**결과는 항목별로 간결하게 정리하라.
description 필드가 핵심
description은 설명이 아니라 Claude가 언제 이 skill을 자동 호출할지 결정하는 트리거 문장이다.
# 나쁜 예 — 너무 광범위description: "코드 품질을 체크한다"
# 좋은 예 — 구체적인 발화 조건description: "drafts/ 디렉토리의 마크다운 파일 작성·편집 시 브랜드 보이스 규칙 체크"
이게 처음엔 좀 헷갈렸다. 그냥 이 skill이 뭘 하는지 쓰면 되는 줄 알았는데, 실제로는 언제 이걸 실행해야 하는지를 모델한테 알려주는 문장이다. 모호하게 쓰면 Claude가 아무 때나 갖다 붙인다.
실전 활용 예시
커밋 메시지 자동 생성
---name: commitdescription: staged 변경사항으로 커밋 메시지 생성. git add 후 자동 호출.allowed-tools: Bash(git diff:*, git log:*)---
`git diff --staged`로 변경사항 확인 후 커밋 메시지 작성:- 제목: 50자 이하, 동사 원형으로 시작- 본문: 변경 이유와 영향 범위- 포맷: feat/fix/chore(scope): description
문서 업데이트 자동화
---name: update-docsdescription: 코드 변경 후 관련 문서 자동 업데이트allowed-tools: Read, Write, Glob---
변경된 파일을 분석해서 docs/ 디렉토리의 관련 문서를 업데이트하라.API 변경은 반드시 docs/api.md에 반영한다.
Skills 위치별 범위
# 프로젝트 범위 (팀 공유, git 관리)
.claude/skills/review-pr/SKILL.md
# 전역 범위 (개인 모든 프로젝트)
~/.claude/skills/my-workflow/SKILL.md
6. Hooks — 결정론적 자동화
왜 Hooks가 필요한가
프롬프트로 코드 작성 후 Prettier 실행해줘라고 해도 Claude가 매번 하리라는 보장이 없다. LLM은 확률적이다. Hooks는 특정 이벤트에 쉘 커맨드를 확정적으로 연결한다.
이게 Hooks의 핵심이다. 프롬프트는 "부탁"이고, Hook은 "규칙"이다. 타입 체크, 린트, 포맷팅처럼 매번 빠뜨리면 안 되는 것들은 프롬프트에 넣지 말고 Hook으로 걸어두는 게 맞다. CI에서 터지기 전에 Claude가 즉각 피드백을 받고 수정할 수 있다.
설정 위치
.claude/settings.json # 팀 공유
~/.claude/settings.json # 전역 개인 설정 (API 키, 알림 등)
주의: API 키, 개인 선호 설정(알림음, 플러그인 토글)은 절대 git에 커밋하지 않는다.
settings.local.json또는 전역 설정 파일에만 작성한다.
지원 이벤트
이벤트발화 시점SessionStart세션 시작 또는 재시작 시UserPromptSubmit사용자 프롬프트 전송 전PreToolUse툴 실행 전 (차단 가능)PostToolUse툴 실행 후NotificationClaude가 알림 전송 시StopClaude 작업 완료 시SubagentStop서브에이전트 완료 시InstructionsLoadedCLAUDE.md 로드 시
기본 설정 예시
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write(*.py)",
"hooks": [
{ "type": "command", "command": "python -m black \"$file\"" }
]
},
{
"matcher": "Write(*.ts)",
"hooks": [
{ "type": "command", "command": "npx tsc --noEmit --skipLibCheck" }
]
},
{
"matcher": "Write(*.java)",
"hooks": [
{ "type": "command", "command": "mvn checkstyle:check -q" }
]
}
],
"Stop": [
{
"hooks": [
{ "type": "command", "command": "afplay /System/Library/Sounds/Blow.aiff" }
]
}
]
}
}
Exit Code 동작 방식
공식 문서 기준
Exit Code의미동작0성공stdout의 JSON 파싱 (있는 경우)2블로킹 에러PreToolUse: 툴 실행 차단, UserPromptSubmit: 프롬프트 거부기타논블로킹 에러무시하고 계속 실행
고급 패턴: 위험한 커맨드 차단
#!/bin/bash# .claude/hooks/block-dangerous.sh
TOOL_INPUT="$1"
# rm -rf / 같은 위험한 패턴 차단if echo "$TOOL_INPUT" | grep -qE "rm\s+-rf\s+/|DROP\s+TABLE|DELETE\s+FROM\s+\w+\s*;"; then
echo "위험한 명령어가 감지됐습니다: $TOOL_INPUT" >&2exit 2 # 블로킹 에러
fi
exit 0
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "bash .claude/hooks/block-dangerous.sh '$tool_input'" }
]
}
]
}
}
SessionStart로 컨텍스트 자동 주입
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "echo \"Today: $(date '+%Y-%m-%d %A')\nRecent commits:\n$(git log --oneline -5 2>/dev/null)\nOpen issues:\n$(gh issue list --limit 5 2>/dev/null)\""
}
]
}
]
}
}
SessionStart 훅의 stdout은 Claude가 볼 수 있는 컨텍스트로 주입된다. 현재 날짜, 최근 커밋, 열린 이슈 등을 자동으로 알려줄 수 있다.
7. Subagent — 컨텍스트 격리
핵심 개념
무거운 작업(대규모 파일 탐색, 긴 테스트 실행, 로그 분석)을 메인 컨텍스트에서 실행하면 대화 이력이 빠르게 부풀어 오른다. Subagent는 격리된 컨텍스트 창에서 작업을 수행하고 결과만 메인으로 반환한다.
중요:
.claude/agents/*.md의 내용은 서브에이전트의 시스템 프롬프트다. 유저 프롬프트가 아니다. 가장 흔한 오해.
AGENT.md 구조
---name: code-reviewerdescription: 코드 변경 후 자동 리뷰. 보안·성능·유지보수성 체크.tools: Read, Grep, Glob, Bashmodel: sonnet---
당신은 시니어 개발자다.코드 리뷰 시 아래 우선순위로 확인하라:
1. 보안 취약점 (SQL Injection, XSS, 인증 누락)2. 성능 이슈 (N+1 쿼리, 불필요한 반복)3. 에러 핸들링 누락4. 유지보수성 (복잡도, 명명 규칙)
스타일 지적은 하지 않는다.결과는 항목별로 간결하게 정리한다.
context: fork 패턴
Skills에서 context: fork를 사용하면 스킬 전체가 격리된 서브에이전트에서 실행된다. 중간 툴 호출 결과는 서브에이전트 컨텍스트에만 남고, 메인 컨텍스트에는 최종 결과만 돌아온다.
8. 컨텍스트 관리 전략
컨텍스트 오염이란
컨텍스트 오염(Context Pollution)은 현재 작업과 무관한 정보가 컨텍스트를 차지하는 현상이다. 오래된 디버깅 로그, 이미 해결된 이슈, 다른 기능의 파일 내용이 계속 남아 있으면
- 매 응답마다 불필요한 토큰을 처리함
- Claude가 관련 없는 컨텍스트에서 잘못된 패턴을 참조할 수 있음
이게 내가 경험한 오후에 답변이 이상해지는 현상의 정체였다. A 기능 작업하면서 읽어둔 파일들이 B 기능 작업할 때도 그대로 컨텍스트에 남아서, Claude가 엉뚱한 파일을 참조하고 있던 것이다.
오염 신호 3가지
- Claude가 이미 줬던 정보를 반복함
- 다른 모듈의 파일을 섞어서 참조함
- 이전 대화에서 논의한 구버전 패턴을 적용함
핵심 커맨드
/clear — 세션 완전 초기화
> /clear
다른 작업으로 전환할 때 반드시 실행. 대화 이력, 읽은 파일, 모든 누적 컨텍스트가 삭제된다. /rename으로 이름 붙여두면 나중에 /resume으로 복귀 가능.
언제 써야 하나: 완전히 다른 기능 작업, 다른 모듈로 전환, 새 버그 리포트 시작
처음엔 /clear를 자주 치는 게 오히려 비효율적이지 않을까 싶었다. 대화 이력을 쌓아두면 Claude가 맥락을 더 잘 이해하지 않을까 하는 생각이었다. 근데 실제로는 반대다. 관련 없는 이전 작업 내용이 쌓일수록 Claude가 지금 작업에 집중하지 못한다. 컨텍스트는 "많을수록 좋다"가 아니라 "지금 필요한 것만 있어야 한다"는 게 핵심이었다.
/compact — 요약 압축
> /compact
> /compact API 계약과 에러 처리 위주로 요약해줘 # 커스텀 지침
현재 대화를 요약해서 컨텍스트를 줄인다. 95% 도달 시 자동 실행되지만, 그 전에 수동으로 실행하는 게 낫다 — 자동 compaction은 중요한 컨텍스트를 잃을 수 있다.
/clear와의 차이를 처음엔 몰랐다. /clear는 완전히 지우는 거고, /compact는 요약해서 압축하는 거다. 같은 작업을 이어가야 하는데 컨텍스트가 너무 커졌을 때 쓰는 게 /compact다. 특히 커스텀 지침을 넣을 수 있다는 게 중요한데, 요약할 때 어떤 내용을 보존할지 직접 지정할 수 있어서 자동 compaction보다 훨씬 낫다고 판단했다.
/context — 현재 사용량 확인
> /context
카테고리별 토큰 사용량을 보여준다. 어디서 토큰이 새는지 파악하는 첫 번째 도구.
이걸 처음 쳤을 때 System tools가 17k나 잡아먹고 있는 걸 보고 놀랐다. 내가 아무것도 안 했는데 세션 시작부터 이미 20k 가까이 소비된 상태라는 걸 그때 처음 알았다. MCP 서버 연결하나가 얼마나 무거운지도 여기서 처음 확인했다.
Auto-compaction 임계값
Claude Code는 컨텍스트가 약 83.5% 차면 자동 compaction을 실행한다 (2026년 초 기준, 이전 77~78%에서 조정됨). 예약 버퍼는 약 33k 토큰 (16.5%).
200k 창 기준 실사용 가능 공간: 200k × 83.5% = 167k tokens
1M 창 기준: 1M × 83.5% = 835k tokens
@파일 참조 — 필요한 것만 로드
# 특정 파일만 컨텍스트에 추가
> @src/auth/token.ts에서 만료 처리 로직 확인해줘
# 여러 파일
> @src/components/Login.tsx와 @src/hooks/useAuth.ts 리뷰해줘
@파일명 없이 "auth 관련 코드 확인해줘"라고 하면 Claude가 파일을 탐색하면서 불필요한 파일까지 읽을 수 있다.
이게 생각보다 차이가 크다. Claude한테 "알아서 찾아봐"라고 하면 관련 있을 것 같은 파일을 다 읽는다. 그 탐색 결과가 전부 컨텍스트에 쌓인다. 내가 원하는 파일 하나를 명시하는 것과, Claude가 알아서 10개를 읽는 것의 차이다. 프롬프트가 조금 귀찮아지더라도 파일을 명시하는 게 낫다고 판단했다.
.claudeignore — 읽지 말아야 할 파일 지정
# .claudeignore
node_modules/
dist/
build/
*.log.env.env.*
coverage/
9. 토큰 비용 최적화
비용 구조 이해
Input 토큰: 대화 이력 + 파일 + 시스템 프롬프트 + 툴 결과
Output 토큰: Claude의 응답 + 생성 코드 + thinking 토큰
Output 토큰은 Input보다 5배 비싸다 (Sonnet 4.6 기준: Input $3/M, Output $15/M).
컨텍스트의 80%는 파일 읽기와 툴 결과가 차지하고, 실제 메시지는 20% 정도다.
이걸 보고 나서 비용을 줄이는 방향이 명확해졌다. 짧게 묻는 게 중요한 게 아니라, 쓸데없이 쌓인 컨텍스트를 줄이는 게 핵심이었다. 그리고 Output이 Input보다 5배 비싸다는 것 — 즉 "더 간결하게 답해줘"라는 요청 하나가 생각보다 큰 효과가 있다.
모델 선택 전략
> /model sonnet # 기본 — 업무의 80% 처리 가능
> /model opus # 복잡한 아키텍처 설계, 깊은 분석만
opusplan 하이브리드: Plan mode는 Opus로 (설계·분석), 실행은 Sonnet으로 자동 전환.
처음엔 그냥 Opus를 기본으로 쓰고 있었다. 어차피 회사에서 쓰는 거니까 좋은 걸 쓰자는 생각이었다. 근데 공식 문서를 보니까 일반적인 개발 업무의 80%는 Sonnet으로 커버된다고 한다. Opus는 아키텍처 결정이나 복잡한 리팩토링 방향을 잡을 때처럼 "진짜 깊은 추론이 필요한 순간"에만 쓰는 게 맞다. 기본 모델을 Sonnet으로 바꾸는 것만으로도 비용이 눈에 띄게 줄어든다.
Plan Mode — 분석과 실행 분리
Shift + Tab # Plan Mode 활성화
!plan # 프롬프트 앞에 붙여도 됨
파일을 건드리지 않고 분석·계획만 수행하는 모드. 가벼운 모델을 써서 토큰 최대 53% 절약 (코드 리뷰 세션 기준 38k → 18k 토큰).
복잡한 변경 전에 반드시 Plan Mode로 먼저 계획을 세우는 게 좋다.
처음엔 Plan Mode를 귀찮은 단계 하나가 더 생기는 것으로 봤다. 그냥 바로 실행하면 되지 않나 싶었다. 근데 두 가지 이유로 생각이 바뀌었다. 하나는 비용이고, 하나는 방향 수정 비용이다. 실행 전에 계획이 잘못됐다는 걸 발견하면 되돌리기 쉬운데, 실행 중간에 발견하면 이미 여러 파일이 바뀐 상태다. Plan Mode는 그 확인 비용을 토큰도 아끼면서 해결해준다.
Extended Thinking 제한
export MAX_THINKING_TOKENS=8000 # 기본값보다 낮게 설정
Thinking 토큰은 Output 토큰으로 청구된다. 단순 작업에서는 비활성화하거나 상한을 낮춘다.
> /config # thinking 비활성화 가능
이게 꽤 맹점이었다. Thinking이 켜져 있으면 Claude가 내부적으로 추론하는 과정도 Output 토큰으로 청구된다. 근데 "파일 이름 바꿔줘"나 "이 함수 주석 달아줘" 같은 단순 작업에서도 기본적으로 thinking이 돌아간다. 복잡한 설계 작업이 아니라면 비활성화하거나 상한을 낮추는 게 낫다.
CLAUDE.md 최적화
매 세션마다 로드되는 파일이라 줄 하나하나가 토큰 비용이다:
- 200줄 이하 유지
- 세부 워크플로우는 Skills로 분리 (호출 시에만 로드)
- 코드 스니펫 넣지 않기 (빠르게 outdated)
@파일명참조로 대용량 내용은 외부화
MCP 툴 관리
연결된 MCP 서버는 설정만 해도 컨텍스트에 툴 정의가 들어간다. 쓰지 않는 MCP는 비활성화:
> /mcp # MCP 서버 관리 메뉴
CI/CD용 비용 상한 설정
자동화 파이프라인에서 비용 폭주를 방지:
# 비용 상한 (USD)
claude -p "failing tests 수정해줘" --max-budget-usd 2.00
# 턴 수 제한
claude -p "이 파일 리뷰해" --max-turns 3
# 경량 모델 사용
claude -p "lint 오류 체크" --model haiku
일일 비용 벤치마크
공식 문서 기준:
- 좋은 습관으로 사용: $5~15/day (API 기준)
- 습관 없이 사용: $20~40/day
- 평균: ~$6/day, 90% 사용자가 $12/day 이하
10. 주요 슬래시 커맨드 레퍼런스
세션 관리
커맨드설명/clear세션 초기화 (컨텍스트 전체 삭제)/compact [지침]대화 요약 압축/context카테고리별 토큰 사용량 확인/cost현재 세션 API 비용 확인/rename [이름]현재 세션 이름 지정/resume이전 세션 재시작
모델/설정
커맨드설명/model [모델명]모델 전환 (sonnet, opus, haiku)/configthinking, effort 등 설정/effort [low|medium|high]reasoning effort 수준 조정
프로젝트
커맨드설명/initCLAUDE.md 초안 자동 생성/memory적용 중인 메모리 파일 확인/hookshooks 인터랙티브 설정 UI/mcpMCP 서버 관리/doctor환경 설정 진단
롤백
Esc 두 번 # rewind 메뉴 열기
→ "Rewind code only" # 코드만 롤백, 대화 유지 (2026 추가)
→ "Rewind conversation" # 코드 + 대화 전체 롤백
11. 실전 워크플로우
일일 루틴
아침 → 새 세션 시작
/model sonnet 확인
오늘 작업 계획 한 줄 입력
작업 → 새 기능마다: /clear로 시작
파일은 @파일명으로 명시적 참조
분석·계획은 Shift+Tab (Plan Mode)
구현은 일반 모드
중간 → /cost로 비용 확인
세션 길어지면 /compact 실행
/context로 토큰 사용 확인
전환 → 완전히 다른 작업 = /clear
/rename으로 이름 붙이고 넘어가기
좋은 프롬프트 vs 나쁜 프롬프트
# 나쁜 예 — 오픈엔드"코드 더 좋게 만들어줘""버그 고쳐줘""auth 시스템 이해해줘"
# 좋은 예 — 구체적 파일 + 목표"@src/components/LoginForm.tsx 유지보수성 개선:
- 커스텀 훅으로 로직 분리
- TypeScript 타입 추가
- Jest 단위 테스트 작성"
"모바일에서 로그인 폼 미제출 버그.
@src/components/Login.jsx 확인해서 form validation 이슈 찾아줘"
"@src/auth/token.ts에서 JWT 만료 처리 로직만 확인해줘"
팀 공유 설정 전략
# git에 포함 (팀 공유)
git add CLAUDE.md
git add .claude/settings.json
git add .claude/skills/
git add .claude/agents/
git add .mcp.json
# git에서 제외 (개인)
echo "CLAUDE.local.md" >> .gitignore
echo ".claude/settings.local.json" >> .gitignore
초기 셋업 순서
Phase 1 (첫날)
└── CLAUDE.md 작성 (/init으로 초안 생성 후 정리)
└── settings.json 기본 구성
Phase 2 (1~2주 후, 필요가 확인되면)
└── 반복 작업 → Skills로 변환
└── 코드 품질 → Hooks 추가
Phase 3 (검증 후)
└── 무거운 작업 → Agents 분리
└── 외부 서비스 → MCP 추가
처음부터 모든 걸 설정하려 하지 말 것. 실제로 반복하는 작업이 생겼을 때 Skills로 만들고, 일관성 문제가 생겼을 때 Hooks를 추가하는 게 낫다.
마치며
공부하면서 가장 크게 느낀 건, Claude Code를 잘 쓰는 건 결국 Claude가 어떻게 동작하는지 이해하는 것에서 시작한다는 거다.
컨텍스트가 뭔지, 토큰이 어디서 쓰이는지를 알고 나면 지금까지 얼마나 비효율적으로 써왔는지가 보인다. 나는 그냥 좋은 AI 툴로만 쓰고 있었지, 이게 어떤 구조로 돌아가는지는 전혀 생각 안 했다. 세션이 길어질수록 답변이 이상해지는 게 모델 탓이라고 생각했는데, 실제로는 내가 컨텍스트를 오염시키고 있었던 것이다.
지금 당장 적용할 수 있는 것부터 시작하면 된다고 생각한다. 모든 걸 한꺼번에 세팅할 필요는 없다. 나는 일단 이 순서로 적용해볼 계획이다:
/clear습관화 — 작업 전환할 때마다 제일 쉽고 효과도 바로 보인다.- CLAUDE.md 정리 — 지금 파일이 얼마나 긴지 확인하고, 필요 없는 줄부터 지운다.
/context주기적으로 확인 — 어디서 토큰이 새는지 눈에 익힌다.- Plan Mode 적용 — 복잡한 변경 전에 먼저 계획 확인하는 습관.
- Skills, Hooks — 반복이 쌓이면 그때 하나씩.
아직 Subagent나 MCP까지는 손을 못 댔는데, 기본적인 컨텍스트 관리가 익숙해지면 그쪽도 공부해볼 생각이다. 팀 단위로 Hooks와 Skills를 git으로 공유하는 것도 나중에 해보고 싶다.
참고 자료
- Claude Code 공식 문서
- Context Windows — Claude API Docs
- Hooks Reference — Claude Code Docs
- Skills — Claude Code Docs
- Manage Costs — Claude Code Docs
- Claude Code Cheat Sheet 2026 — computingforgeeks.com
- Taming Claude Code: CLAUDE.md and Hooks — Medium
- Claude Code Context Buffer Management — claudefa.st
- 1M Context Window GA — claudefa.st
- Claude Code Best Practices — github.com/shanraisshan
- Awesome Claude Code — github.com/hesreallyhim
