Claude Code Skills·Hooks·Subagents 차이와 함께 쓰는 구성법

언제 지침을 불러오고, 언제 강제로 실행하고, 언제 작업을 떼어 낼지 나누는 기준

핵심 요약

  1. Skill은 필요할 때 불러오는 절차서, Hook은 항상 실행되는 규칙, Subagent는 맥락을 분리하는 작업자다.
  2. 반드시 지켜야 하는 규칙은 모델 판단에 맡기지 말고 Hook으로 강제한다.
  3. Skill은 설명만 상시 로드되므로 긴 참고 자료를 넣어도 사용 전까지 비용이 작다.
  4. Subagent는 tools와 model을 제한해 읽기 전용 리뷰나 대규모 탐색에 쓴다.

Claude Code를 팀 프로젝트에 맞추다 보면 같은 요구를 세 가지 기능 중 어디에 넣어야 할지 헷갈리는 순간이 온다. "커밋 전에 테스트를 돌려라"는 지시를 CLAUDE.md에 쓸지, Skill로 만들지, Hook으로 강제할지에 따라 동작 방식이 완전히 달라진다. 이 글은 Skills, Hooks, Subagents 공식 문서를 바탕으로 세 기능의 차이를 정리하고, 한 프로젝트 안에서 겹치지 않게 나누는 기준을 제시한다. 프로젝트 공통 지침 파일(CLAUDE.md)과 설정 파일의 역할은 Claude Code 설정과 토큰 최적화 글에서 먼저 다뤘다.

세 기능이 해결하는 문제는 서로 다르다

구분SkillsHooksSubagents
한 줄 정의필요할 때 불러오는 지침·스크립트 묶음정해진 시점에 자동 실행되는 명령별도 컨텍스트에서 일하는 전문 에이전트
누가 실행을 결정하나모델(설명 기반) 또는 사용자(/이름)Claude Code 하네스(이벤트 발생 시 항상)모델이 위임하거나 사용자가 지정
위치.claude/skills/<이름>/SKILL.mdsettings.json의 hooks.claude/agents/*.md
컨텍스트 비용설명만 상시 로드, 본문은 사용 시 로드모델 컨텍스트를 거의 쓰지 않음본 대화와 분리, 요약만 돌아옴
적합한 용도배포 절차, 리뷰 체크리스트, 문서 템플릿포맷터 실행, 위험 명령 차단, 알림대규모 탐색, 독립적인 리뷰, 병렬 작업

핵심 차이는 "누가 실행을 결정하느냐"다. Skill과 Subagent는 모델이 상황을 보고 고르는 장치이고, Hook은 모델의 판단과 상관없이 이벤트가 발생하면 반드시 실행된다. 따라서 반드시 지켜져야 하는 규칙은 Hook으로, 판단이 필요한 절차는 Skill로, 맥락을 분리해야 하는 작업은 Subagent로 보내는 것이 기본 원칙이다.

Skills: 필요할 때만 불러오는 절차서

Skill은 SKILL.md 파일 하나로 시작한다. 공식 문서에 따르면 매 턴에는 각 Skill의 설명(description)만 컨텍스트에 올라가고, 본문은 사용자가 /skill-name으로 호출하거나 모델이 설명과 대화가 맞는다고 판단할 때 로드된다. 그래서 긴 참고 자료를 Skill에 넣어도 사용하기 전까지는 비용이 거의 들지 않는다.

---
name: release-notes
description: 지난 태그 이후 커밋으로 릴리스 노트를 작성한다. 릴리스 노트, 변경 이력 요청에 사용.
disable-model-invocation: true
allowed-tools: Bash(git log *) Bash(git tag *)
---

## 최근 변경
!`git log --oneline $(git describe --tags --abbrev=0)..HEAD`

## 작성 규칙
- 기능 추가 / 버그 수정 / 내부 변경으로 분류한다.
- 사용자에게 보이는 변경만 앞에 둔다.

disable-model-invocation: true를 두면 모델이 스스로 호출하지 않고 사용자가 직접 부를 때만 실행된다. 배포처럼 부작용이 있는 절차에 쓰는 설정이다. 반대로 user-invocable: false는 메뉴에서 숨기고 모델만 쓰게 한다. 본문 안의 !`명령` 문법은 Skill 내용이 모델에 전달되기 전에 명령을 실행해 결과를 끼워 넣는다.

Hooks: 모델 판단과 무관하게 항상 실행되는 규칙

Hook은 PreToolUse, PostToolUse, UserPromptSubmit, Stop, SessionStart 같은 이벤트에 명령을 연결한다. 설정은 .claude/settings.json(팀 공유) 또는 .claude/settings.local.json(개인)에 둔다. 다음은 파일을 수정한 직후 포맷터를 실행하는 예다.

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          { "type": "command", "command": "npx prettier --write \"$CLAUDE_PROJECT_DIR\"/src", "timeout": 30 }
        ]
      }
    ]
  }
}

Hook 명령은 표준 입력으로 tool_name, tool_input 같은 JSON을 받는다. 종료 코드 0은 성공, 2는 차단을 뜻한다. 예를 들어 PreToolUse에서 2로 끝나면 해당 도구 호출이 막히고, Stop에서 2로 끝나면 응답 종료가 보류된다. 다른 종료 코드는 오류로 기록되지만 작업은 계속된다. "테스트를 꼭 돌려라" 같은 문장을 CLAUDE.md에 적으면 모델이 놓칠 수 있지만, Hook으로 걸어 두면 실행 자체가 보장된다.

Subagents: 맥락을 떼어 내 결과만 돌려받는 작업자

Subagent는 자체 시스템 프롬프트와 도구 권한을 가진 에이전트로, 본 대화와 분리된 컨텍스트 창에서 일하고 요약만 돌려준다. .claude/agents/에 마크다운 파일로 정의하며 name과 description이 필수다. 기본 제공되는 Explore(읽기 전용 탐색), Plan(계획 모드 조사), general-purpose가 있고, tools로 허용 도구를, model로 사용할 모델을 지정할 수 있다.

---
name: security-reviewer
description: 인증·권한·입력 검증 관련 변경을 읽기 전용으로 검토한다. PR 리뷰 전에 사용.
tools: Read, Grep, Glob
model: sonnet
---

변경된 파일에서 인증 누락, 권한 확인 누락, 검증 없는 입력 사용을 찾아
파일 경로와 줄 번호, 위험도를 표로 보고한다. 파일은 수정하지 않는다.

세 기능을 한 프로젝트에서 조합하는 예

세 기능은 서로 대체재가 아니라 층이 다르다. Skill과 Subagent의 frontmatter 안에도 hooks를 넣을 수 있고, Skill은 context: fork와 agent로 Subagent 안에서 실행되게 할 수도 있다. 웹 서비스 저장소라면 다음처럼 나눌 수 있다.

  1. Hook: PostToolUse에서 포맷터, PreToolUse에서 rm -rf나 운영 DB 접속 명령 차단.
  2. Skill: /deploy-check(배포 전 점검 절차), /write-migration(마이그레이션 작성 규칙과 템플릿).
  3. Subagent: 읽기 전용 security-reviewer, 테스트 실패 원인을 좁히는 test-investigator.
  4. CLAUDE.md: 위 장치를 언제 쓰는지 한두 줄로만 안내하고 상세 절차는 Skill로 넘긴다.

권한 승인과 자동 실행 범위를 정할 때는 Claude Code Auto Mode 보안 글의 권한 설계와 함께 맞춰 두면 Hook 차단 규칙과 승인 규칙이 서로 어긋나지 않는다.

구성이 의도대로 동작하는지 점검하는 순서

  • Skill: 설명에 맞는 요청을 보냈을 때 자동으로 로드되는지, 원치 않는 요청에서 불필요하게 로드되지 않는지 확인한다.
  • Hook: 일부러 차단 대상 명령을 요청해 종료 코드 2로 막히는지 확인한다. 스크립트가 0이 아닌 다른 코드로 끝나면 차단되지 않고 오류만 기록된다.
  • Subagent: 위임 결과가 요약 형태로 돌아오는지, tools 제한 때문에 필요한 작업이 실패하지 않는지 본다.
  • 설명 문장 길이: Subagent 설명을 모두 합쳐 15,000토큰을 넘으면 시작 시 경고가 뜬다고 문서에 적혀 있으므로 짧게 유지한다.

초보자가 자주 실수하는 포인트

  • 반드시 실행돼야 하는 검증을 CLAUDE.md 문장으로만 남겨 두는 경우
  • 부작용이 있는 배포 Skill에 disable-model-invocation을 설정하지 않는 경우
  • Hook 스크립트가 차단 시 종료 코드 2가 아닌 1로 끝나 실제로는 막지 못하는 경우
  • Subagent에 모든 도구를 열어 두어 리뷰 에이전트가 파일을 수정하는 경우

체크리스트

  • 항상 지켜야 할 규칙이 Hook으로 걸려 있는가
  • 부작용이 있는 Skill은 사용자만 호출하도록 설정했는가
  • Hook 차단 로직이 종료 코드 2를 반환하는가
  • Subagent마다 필요한 최소 도구만 허용했는가
  • CLAUDE.md에는 장치 안내만 남기고 긴 절차는 Skill로 옮겼는가

자주 묻는 질문

Skill과 슬래시 명령은 같은 것인가요?

공식 문서상 Skill은 /skill-name으로 직접 호출할 수 있고, 설명이 대화와 맞으면 모델이 스스로 불러오기도 한다. 사용자 호출만 허용하려면 disable-model-invocation: true를 둔다.

Hook에서 모델에게 피드백을 줄 수 있나요?

종료 코드 0으로 끝나며 JSON의 hookSpecificOutput.additionalContext에 내용을 넣으면 모델에 맥락으로 전달된다. 차단이 목적이면 종료 코드 2와 표준 오류 메시지를 쓴다.

Subagent가 또 다른 Subagent를 부를 수 있나요?

기본값으로 본 대화 아래 3단계까지 가능하며, CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH 환경 변수로 깊이를 줄이거나 1로 두어 중첩을 막을 수 있다.

참고 자료 · 검증 기준

위 자료와 내용을 대조한 날짜: . 도구·서비스 정책은 이후 바뀔 수 있으므로 적용 전 공식 문서를 다시 확인하세요.

이 글은 위 참고 자료를 바탕으로 정리했으며, 내용은 운영 과정에서 순차적으로 보완될 수 있습니다.