본문으로 바로가기

Claude Code 훅: 워크플로 자동화를 위한 실전 가이드

훅 기반 자동화가 어떻게 작동하는지 배우고, Claude Code 훅으로 테스트, 포매팅, 알림 같은 코딩 작업을 자동화하는 방법을 시작해 보세요.
업데이트됨 2026년 7월 22일  · 15분 읽다

AI로 탐색하기

ChatGPT에서 열기Claude에서 열기Perplexity에서 열기

Claude Code로 작업하다 보면 공통적인 문제가 보입니다. 코드는 잘 쓰지만 포매팅, 테스트 실행, 보안 프로토콜 준수 같은 중요한 단계를 잊곤 합니다. 결국 같은 주의를 계속 반복해서 상기시켜야 하죠. Claude Code 훅을 사용하면 워크플로의 특정 지점에서 셸 명령을 자동으로 실행해 이러한 상기를 자동화할 수 있습니다.

이 튜토리얼에서는 코드 포매팅, 테스트 실행, 알림, 파일 보호를 위한 훅 설정 방법을 다룹니다. 수동 개입 없이 개발 표준을 강제하는 자동화 시스템을 구축하게 됩니다.

Claude Code에 대해 더 알아보려면 Claude Code 모범 사례 가이드와 Claude Skills 튜토리얼을 확인하세요. 프로젝트 수준의 지침을 구성하는 방법이 궁금하다면 CLAUDE.md 작성 가이드를 참조하세요.

요약

  • Claude Code 훅은 Claude Code의 수명 주기 특정 지점(도구 호출 전/후, 세션 시작 시, Claude가 중지될 때)에 자동으로 실행되는 셸 명령입니다.

  • 프로젝트는 .claude/settings.json, 전역은 ~/.claude/settings.json에 이벤트, 매처, 명령을 JSON으로 구성합니다.

  • PreToolUse 훅으로 위험한 작업을 사전에 차단하세요(종료 코드 2 = 차단).

  • PostToolUse 훅은 Claude가 코드를 쓴 뒤 포매팅, 린팅, 테스트 실행 같은 정리 작업에 사용하세요.

  • 훅은 stdin으로 JSON 컨텍스트를 받고, 종료 코드, stdout, stderr로 결과를 전달합니다.

Claude Code 훅이란 무엇인가요?

Claude Code 훅은 AI 코딩 세션 중 특정 이벤트가 발생할 때 자동으로 실행되는 셸 명령입니다. Claude가 파일을 쓰기 전, 명령을 실행한 후, 알림을 보낼 때 등 정확한 타이밍에 사용자 스크립트를 실행하는 자동 트리거라고 생각하면 됩니다.

이 시스템은 Claude Code의 동작을 감시하고, 구성 파일에 정의한 규칙과 일치하는지 확인해 작동합니다. 일치하면 지정한 명령이 방금 발생한 일에 대한 컨텍스트에 접근해 실행됩니다. 이를 통해 Claude의 동작을 제어하고, 원래라면 수동 개입이 필요한 반복 작업을 자동화할 수 있습니다.

다음은 Claude가 Python 파일을 작성할 때마다 코드 포매터를 실행하는 기본 훅입니다.

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "python -m black ."
          }
        ]
      }
    ]
  }
}

이 훅은 세 부분으로 구성됩니다. 

  • 이벤트: PostToolUse(Claude가 작업을 마친 후)

  • 매처: Write(파일 작성 시에만)

  • 명령: python -m black .(현재 디렉터리의 Python 파일 포매팅)

훅은 스크립트 입력으로 전송되는 JSON 데이터를 통해 Claude가 방금 수행한 작업에 대한 상세 정보를 받습니다. 이를 활용해 특정 파일 변경에 반응하는 정교한 자동화를 구축할 수 있습니다.

Claude Code 자동화를 더 확장하고 싶다면, 클라우드에서 훅과 에이전트를 정기적으로 실행하도록 예약하는 방법을 다룬 Claude Code Routines 튜토리얼을 참고하세요.

이제 처음부터 훅을 만들고 Claude Code에 등록하는 방법을 살펴보겠습니다.

사전 준비 사항

시작하기 전에 다음이 필요합니다.

  • Claude Code 설치 및 실행: Claude Code를 기본 코딩 작업에 편안하게 사용할 수 있어야 합니다.

  • 명령줄 숙련도: 훅은 셸 명령을 실행하므로 운영체제에 맞는 기본 터미널 명령을 작성할 줄 알아야 합니다.

  • 텍스트 편집기: 훅 설정을 위해 JSON 구성 파일을 편집합니다.

  • 프로젝트 디렉터리: 중요한 작업에 영향을 주지 않고 훅을 안전하게 테스트할 수 있는 코딩 프로젝트

셸 스크립팅 전문가일 필요는 없지만 ls, cd 같은 명령과 기본 파일 작업을 이해하면 예제를 따라가기 쉽습니다. bash 스크립팅이나 터미널이 처음이라면 Introduction to Shell 과정을 추천합니다.

Claude Code 훅 시작하기

훅이 무엇인지 이해했으니 첫 자동화를 설정해 보겠습니다. 필요한 이벤트를 고르고, 간단한 규칙을 구성한 뒤, 기본 명령으로 테스트하는 순서입니다.

훅 이벤트 이해하기

Claude Code는 25개가 넘는 훅 이벤트를 제공합니다. 아래 표는 가장 자주 사용하는 10가지를 다룹니다. 전체 목록은 공식 훅 참고문서를 확인하세요.

PreToolUsePostToolUse가 가장 일반적입니다. PreToolUse는 Claude가 파일을 쓰거나 명령을 실행하는 등의 작업을 수행하기 전 실행되어, 검증이나 위험 작업 차단에 적합합니다. PostToolUse는 작업 완료 후 실행되어 코드 포매팅이나 테스트 실행 같은 정리 작업에 유용합니다.

UserPromptSubmit은 프롬프트를 제출했을 때, 처리 전 트리거됩니다. 이를 사용해 대화에 컨텍스트를 추가하거나 프롬프트가 특정 요건을 충족하는지 검증할 수 있습니다.

Notification은 Claude가 명령 실행 권한 요청이나 입력 필요 등 알림을 보낼 때 실행됩니다. PermissionRequest는 Claude Code가 권한 대화상자를 표시할 때 트리거되어 사용자를 대신해 요청을 자동으로 승인 또는 거부할 수 있게 합니다.

StopSubagentStop은 Claude의 응답이 끝날 때 트리거되어 최종 점검이나 보고서 생성에 유용합니다. 둘의 차이는 Stop은 Claude의 전체 응답이 끝날 때, SubagentStop은 도구가 생성한 보조자(“서브에이전트”)의 작업이 끝날 때 발생한다는 점입니다.

나머지 이벤트인 PreCompact, SessionStart, SessionEnd는 수명 주기별 상황을 처리합니다. PreCompact는 Claude가 대화 내역을 단축하기 직전에 실행됩니다. ‘SessionStart’는 새 세션 시작 시 기본값을 설정하고, SessionEnd는 세션 종료 시 트리거되어 정리 또는 최종 보고에 유용합니다.

이벤트 이름

트리거 시점

주요 사용 사례

PreToolUse

Claude가 작업을 수행하기 전(예: 파일 작성, 명령 실행).

작업 검증 또는 위험한 작업 차단.

PostToolUse

Claude가 작업을 완료한 후.

정리 작업, 코드 포매팅, 테스트 실행.

UserPromptSubmit

프롬프트 제출 시, 처리 시작 전.

대화 컨텍스트 추가 또는 프롬프트 요건 검증.

Notification

Claude가 알림을 보낼 때(예: 입력 또는 권한 요청).

시스템 알림 및 사용자 주의 요청 처리.

PermissionRequest

권한 대화상자가 표시될 때.

사용자를 대신해 요청 자동 승인/거부.

Stop

Claude의 전체 응답이 끝날 때.

메인 응답에 대한 최종 점검 또는 보고 생성.

SubagentStop

도구가 생성한 보조자("subagent")의 작업이 끝날 때.

서브에이전트 활동에 대한 최종 점검.

PreCompact

대화 내역을 단축하기 직전.

대화 정리 및 컨텍스트 보존 관리.

SessionStart

새 세션 시작 시.

초기화 및 기본값 설정.

SessionEnd

세션 종료 시.

최종 정리 또는 세션 종료 보고.

매처 이해하기

매처는 어떤 Claude Code 동작이 훅을 트리거할지 결정하는 필터입니다. 기술적으로는 정규식으로 해석되는 문자열이므로, 정확 일치나 유연한 패턴을 사용할 수 있습니다. 

가장 유용한 매처는 Write(파일 작성 시 트리거), Edit(콘텐츠 편집 시 트리거) 같은 단순한 것과, 둘을 함께 다루는 Edit|Write 같은 조합입니다. 

또한 Notebook.* 같은 접두사 패턴으로 “Notebook.”으로 시작하는 모든 도구를 매칭할 수 있습니다. 모든 동작에서 훅을 발화시키려면 범용 정규식 .*나 빈 문자열(""), 또는 matcher를 비워두면 됩니다.

매처는 대소문자를 구분하며 동작 이름에만 적용되므로 가능하면 구체적으로 유지하는 것이 좋습니다. 더 세밀한 제어(예: 특정 파일 유형으로 제한)가 필요하다면 Claude가 훅에 전달하는 JSON 페이로드를 읽어 자체 정규식이나 조건을 적용하세요.

Claude Code에서 첫 훅 만들기

Claude Code에서는 대화형 /hooks 명령을 사용하거나 구성 파일을 직접 편집해 훅을 설정할 수 있습니다. 초보자에게 더 친숙한 대화형 방식부터 시작하겠습니다.

/hooks 명령 사용:

  1. Claude Code를 열고 채팅 인터페이스에 /hooks를 입력하세요.

  2. 트리거 이벤트를 선택하세요(예제에서는 PostToolUse 선택).

  3. 메뉴에서 "Add new hook"을 선택합니다.

  4. 매처 패턴을 설정하세요(Write를 입력해 파일 작성을 대상으로 지정).

  5. 명령을 입력합니다:

    • Mac: say "Task complete"

    • Windows: powershell -c [console]::beep()

    • Linux: spd-say "Task complete"

  6. Esc를 세 번 눌러 구성을 저장하고 Claude Code로 돌아갑니다.

/hooks 명령은 설정 파일을 자동으로 업데이트하고 구성을 다시 불러옵니다. 기존 훅을 확인하거나 변경하려면 언제든지 /hooks를 사용할 수 있습니다.

구성 파일을 직접 편집하길 원한다면, 전역 설정은 ~/.claude/settings.json, 프로젝트 디렉터리의 팀 공유 훅은 .claude/settings.json(리포지토리에 커밋), 개인 훅은 기본적으로 gitignore되는 .claude/settings.local.json에 위치합니다. 위 예제는 다음과 같습니다.

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "say 'Task complete'"
          }
        ]
      }
    ]
  }
}

파일을 수동으로 편집한 후 Claude Code를 다시 시작하거나 /hooks 명령으로 구성을 리로드하세요. 이제 Claude가 파일을 쓸 때마다 오디오 알림을 들을 수 있습니다.

훅 테스트하기

다음 단계로 넘어가기 전에 훅이 실제로 동작하는지 확인하세요.

  1. Claude에게 아무 Python 파일이나 쓰도록 요청하세요(예: "hello.py 파일을 만들어 hello world를 출력해 주세요").

  2. Claude가 쓰기 작업을 완료하면 오디오 알림이 재생되어야 합니다.

  3. 아무 소리도 나지 않으면 Ctrl-O를 눌러 Claude Code의 대화 내역에서 오류 메시지를 확인하세요.

  4. 일반적인 문제는 훅 명령을 찾지 못함, 잘못된 파일 권한, 구성 파일의 구문 오류 등입니다.

이 기본 테스트를 통과하면 이후 더 복잡한 훅을 만들 때 디버깅 시간을 절약할 수 있습니다. 설정 파일을 방금 수동으로 수정했거나 매처/이벤트를 변경했거나, 훅 명령에서 사용하려는 새 도구를 설치했다면, 구성을 다시 불러오기 위해 /hooks를 다시 열거나 Claude를 재시작하는 것이 도움이 됩니다.

이 기본 패턴(이벤트, 매처, 명령)이 모든 훅 자동화의 기반입니다. 동일한 이벤트가 트리거될 때 동시에 여러 명령을 실행하도록 확장할 수 있습니다. 예를 들어, Claude가 파일을 쓸 때 사운드를 재생하고 백업을 생성하도록 할 수 있습니다. 

또한 같은 이벤트 내에서 도구별로 별도의 매처를 만들어, 파일 작성은 코드 편집과 다른 작업을 트리거하도록 구성할 수 있습니다. 동일한 도구 패턴과 일치하는 모든 훅은 병렬로 실행됩니다. 같은 이벤트에 여러 매처를 구성하면 각 훅은 자신의 매처가 트리거될 때 실행됩니다.

훅 입력 다루기

Claude Code가 훅을 트리거하면, 표준 입력(stdin)을 통해 방금 일어난 일에 대한 정보를 전송합니다. 이는 명령 실행 시 직접 전달되는 데이터 스트림입니다. 이 데이터 덕분에 훅은 임의 시점에 실행되는 스크립트가 아니라, 강력한 자동화 도구가 됩니다. 

Claude Code는 이 정보를 JSON으로 포장해 구성한 어떤 명령이든(단순 터미널 명령이든 사용자 스크립트든) 전달합니다.

훅 입력의 구조

모든 훅은 현재 세션에 대한 기본 필드를 담은 JSON 객체를 받습니다.

{
  "session_id": "abc123",
  "transcript_path": "/Users/you/.claude/projects/my-project/conversation.jsonl", 
  "cwd": "/Users/you/my-project",
  "hook_event_name": "PostToolUse"
}

각 구성 요소를 해석해 봅시다.

  • session_id: 현재 대화를 식별합니다.

  • transcript_path: 대화 기록의 경로입니다.

  • cwd: 작업 디렉터리입니다.

  • hook_event_name: 어떤 이벤트가 발생했는지 알려줍니다.

이 컨텍스트를 통해 훅이 똑똑한 결정을 내릴 수 있습니다. 어떤 대화가 작업을 트리거했는지 추적하고, 필요 시 전체 채팅 기록에 접근하거나, 올바른 디렉터리에서 명령을 실행할 수 있습니다.

이벤트별 입력 차이

PreToolUsePostToolUse 같은 도구 이벤트에는 작업에 대한 추가 세부정보가 포함됩니다. 여기가 자동화에 정말 유용한 부분입니다. PreToolUse에서는 tool_input이 제공되고, PostToolUse에서는 여기에 더해 tool_response가 포함됩니다.

{
  "session_id": "abc123",
  "hook_event_name": "PostToolUse",
  "tool_name": "Write",
  "tool_input": {
    "file_path": "/path/to/file.py",
    "content": "print('Hello world')"
  },
  "tool_response": {
    "filePath": "/path/to/file.py", 
    "success": true
  }
}

훅 입력에서 file_path는 쓰거나 편집 중인 파일의 경로를, content는 도구가 쓰려는 정확한 텍스트를 나타냅니다. 실행 후 도구의 응답은 실제로 영향을 준 파일의 최종 filePath(camelCase임)를 반영하고, 작업이 올바르게 완료되었는지 나타내는 success 플래그를 제공합니다. 

이 상세 정보 덕분에 훅은 실제 상황에 따라 다르게 반응할 수 있습니다. Python 파일만 포매팅하거나, 중요한 디렉터리만 백업하거나, 특정 파일 유형이 변경될 때만 알림을 보낼 수 있습니다.

UserPromptSubmit 같은 이벤트는 도구가 관여하지 않으므로 더 단순합니다.

{
  "session_id": "abc123",
  "hook_event_name": "UserPromptSubmit", 
  "prompt": "Write a function to calculate factorial"
}

UserPromptSubmit 훅은 구성에서 매처를 사용하지 않는다는 점에 유의하세요. 도구 작업이 아니라 모든 프롬프트에 대해 트리거됩니다. 따라서 대화 로깅, 프로젝트 컨텍스트 자동 추가, Claude가 처리하기 전 프롬프트 검증 등에 적합합니다.

실전에서 훅 입력 읽기

모든 사용자 프롬프트를 기록하는 훅을 만들어 보겠습니다. 긴 코딩 세션에서 Claude에게 무엇을 요청했는지 잊어버리는 문제를 해결합니다. 먼저 훅 구성입니다.

{
  "hooks": {
    "UserPromptSubmit": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "python3 ~/.claude/log_prompts.py"
          }
        ]
      }
    ]
  }
}

다음으로 ~/.claude/log_prompts.py 파일을 생성하고 아래 내용을 넣습니다.

#!/usr/bin/env python3
import json
import sys
from datetime import datetime

# Read JSON data from stdin
input_data = json.load(sys.stdin)

# Extract information
session_id = input_data.get("session_id", "unknown")
prompt = input_data.get("prompt", "")
timestamp = datetime.now().isoformat()

# Log the prompt
log_entry = f"{timestamp} | Session: {session_id[:8]} | {prompt}\n"
with open("prompt_history.txt", "a") as f:
    f.write(log_entry)

이 스크립트는 Claude Code가 전송하는 JSON 데이터를 읽어 세션 컨텍스트와 함께 프롬프트를 기록합니다. 이렇게 쌓인 검색 가능한 기록은 몇 주 뒤 문제를 어떻게 해결했는지 되돌아봐야 할 때 큰 도움이 됩니다.

훅 출력 다루기

훅 명령이 실행된 후에는 무슨 일이 일어났고 정상 진행해도 되는지 Claude Code에 알려야 합니다. 이 제어 메커니즘 덕분에 훅은 단순 로깅 도구를 넘어 Claude의 동작을 안내하는 강력한 워크플로 자동화가 됩니다. 이는 표준 출력(stdout), 표준 오류(stderr), 종료 코드 세 가지 채널을 통해 이뤄집니다.

출력 채널과 종료 코드

표준 출력(stdout)은 정상 출력을 의미합니다. 예를 들어 무언가를 출력하면 stdout으로 갑니다. 대부분의 훅에서는 Ctrl-O를 눌렀을 때 Claude Code의 대화 내역에 표시되어, 자동화가 수행한 작업의 기록을 남기면서 메인 대화를 어지럽히지 않습니다.

표준 오류(stderr)는 오류 메시지를 의미합니다. 다음 방식으로 stderr에 쓸 수 있습니다. 

  • Python: print("message", file=sys.stderr) 또는

  • 커맨드라인: echo "message" >&2

핵심 차이는 stderr를 Claude에게 직접 보내 자동 처리하게 할 수 있어, 훅이 감지한 문제에 Claude가 대응할 수 있다는 점입니다.

종료 코드는 다음 단계를 Claude Code에 지시합니다.

  • 종료 코드 0: 성공(stdout을 사용자에게 표시)

  • 종료 코드 2: 차단 오류(stderr를 Claude에게 전송)

  • 기타 코드: 비차단 오류(stderr를 사용자에게 표시하되 계속 진행)

이 시스템을 통해 Claude가 언제 중단, 계속, 피드백 수신을 해야 할지 세밀하게 제어할 수 있습니다. 가장 중요한 두 종료 코드의 예시를 살펴보겠습니다.

종료 코드 0: 정상 동작

대부분의 훅은 모든 것이 잘 됐음을 나타내기 위해 종료 코드 0을 사용합니다. 다음은 파일 작업을 로깅하고 사용자에게 알리는 완전한 훅입니다.

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "python3 -c \"import datetime; open('activity.log','a').write('File written: ' + datetime.datetime.now().isoformat() + '\\n'); print('Logged file operation')\""
          }
        ]
      }
    ]
  }
}

이 훅은 파일에 로그를 남기고, 그다음 메시지를 대화 내역에 출력하는 두 가지 작업을 수행합니다. 방식은 다양하지만, 이 방법은 크로스 플랫폼이며 커맨드라인 세부 구현에 덜 의존합니다.

명시적인 종료 코드가 없으므로 기본값 0이 적용됩니다. 출력된 메시지는 Claude Code의 대화 내역에 표시되어 로깅이 제대로 수행되었음을 알려줍니다. 이 패턴은 감사를 위한 로그를 만들거나, 시간이 지나며 Claude가 프로젝트에 가한 변경 사항을 추적하는 데 적합합니다.

종료 코드 2: 피드백과 함께 차단

종료 코드 2는 오류 메시지를 Claude에 직접 보내 자동으로 대응하게 합니다. 여기서부터 훅은 단순 자동화를 넘어 안전장치가 됩니다. 다음은 위험한 파일 작업을 차단하는 훅입니다.

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "python3 ~/.claude/security_check.py"
          }
        ]
      }
    ]
  }
}

보안 검사 스크립트를 ~/.claude/security_check.py 위치에 생성해야 합니다.

#!/usr/bin/env python3
import json
import sys

# Read hook input
input_data = json.load(sys.stdin)
tool_input = input_data.get("tool_input", {})
file_path = tool_input.get("file_path", "")

# Check for dangerous patterns
dangerous_paths = ["/etc/", "/usr/", "production.conf"]
is_dangerous = any(pattern in file_path for pattern in dangerous_paths)

if is_dangerous:
    # Block the operation and tell Claude why
    print(f"Blocked modification of {file_path} - this appears to be a system or production file", file=sys.stderr)
    sys.exit(2)  # Sends stderr message to Claude
else:
    # Allow the operation
    print(f"Approved modification of {file_path}")
    sys.exit(0)  # Shows stdout in transcript

이 훅이 위험한 경로를 감지하면 종료 코드 2와 함께 종료합니다. Claude Code는 stderr 메시지를 Claude에게 보내고, Claude는 왜 작업이 차단되었는지 설명하고 대안을 제시할 수 있습니다. 이를 통해 시스템 파일에 대한 우발적 손상을 방지하면서 Claude에게 보안 정책을 알릴 수 있습니다.

Claude Code를 위한 스마트 알림 훅 만들기

입력 처리와 스마트한 출력 처리를 결합한 개선된 알림 훅을 만들어 봅시다. 초기 훅이 모든 파일 변경에서 경고를 울리던 소음 문제를 해결합니다.

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "python3 ~/.claude/smart_notify.py"
          }
        ]
      }
    ]
  }
}

알림 스크립트를 ~/.claude/smart_notify.py 위치에 생성합니다.

#!/usr/bin/env python3
import json
import sys
import os
import subprocess

# Read the hook input
input_data = json.load(sys.stdin)
tool_input = input_data.get("tool_input", {})
file_path = tool_input.get("file_path", "")

# Categorize file importance
important_extensions = [".py", ".js", ".ts", ".java", ".cpp"]
config_files = ["Dockerfile", "requirements.txt", "package.json"]

is_code = any(file_path.endswith(ext) for ext in important_extensions)
is_config = any(filename in file_path for filename in config_files)

if is_code:
    # Important: notify and log
    print(f"Code file modified: {os.path.basename(file_path)}")
    subprocess.run(["say", "Code updated"], check=False)  # Mac
    sys.exit(0)  # Show message in transcript
elif is_config:
    # Very important: louder notification
    print(f"Configuration file changed: {os.path.basename(file_path)}")
    subprocess.run(["say", "Configuration updated - review changes"], check=False)
    sys.exit(0)
else:
    # Not important: silent success
    sys.exit(0)

이 훅은 어떤 파일이 수정되었는지 입력을 읽어 파악하고, 파일 유형에 따라 알림 중요도를 결정합니다. 중요한 변경은 stdout으로 대화 내역에 기록하고, 파일 유형별로 다른 오디오 알림을 트리거합니다. 차단이 아닌 정보용 작업이므로 항상 종료 코드 0으로 종료합니다.

입력 분석과 출력 제어를 결합하면 컨텍스트에 따라 지능적으로 동작하면서, 사용자와 Claude Code 모두에게 적절한 수준의 피드백을 제공하는 훅을 만들 수 있습니다. 임시 파일마다 성가신 알림을 받는 대신, 프로젝트에 실제로 중요한 변경에만 알림을 받게 됩니다.

참고로 이 예제는 macOS에서 사용 가능한 say 명령을 사용합니다. Linux에서는 notify-send, Windows에서는 PowerShell 명령 등으로 유사한 알림을 구현할 수 있습니다.

Claude Code 훅의 흔한 함정

처음 일주일 동안 대부분이 겪는 몇 가지 문제입니다.

셸 프로파일의 echo 문이 훅을 망칩니다. 훅은 비대화형 셸에서 실행되며 ~/.zshrc 또는 ~/.bashrc를 소스합니다. 프로파일에 무조건적인 echo 문이 있으면 훅의 stdout 앞에 텍스트가 붙어 JSON 파싱이 깨집니다. 인터랙티브 셸 체크로 감싸세요.

if [[ $- == *i* ]]; then
  echo "Welcome back"
fi

Stop 훅이 무한 루프에 빠질 수 있습니다. Stop 훅이 종료 코드 2로 끝나면 Claude는 계속 작업을 시도합니다. 스크립트가 입력 JSON의 stop_hook_active를 확인해 true일 때 정상 종료하지 않으면, 타임아웃까지 반복됩니다. 항상 초기에 빠른 종료 가드를 넣으세요.

매처는 대소문자를 구분합니다. bashBash와 일치하지 않습니다. Claude Code에 표시되는 정확한 도구 이름을 사용하세요.

출력은 10,000자까지 제한됩니다. 이를 초과하면 Claude 컨텍스트에 주입되기 전 잘립니다. stdout은 간결하게 유지하고, 모델이 행동하는 데 필요한 것만 표면화하세요.

팀 수준 훅과 개인 훅 혼동. .claude/settings.json의 훅은 팀과 공유됩니다(리포지토리에 커밋). 공유하고 싶지 않은 개인 훅은 기본적으로 gitignore되는 .claude/settings.local.json을 사용하세요.

훅 vs. 스킬: 언제 무엇을 쓸까

훅과 Claude 스킬은 목적이 다르며 함께 사용할 때 가장 좋습니다. 스킬은 마크다운 파일로, 절차나 관례, 템플릿 등 무엇을 어떻게 할지 Claude에게 가르칩니다. 훅은 Claude의 결정과 무관하게 규칙을 결정론적으로 강제하는 셸 명령입니다.

차이는 중요합니다. 스킬은 모델이 상황에 따라 무시할 수 있는 제안입니다. 훅은 매번 발화합니다. 팀의 마이그레이션 절차를 문서화하려면 스킬을 작성하세요. Claude가 쓰는 모든 .sql 파일에 마이그레이션 린터를 실행하려면 PostToolUse 훅을 작성하세요. 스킬은 Claude를 유능하게 만들고, 훅은 Claude를 책임 있게 만듭니다.

필요

스킬 사용

훅 사용

관련 시 로드되는 절차적 지식

아니오

건너뛸 수 없는 강제 집행

아니오

매번 결정론적으로 실행

아니오

오동작하는 모델에도 견딤

아니오

Claude Code 훅을 위한 고급 패턴

기본 알림과 로깅을 넘어, 훅은 팀이 매일 겪는 실제 개발 워크플로 문제를 해결할 수 있습니다. 프로젝트에 맞게 적용할 수 있는 아이디어를 소개합니다.

좋은 점은 이런 훅을 직접 모두 만들 필요가 없다는 것입니다. 아래 프롬프트 아이디어 중 하나와 문서의 Hooks 참고문서를 Claude Code에 제공하면, 관련 코드와 구성용 JSON을 생성해 줍니다.

각 패턴은 도구와 워크플로에 맞게 사용자화할 수 있습니다. 매일 가장 큰 불편을 해결하는 것부터 시작해, 훅 개발에 익숙해질수록 자동화를 확장해 보세요.

보안과 컴플라이언스를 위한 고급 훅

훅은 보안 규칙과 컴플라이언스 기준을 강제하기에 좋습니다. 다음 네 가지 사용 사례가 있습니다.

API 키 스캐너

  • 문제: 비밀 정보가 버전 관리에 실수로 커밋됨

  • 트리거: 모든 파일 쓰기 전

  • 해결: 정규식을 사용해 API 키, 토큰, 비밀번호를 파일 콘텐츠에서 스캔

“훅 입력 JSON을 읽어 파일 콘텐츠를 추출하고, api_key=, token:, password= 같은 일반적인 비밀 패턴을 정규식으로 감지하세요.  의심스러운 항목은 로컬에서 검증하고 절대 원문 비밀을 외부로 보내지 마세요. 

마스킹된 일부(예: 앞/뒤 4자 유지)나 해시만 Anthropic API로 보내 의심 문자열이 실제 비밀인지, 변수명인지 판별하게 하세요. 코드 2로 종료해 감지된 비밀과 더 안전한 대안에 대해 Claude에 피드백을 제공하세요.”

라이선스 헤더 강제기

  • 문제: 오픈 소스 프로젝트에서 새 파일에 필수 라이선스 헤더가 누락됨

  • 트리거: 소스 코드 파일 작성 전

  • 해결:.py, .js, .java 파일에 올바른 라이선스 텍스트가 있는지 검증

“훅 입력을 파싱해 파일 콘텐츠를 가져오고, 처음 10줄에 라이선스 텍스트가 있는지 문자열 매칭으로 확인하세요. 더 정교한 검증을 위해 파일 헤더를 Anthropic API로 보내 적절한 저작권 고지와 라이선스 정보가 포함되었는지 확인하게 하세요. 헤더가 없으면 코드 2로 파일 생성을 차단하고, Claude에 올바른 라이선스 템플릿을 제공하세요.”

프로덕션 파일 보호기

  • 문제: 중요 시스템 구성 파일을 실수로 수정

  • 트리거: 민감한 디렉터리의 파일을 편집하기 전

  • 해결: /etc/, nginx.conf, database.yml 등 중요 구성에 대한 변경 차단

“훅 입력 JSON에서 파일 경로를 추출해 /etc/, production.yml 등 패턴과 일치하는지 확인하세요. Claude의 API로 파일 경로를 분석해 프로덕션에 영향을 줄 수 있는 구성 파일인지 판별하게 하세요. 위험 경로가 감지되면 코드 2로 종료하고 더 안전한 개발 관행에 대한 구체적 지침을 제공하세요.”

이미지 최적화기

  • 문제: 큰 이미지 파일이 애플리케이션과 리포지토리를 느리게 만듦

  • 트리거: 새 이미지 파일 추가 후

  • 해결: 시각 품질을 유지하며 PNG/JPEG 파일 압축

“훅 입력을 파싱해 파일 경로를 가져오고 확장자 매칭으로 이미지 파일인지 확인하세요. imageoptim 같은 압축 도구를 실행하거나 TinyPNG API를 호출해 품질을 유지하며 압축하세요. 압축 결과를 stdout에 로깅해 Claude의 대화 내역에서 파일 크기 절감을 확인할 수 있게 하세요.”

버전 관리 자동화를 위한 고급 훅

Git 워크플로와 문서는 훅이 특히 유용한 영역입니다. 몇 가지 아이디어를 살펴보겠습니다.

Git 브랜치 검증기

  • 문제: 팀원이 보호된 브랜치에 실수로 푸시

  • 트리거: 모든 파일 쓰기 또는 편집 전

  • 해결: 현재 Git 브랜치를 확인하고 main/master/production에서 작업 차단

“간단한 bash 명령 git branch --show-current로 현재 브랜치 이름을 가져와 보호된 브랜치 목록과 비교하세요. 보호된 브랜치라면 코드 2로 종료하고 브랜치 보호 정책을 설명하는 오류 메시지를 Claude에 보내세요. 복잡한 브랜치 네이밍 규칙은 Claude의 API로 분석해 보호 패턴과 일치하는지 판별하게 하세요.”

스마트 자동 커밋

  • 문제: 커밋을 잊거나 좋지 않은 커밋 메시지 작성

  • 트리거: 모든 파일 수정 후

  • 해결: AI가 생성한 설명적 메시지로 변경 사항 자동 스테이징 및 커밋

“훅 입력에서 수정된 파일 경로를 읽고 git diff로 변경 내용을 가져온 뒤, Claude의 API에 간결한 커밋 메시지를 요청하세요. 생성된 메시지를 git addgit commit에 사용해 변경 사항을 자동 커밋하세요. API 프롬프트에 파일명과 변경 유형을 포함해 Conventional Commits 기준을 따르는 메시지가 생성되게 하세요.”

문서 생성기

  • 문제: API 문서가 코드 변경과 불일치

  • 트리거: 인터페이스 파일(컨트롤러, 모델, API) 수정 후

  • 해결: JSDoc, Sphinx, OpenAPI 생성기 등 문서 도구 자동 실행

“수정된 파일 경로를 확인해 패턴 매칭으로 API 엔드포인트, 모델, 인터페이스 파일인지 판별하세요. 파일 콘텐츠를 Claude의 API로 보내 API 변경 사항을 추출하고 문서 업데이트를 생성하게 하세요. 적절한 문서 생성 도구(jsdoc, sphinx-build 등)를 실행하고 업데이트된 문서를 자동 커밋하세요.

협업과 워크플로 통합을 위한 고급 훅

마지막으로, 훅은 팀의 모든 구성원이 최신 상태를 유지하도록 돕습니다.

Slack 통합

  • 문제: 공유 코드베이스의 중요한 변경을 팀이 알지 못함

  • 트리거: 중요 작업에 대한 알림이 전송될 때

  • 해결: 파일명과 변경 요약이 포함된 포맷된 메시지를 팀 채널에 게시

“훅 입력에서 파일 정보를 추출하고 소스 코드나 구성 파일 같은 중요한 유형으로 필터링하세요. 파일명과 유형을 바탕으로 변경 사항의 사람이 읽기 쉬운 요약을 Claude의 API로 생성하게 하세요. 웹훅 URL을 사용해 중요 변경에는 팀원 멘션과 함께 Slack에 포맷된 메시지를 전송하세요.”

웹훅 디스패처

  • 문제: 수동 CI/CD 파이프라인 트리거로 인한 배포 지연

  • 트리거: 특정 이벤트 발생 시(구성 변경, 배포 파일 수정)

  • 해결: 외부 API를 호출해 빌드, 배포 등 자동 프로세스 트리거

“수정된 파일 경로를 Dockerfile, package.json, 배포 구성 등 패턴과 비교해 CI/CD 트리거 여부를 결정하세요. Python의 requests 라이브러리로 인증 헤더와 변경 정보 페이로드를 포함해 웹훅 URL을 호출하세요. 외부 시스템이 무엇을 빌드/배포할지 지능적으로 결정할 수 있도록 페이로드에 파일 경로와 변경 메타데이터를 포함하세요.”

상태 페이지 업데이트

  • 문제: 고객이 유지보수나 배포 활동을 인지하지 못함

  • 트리거: 배포나 인프라 파일 수정 시

  • 해결: 서비스 상태 페이지에 유지보수 알림 업데이트

“Kubernetes 매니페스트나 Terraform 구성 같은 인프라 파일 변경을 파일 경로 패턴으로 훅 입력에서 파싱하세요. 감지된 인프라 변경 유형에 따라 Claude의 API로 유지보수 메시지를 생성하세요. StatusPage.io나 PagerDuty 같은 서비스의 REST API를 사용해 적절한 인시던트 유형과 예상 소요 시간을 포함해 상태 업데이트를 게시하세요.”

팀 상태 알리미

  • 문제: 여러 개발자가 같은 기능을 모르게 동시에 작업해 충돌 발생

  • 트리거: 새 Claude Code 세션 시작 시

  • 해결: 특정 프로젝트나 컴포넌트 작업 시작을 팀 채널에 알림

“훅 입력에서 프로젝트 디렉터리를 읽고, 최근 파일이나 git 기록을 분석해 어떤 유형의 작업인지 Claude의 API로 파악하세요. 이름, 프로젝트명, 집중 영역을 포함한 포맷된 메시지를 팀 커뮤니케이션 채널로 보내세요. 예상 작업 기간을 포함하고, 관련 기능을 작업 중인 팀원에게 협업을 제안하세요.”

마무리

Claude Code 훅은 예측 불가능한 AI 코딩 도우미를 필요한 순간 정확히 실행되는 자동화된 워크플로로 바꿉니다. 이 튜토리얼에서는 대화형 /hooks 명령과 수동 구성으로 훅을 설정하는 방법, 지능형 자동화를 가능하게 하는 JSON 입력 데이터를 이해하는 방법, 종료 코드와 구조화된 출력을 통해 Claude의 동작을 제어하는 방법을 학습했습니다. 

실용적 패턴으로는 위험 작업을 차단하는 보안 검증기와 소음을 줄이는 스마트 알림을 다뤘습니다. 이러한 예시는 훅이 실제 개발 문제를 해결하면서 AI 도우미에 대한 완전한 통제력을 제공함을 보여줍니다. 이제 기본을 이해했으니, 팀의 워크플로 요구에 맞는 자동화를 구축해 보세요. 

AI 도구 활용을 더 배우고 싶다면 DataCamp의 Understanding Prompt Engineering 과정을 확인하세요. 훅 개발과 직접 맞물리는 프롬프트 전략을 다룹니다. 더 폭넓은 AI 코딩 역량을 원한다면 Intermediate ChatGPT 과정으로 개발 워크플로에서 AI 도우미를 더 신뢰할 수 있는 파트너로 만드는 기술을 익히세요.

Claude Code 훅 자주 묻는 질문(FAQs)

Claude Code 훅이란 무엇인가요?

Claude Code 훅은 Claude Code 세션 중 특정 이벤트가 발생할 때 셸 명령을 실행하는 자동 트리거입니다. Claude가 코드는 잘 쓰지만 포매팅, 테스트 실행, 보안 점검 같은 중요한 단계를 잊어버리는 문제를 해결해 줍니다. 매번 수동으로 상기시키는 대신, 훅이 이를 자동으로 실행합니다. 예를 들어, Claude가 Python 코드를 쓴 뒤 포매팅하고, 수정 후 테스트를 실행하거나, 민감한 파일에 대한 위험한 변경을 차단합니다. 훅은 세션을 모니터링하고 일치하는 이벤트를 감지해, Claude가 방금 수행한 작업에 대한 상세 컨텍스트에 접근한 상태로 구성한 명령을 실행합니다.

Claude Code에서 훅은 어떻게 사용하나요?

두 가지 방법으로 훅을 설정할 수 있습니다. 가장 쉬운 방법은 Claude Code에서 대화형 /hooks 명령을 사용하는 것입니다. 여기서 이벤트(PostToolUse 등), 매처 패턴(파일 작성을 위한 Write 등), 명령(python -m black . 등)을 차례로 선택하도록 안내합니다. 또는 전역은 ~/.claude/settings.json, 프로젝트별은 .claude/settings.json에서 JSON으로 훅을 직접 정의할 수도 있습니다. 구성 후 훅은 자동으로 로드되어 활성화됩니다. /hooks를 다시 실행하거나 Claude Code를 재시작해 언제든지 훅을 확인, 수정, 리로드할 수 있습니다.

PreToolUse와 PostToolUse 훅의 차이는 무엇인가요?

PreToolUse 훅은 Claude가 파일을 쓰거나 편집하는 등 동작을 실행하기 전에 실행되어 검증 및 위험 작업 차단에 적합합니다. 코드 2로 종료해 필요한 경우 작업을 중단할 수 있습니다. PostToolUse 훅은 Claude가 동작을 완료한 후에 실행되어 코드 포매팅, 테스트 실행, 로깅 같은 정리 작업에 적합합니다. 사전 예방적 제어가 필요하면 PreToolUse, 사후 자동화가 필요하면 PostToolUse를 사용하세요.

Claude가 한 작업 정보를 훅 스크립트에 어떻게 전달하나요?

Claude Code는 표준 입력(stdin)으로 JSON 형태의 상세 정보를 전송합니다. 여기에는 파일 경로, 작성될 콘텐츠, 세션 ID 등 컨텍스트가 포함됩니다. 훅 스크립트는 Python에서는 json.load(sys.stdin) 등으로 이 JSON을 읽습니다. 이 페이로드를 활용해 파일 확장자를 확인해 Python 파일만 포매팅하거나, 파일 경로를 검사해 특정 디렉터리에 대한 수정만 차단하는 등 지능적인 결정을 내릴 수 있습니다.

종료 코드 2는 무엇이며 언제 사용하나요?

종료 코드 2는 작업을 차단해야 한다는 신호이며, stderr에 쓴 오류 메시지를 Claude에게 직접 보냅니다. 그러면 Claude가 문제를 설명하고 대안을 제시할 수 있습니다. 보안 검사(위험한 파일 수정 차단), 컴플라이언스 검증(필수 헤더 누락), 안전 게이트(보호된 브랜치로의 커밋 방지) 등에 코드 2를 사용하세요. 결코 차단하지 말아야 하는 정보용 훅에는 코드 0이나 다른 코드를 사용하세요.

Claude Code 훅이 무한 루프를 유발할 수 있나요?

가능합니다. Stop 훅은 주의하지 않으면 무한 루프에 빠질 수 있습니다. Stop 훅이 코드 2로 종료하면 Claude는 계속 작업을 시도합니다. 스크립트가 훅 입력 JSON의 stop_hook_active를 확인해 이미 true일 때 즉시 코드 0으로 종료하지 않으면, Claude가 응답하고 다시 Stop 훅이 트리거되고, 다시 차단되는 과정이 세션 타임아웃까지 반복됩니다. 항상 스크립트 상단에 이 필드를 확인하는 가드를 추가하세요.

셸 명령 외에 Claude Code가 지원하는 훅 유형은 무엇인가요?

Claude Code는 다섯 가지 훅 유형을 지원합니다. command(가장 일반적인 셸 명령), http(웹훅 통합을 위한 URL로 POST), mcp_tool(연결된 MCP 서버의 도구 호출), prompt(단일 턴 평가를 위해 Claude 모델에 프롬프트 전송), agent(조건 검증을 위해 도구를 사용할 수 있는 서브에이전트 생성)입니다. 대부분의 사용 사례는 command 훅으로 충분합니다. 각 유형의 상세 내용은 공식 훅 참고문서를 참조하세요.

주제

DataCamp로 AI 보조 코딩을 배워보세요!

courses

개발자를 위한 AI 보조 코딩

1 시 30 분
8.1K
AI로 코딩 능력을 향상시키세요—코딩 어시스턴트를 활용해 코드를 효과적으로 작성, 테스트, 문서화하세요.
자세히 보기Right Arrow
강좌 시작
더 보기Right Arrow