
Claude Code hooks 완전 가이드 — AI의 행동을 메커니즘으로 제어하기
요약
Claude Code의 hooks 기능을 활용하여 AI의 동작을 자동화하고 제어하는 방법을 설명합니다. PreToolUse, PostToolUse 등 다양한 이벤트 시점에 쉘 스크립트를 실행하여 보안 검사나 코드 품질 체크를 자동화할 수 있습니다.
핵심 포인트
- hooks를 통해 Claude Code의 특정 액션 전후에 쉘 스크립트 실행 가능
- .env 파일 커밋 방지 등 보안 및 시크릿 유출 자동 차단
- PostToolUse를 활용한 코드 품질(ruff 등) 자동 검사
- Stop hook을 이용한 세션 종료 시 로그 기록 자동화
AI 기업(こびと社)을 개인으로 운영하며, Claude Code를 매일 사용하며 시행착오를 겪고 있습니다. 이 기사는 실제로 구동하며 얻은 지견을 정리한 것입니다.
동작 확인 환경: macOS Sequoia 15.x / Claude Code (최신 버전) / zsh
Claude Code에 「.env를 커밋하려고 하면 중단하기」, 「세션 종료 시 일일 로그를 기록하기」와 같은 자동적인 제어를 추가할 수 있다는 사실을 알고 계십니까?
이것이 Claude Code의 hooks 기능입니다.
이 기사에서는 hooks의 메커니즘과 실전적인 사용법을 해설합니다. 실제로 작동하고 있는 코드를 바탕으로 하고 있습니다.
hooks는 「Claude Code가 특정 액션을 실행하기 전후에 쉘 스크립트(Shell Script)를 자동으로 실행하는 메커니즘」입니다.
Claude Code가 툴(Tool)을 사용
↓
[PreToolUse hook] ← 여기에 검사 스크립트를 심음
...
hooks가 없다면: Claude Code가 .env를 커밋하려고 해도 중단할 수 없습니다.
hooks가 있다면: git commit을 감지하면 자동으로 시크릿 검사 스크립트를 실행하여, 문제가 있으면 커밋을 차단할 수 있습니다.
.claude/settings.json의 hooks 필드에서 설정합니다.
| 이벤트 | 타이밍 |
|---|---|
PreToolUse | Claude가 툴을 사용하기 전 |
PostToolUse | Claude가 툴을 사용한 후 |
PreCompact | /compact (컨텍스트 압축) 전 |
Stop | Claude가 세션을 종료하기 전 |
.claude/settings.json:
{
"hooks": {
"PreToolUse": [
...
matcher: 어떤 툴이 대상인지 (Bash, Write, Edit, Read 등). 생략하면 모든 툴이 대상입니다. when: 추가 조건 (JavaScript 식). tool_input.command로 커맨드 문자열을 참조할 수 있습니다. command: 실행할 쉘 커맨드. 스크립트 파일을 지정하는 것을 추천합니다.
.env의 오커밋이나 API 키 유출을 자동으로 방지합니다.
.claude/hooks/pre-commit-check.sh:
#!/usr/bin/env bash
set -euo pipefail
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM 2>/dev/null || true)
...
동작 이미지:
Claude: git commit -m "feat: add new feature"
↓
[pre-commit-check.sh 가 자동 기동]
...
Claude Code 측은 차단을 받으면 커밋을 중지하고 사용자에게 보고합니다.
Claude Code가 대화를 종료하려고 할 때, 일일 로그의 기록 상황을 확인합니다.
.claude/hooks/session-stop.sh:
#!/usr/bin/env bash
TODAY=$(date +%Y-%m-%d)
NOW=$(date +%H:%M)
...
중요: Stop hook 스크립트는 exit 0으로 끝나야 합니다. 0이 아닌 값으로 종료하면 Claude Code가 세션 종료를 거부합니다.
{
"PostToolUse": [
{
...
# .claude/hooks/post-write-check.sh
#!/usr/bin/env bash
# src/ 에 쓰기가 있으면 ruff 로 자동 체크
...
src/로의 Write가 완료되면 자동으로 ruff가 실행됩니다. 코드 품질 체크를 커밋 전이 아니라 쓰기 직후에 실행하고 싶을 때 유용합니다.
| 코드 | 의미 | 주요 용도 |
|---|---|---|
0 | 성공 | 일반적인 완료 |
1 | 경고 (계속) | 문제는 있으나 중단하지 않음 |
2 | 차단 (중단) | PreToolUse에서 도구 실행을 중단 |
PostToolUse와 Stop은 종료 코드(exit code)와 관계없이 이미 실행된 액션을 취소할 수 없습니다.
hook의 echo 출력은 Claude Code의 대화창에 표시됩니다.
echo "::error::시크릿을 감지했습니다" # 에러로 표시
echo "::warning::경고: 200행을 초과했습니다" # 경고로 표시
echo "일반 메시지" # 일반 메시지
Claude는 이 출력을 바탕으로 다음 액션을 판단합니다. 구체적인 메시지를 작성하면 Claude가 정확하게 대응할 수 있습니다.
hook 스크립트가 장시간 실행되면 Claude의 응답이 느려집니다. PreToolUse hook은 특히 가볍게 유지해야 합니다. 기준은 5초 이내입니다.
when 필드에는 JavaScript 식이 작성될 수 있습니다.
"when": "tool_input.command.startsWith('git commit')"
"when": "tool_input.path.endsWith('.env')"
"when": "tool_input.command.includes('rm -rf')"
|| (OR)나 && (AND)도 사용할 수 있습니다.
"이 작업은 hook을 통해 확인된 경우에만 허용한다"는 설계.
{
"PreToolUse": [
{
...
check-destructive.sh가 exit 2를 반환하면 명령은 실행되지 않습니다.
작업 후에 상태를 기록하고 싶은 경우.
{
"PostToolUse": [
{
...
모든 git 작업을 로그로 남길 수 있습니다.
{
"PostToolUse": [
{
...
Python 파일에 대한 Write 이후에 자동으로 포맷팅.
Claude Code hooks를 사용하면 AI의 행동에 "메커니즘 수준의 제어"를 추가할 수 있습니다.
| 사용 사례 | hook 종류 | 구현 |
|---|---|---|
| 커밋 전 시크릿 검사 | PreToolUse (Bash) | git commit을 when으로 필터링 |
| ... |
hooks는 "신뢰하고 맡길 수 있는 범위를 넓히기 위한 안전망(safety net)"입니다.
Claude Code를 자율적으로 동작시키고 싶을수록, 멈추는 메커니즘을 제대로 만드는 것이 중요합니다.
이 기사는 Zenn에도 곧 공개될 예정입니다. 괜찮으시다면 팔로우해 주세요 → Zenn: kobito-co
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기