- 출처: Anthropic 블로그 Steering Claude Code: skills, hooks, rules, subagents, and more.
- Claude의 행동을 제어하는 방법은 7가지이고, 각각 로드 시점 · 컴팩션 동작 · 컨텍스트 비용 · 권한 수준이 다르다.
- 핵심 결정은 “무엇을 시킬까"가 아니라 “그 지시를 어디에 넣을까"다. 같은 규칙도 넣는 위치에 따라 비용과 강제력이 달라진다.
- 큰 원칙 하나: 모든 라인은 토큰 비용이다. 항상 로드되는 곳(CLAUDE.md, output style)에는 최소한만 두고, 나머지는 필요할 때만 로드되는 곳으로 밀어낸다.
- 또 하나: “선택적으로 따라도 되는 규칙"은 규칙이 아니다. 반드시 일어나야 하는 일은 모델의 판단(prompt)이 아니라 harness의 결정적 실행(hook)에 맡긴다.
7가지 방법 비교#
| 방법 | 로드 시점 | 컴팩션 동작 | 컨텍스트 비용 | 주 용도 |
|---|
| CLAUDE.md (루트) | 세션 시작 | 재읽음 | 높음 | 빌드 명령어, 팀 코딩 규칙 |
| CLAUDE.md (서브디렉토리) | 해당 폴더 접근 시 | 손실됨 | 낮음 | 디렉토리별 컨벤션 |
| Rules | 세션 시작 또는 경로별 | 재삽입됨 | 중간 | 파일 특정 제약, 교차 관심사 |
| Skills | 이름·설명만 시작 시 | 예산 내 재삽입 | 낮음 | 절차·체크리스트 |
| Subagents | 이름·설명만 시작 시 | 최종 메시지만 반환 | 매우 낮음 | 격리된 병렬 작업 |
| Hooks | 라이프사이클 이벤트 | 컴팩션 무관 | 매우 낮음 | 결정적 자동화 |
| Output styles | 세션 시작 | 절대 컴팩션 안 됨 | 높음 | 주 역할 변경 |
CLAUDE.md#
- 프로젝트의 뼈대(빌드 명령어, 디렉토리 구조, 모노레포 레이아웃, 팀 규범)를 Claude에 설명하는 파일.
- 루트 CLAUDE.md는 세션 시작 시 로드되고 컴팩션 후 다시 읽힌다. 서브디렉토리 CLAUDE.md는 그 폴더의 파일에 접근할 때만 로드된다.
- 200줄 이하로 유지한다. 모든 엔지니어가 매 세션 전체를 로드하므로, 길어질수록 모두의 컨텍스트를 낭비한다.
- 팀별·경로별 컨벤션은 경로 범위 rules로, 절차는 skills로 밀어낸다.
Rules#
.claude/rules/의 마크다운 파일로 특정 제약과 컨벤션을 정의한다. CLAUDE.md보다 작고 집중적이다.- 프론트매터의
paths:로 범위를 지정하면 관련 파일을 만질 때만 로드된다. 범위 없는 rule은 CLAUDE.md처럼 항상 로드되어 낭비가 된다.
---
paths:
- "src/api/**"
- "**/*.handler.ts"
---
모든 API 핸들러는 처리 전에 Zod로 입력을 검증한다.
- 적합한 경우: “마이그레이션은 append-only” 같은 파일 특정 제약, 여러 곳에 흩어진 파일에 걸리는 교차 관심사.
Skills#
.claude/skills/의 폴더 구조로 재사용 가능한 절차를 정의한다. SKILL.md에 이름·설명·본문이 들어간다.- 세션 시작 시엔 이름과 설명만 로드된다. 슬래시 명령어(
/code-review)나 자동 매칭으로 호출될 때 전체 본문이 로드된다.- 컴팩션 시에는 호출됐던 skill만 예산 범위 안에서 재삽입되고, 가장 오래된 것부터 제거된다.
- 배포 워크플로우, 릴리스 체크리스트, 코드 리뷰처럼 매번 같은 구조를 보장해야 하는 절차에 쓴다. 30줄짜리 절차를 CLAUDE.md에 넣는 대신 skill로 뺀다.
Subagents#
.claude/agents/의 마크다운 파일로 격리된 전문 어시스턴트를 정의한다. 프론트매터에 이름·설명·모델·도구 접근, 본문에 그 에이전트의 시스템 프롬프트를 쓴다.- Skill과 마찬가지로 이름·설명만 시작 시 로드된다. 결정적 차이는 본문이 부모 대화에 들어오지 않는다는 점이다.
- Agent 도구로 호출하면 독립된 컨텍스트 윈도우에서 실행되고, 부모에는 최종 메시지(요약+메타데이터)만 반환한다.
- 깊은 검색, 로그 분석, 의존성 감사처럼 주 대화를 어지럽히지 않아야 할 병렬 작업에 쓴다. 5단계까지 중첩할 수 있고, 수십~수백 개를 백그라운드로 조율할 수도 있다.
Hooks#
settings.json에 등록하는 라이프사이클 이벤트 기반 트리거다. 파일 편집, 도구 호출, 세션 시작 등 정의된 지점(PreCompact, PreToolUse, PostEdit 등)에서 실행된다.- 타입에 따라 결정적이거나 모델 판단을 쓴다.
- 결정적:
command(CLI 실행), http(HTTP 요청), mcp_tool(MCP 도구 실행). - 판단 사용:
prompt, agent.
- 편집 후 린터 자동 실행, 완료 시 Slack 알림, PreCompact에서 채팅 백업, PreToolUse에서 exit code 2로 명령어 차단 등에 쓴다.
- 핵심은 결정적 자동화다. “항상 일어나야 하는 일"은 모델이 아니라 harness가 실행하므로, 모델의 변덕에 좌우되지 않는다.
Output styles#
.claude/output-styles/의 파일로 시스템 프롬프트에 주입된다. 매 세션 시작 시 로드되고 절대 컴팩션되지 않으며 시스템 프롬프트 수준의 높은 가중치를 가진다.- 주의: 커스텀 스타일은 기본값을 완전히 덮어쓴다. 소프트웨어 엔지니어링 지원 지시, 보안 우려 처리, 테스트 검증 습관이 통째로 사라진다.
- 프론트매터에
keep-coding-instructions: true를 주면 기본 코딩 지시를 유지한다.
- 커스텀을 만들기 전에 내장 스타일부터 확인한다: Proactive(높은 자율성), Explanatory(교육 모드), Learning(협업 코딩).
System prompt 추가 (append-system-prompt)#
- CLI 플래그로 호출 시에만 붙이는 지시다. 파일이 아니라 매개변수라 세션 간 지속되지 않는다.
- Output style과 달리 덧셈형이라 기본 역할을 지우지 않는다. 그래서 더 안전하고, 프롬프트 캐싱도 받는다.
- 다만 입력 토큰이 늘어 컨텍스트 비용이 높고, 지시가 많아질수록 준수도가 떨어지는 수렴점이 있다. 코딩 표준·형식 지시·도메인 지식을 임시로 얹을 때 쓴다.
안티패턴과 해결책#
- 규칙을 CLAUDE.md에 몰아넣는 것이 가장 흔한 실수다. 위치를 옮기면 대부분 해결된다.
| 안티패턴 | 왜 문제인가 | 해결 |
|---|
| “매번 X 해라"를 CLAUDE.md에 | 모델이 선택적으로 따를 수 있음 | Hooks로 강제 |
| “절대 X 하지 마라"를 CLAUDE.md에 | 긴 세션·모호함·prompt injection에 무너짐 | PreToolUse hook(exit 2) 또는 managed settings |
| 30줄 절차를 CLAUDE.md에 | 불필요하게 항상 로드됨 | Skill로 분리 |
| 경로 범위 없는 rule | 무관한 작업에도 로드됨 | paths: 프론트매터로 범위 지정 |
| 개인 선호를 프로젝트 CLAUDE.md에 | 팀 전체가 로드함 | 로컬 설정 파일로 분리 |
선택 기준 한 줄 요약#
- 항상 일어나야 하나? → Hooks
- 절차·체크리스트인가? → Skills
- 격리된 병렬 작업인가? → Subagents
- 특정 디렉토리·파일 한정인가? → 경로 범위 Rules 또는 서브디렉토리 CLAUDE.md
- 주 역할을 바꾸나? → Output style
- 톤·길이·형식만 얹나? → append-system-prompt
- 그 외 프로젝트 뼈대 → 루트 CLAUDE.md (200줄 이하)
- Plugins는 skills·subagents·hooks·output styles를 묶어 팀에 배포하는 번들이다.
- Managed settings는 관리자가 배포하고 사용자가 재정의할 수 없어, 조직 차원의 강제가 필요한 규칙에 쓴다.
- 관련 노트:
Claude Code 루프 시작하기, Claude Code 모델과 Effort Level.