• 출처: 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.