Claude Code에는 약 30개의 훅 (hook) 이벤트가 있습니다. 저는 단 하나만 사용해 왔습니다.
요약
Claude Code에서 제공하는 약 30개의 훅(hook) 이벤트 중 유용한 주요 이벤트들을 소개합니다. PreToolUse 외에도 Stop, PreCompact, SessionStart, PostToolUse 등의 활용법을 통해 에이전트의 동작을 정교하게 제어하는 방법을 설명합니다.
핵심 포인트
- Stop 훅을 사용하여 에이전트의 작업 완료 여부를 결정하는 게이트로 활용 가능
- PreCompact 훅을 통해 컨텍스트 압축 전 상태를 디스크에 저장하여 데이터 유실 방지
- SessionStart 훅으로 현재 브랜치나 이슈 등 동적 컨텍스트를 세션에 주입
- PostToolUse 훅을 사용하여 도구 출력값에서 비밀번호를 제거하거나 내용을 수정
먼저 밝혀둡니다: 저는 오픈 소스 에이전트 하네스 (agent harness)인 Agent AFK를 개발하고 있으며, 따라서 Claude Code가 실행되는 것과 동일한 메커니즘에서 많은 시간을 보냅니다. 저만의 훅 (hook) 시스템을 구축하면서 Claude Code의 훅 문서를 다시 살펴보니 약 30개의 훅 이벤트가 있다는 것을 확인했습니다. 저는 그중 단 하나(PreToolUse)만 사용해 왔으며, 많은 분이 저와 같은 상황일 것이라고 생각합니다.
PreToolUse는 가장 유명한 이벤트입니다 (도구 호출이 실행되기 전에 이를 차단할 수 있습니다). 하지만 이는 전체 기능의 30분의 1 정도에 불과합니다. 제가 더 일찍 알았더라면 좋았을 훅 이벤트들과 각각의 이벤트로 실제로 무엇을 구축할 수 있는지 소개합니다. 이 모든 내용은 Claude Code의 자체 문서에 포함되어 있지만, 저는 첫 번째 예시 이후로는 읽지 않았을 뿐입니다.
Stop은 완료 여부를 결정하는 게이트 (doneness gate)입니다. 메인 에이전트가 자신의 턴을 종료하려고 할 때 실행되며, 모델에게 이유와 함께 "아니요, 계속하세요"라고 말할 수 있습니다. 따라서 "이것을 완료하기 전에 테스트를 실행하세요"라는 명령은 단순한 희망 사항이 아니라 규칙이 됩니다. 문서에서 언급하는 한 가지 미묘한 차이점은 다음과 같습니다: decision:block을 반환하면 Claude는 계속 작동하지만 트랜스크립트(transcript)에는 *훅 에러 (hook error)*로 표시됩니다. 반면 additionalContext를 반환하는 것도 Claude를 계속 작동하게 하지만, 일반적인 "Stop 훅 피드백 (Stop hook feedback)"으로 읽힙니다. 무언가 고장 난 것처럼 보이지 않도록 일상적인 게이트에는 두 번째 방식을 사용하세요. (무한 루프를 방지하기 위해 8회 연속 제한이 있습니다.)
PreCompact는 컨텍스트 (context)가 압축 (compacted)되기 직전에 실행됩니다. 이는 생각보다 더 중요합니다. 컨텍스트 창이 가득 차면, 하네스 (harness)는 지금까지의 이력을 요약하고 원본 턴 (raw turns)을 해당 요약본으로 대체합니다. 이전에 구축했지만 파일에 기록하지 않은 모든 것은 이제 여러분이 보지 못한 요약본에 의해 생존하거나 사라지게 됩니다. PreCompact는 그런 일이 일어나기 전에 상태 (state)를 디스크에 저장할 수 있는 마지막 기회입니다 (그리고 PostCompact는 요약본을 로그로 남기고 싶을 경우 그 이후의 요약본을 전달합니다). 솔직히 긴 세션을 실행한다면 제가 가장 먼저 추가할 훅은 이것입니다.
SessionStart는 CLAUDE.md가 담을 수 없는 컨텍스트를 전달합니다. CLAUDE.md는 변하지 않는 것들을 위한 것입니다. SessionStart는 세션 시작 시 스크립트를 실행하고 현재 상태를 주입합니다: 현재 작업 중인 브랜치 (branch), 열려 있는 이슈 (issues), 마지막 CI 결과 등 무엇이든 가능합니다.
문서에는 동적 사실(dynamic facts)은 CLAUDE.md가 아니라 이곳에 속해야 한다고 명시되어 있습니다. 또한 실행 도중에 스킬(skills)을 다시 로드하거나, 세션이 끝날 때까지 환경 변수(env vars)를 유지할 수도 있습니다.
PostToolUse는 모델이 보는 내용을 다시 쓸 수 있습니다. 모두가 이를 "수정 후 린터(linter)를 실행하는 것"으로 생각하며, 실제로도 그렇습니다. 하지만 모델이 읽기 전에 도구의 출력값(updatedToolOutput)을 교체하거나, 결과 옆에 노트를 붙일 수도 있습니다. 명령의 출력에서 비밀번호(secrets)를 제거하거나, "이 파일은 생성된 파일이니 대신 소스 코드를 수정하세요"라는 피드백을 전달할 수도 있습니다. 문서는 정확히 이러한 종류의 편집(redaction)을 위해 PreToolUse와 PostToolUse를 지목하고 있으며, 모델은 오직 당신이 허용한 버전만을 보게 됩니다.
훅(hook)이 반드시 쉘 스크립트(shell script)일 필요는 없습니다. 솔직히 저는 너무 오랫동안 이 사실을 깨닫지 못했습니다. 명령(commands) 외에도, 훅은 type:prompt(Claude Code가 예/아니오 판단을 위해 빠른 모델로 이벤트를 전송) 또는 type:agent(Read/Grep/Glob 기능을 가진 서브 에이전트(subagent)를 생성하여 조사한 뒤 결정하게 함) 유형이 될 수 있습니다. 따라서 당신의 중단 게이트(Stop gate)는 말 그대로 "에이전트를 생성하고, 테스트 스위트(suite)를 실행한 뒤, 통과했을 때만 나를 멈추게 해라"가 될 수 있습니다. 스크립트가 필요 없습니다.
제가 아직 실험 중인 몇 가지 언급할 만한 것들은 다음과 같습니다: UserPromptSubmit(모델이 보기 전에 프롬프트를 차단하거나 풍부하게 만듦, 저는 AFK에서 정확히 이 기능을 출시했습니다), SubagentStart/SubagentStop(서브 에이전트에 컨텍스트를 주입함. 단, 부모에게 무언가를 피드백하려면 SubagentStop이 아니라 Agent 도구에 PostToolUse를 걸어야 합니다), MessageDisplay(대화 기록(transcript)을 건드리지 않고 화면에 표시되는 내용을 다시 씀, 편집(redaction)에 유용함), 그리고 비동기 훅(async hooks, 백그라운드에서 테스트 실행을 시작하고 다음 턴에 결과를 받음)입니다.
제가 주장하지 않는 점: 저는 Claude Code를 역공학(reverse-engineer)한 것이 아닙니다. 훅 목록은 공식 문서에서 그대로 가져온 것이며, 동작을 추측하는 부분은 명시하겠습니다. 또한 저는 30개를 모두 제 하네스(harness)에 구현하지도 않았습니다. 저는 라이프사이클(lifecycle) 관련 훅(start, stop, pre/post tool, compaction)을 깊게 파고들었으며, 에이전트 팀(agent-team) 관련 훅은 여전히 파악 중입니다.
대부분의 경우, 저는 다른 사람들이 이 중 실제로 어떤 것들을 실전에서 사용하는지 궁금합니다.
제 생각에 '게이트로서의 중단 (Stop-as-a-gate)' 방식은 활용도가 낮은 것 같은데, 어쩌면 제가 너무 늦게 발견한 것일지도 모르겠습니다. 여러분은 어떤 것들을 연결해서 사용하고 계신가요?
submitted by /u/Slowstonks40
[link] [comments]
AI 자동 생성 콘텐츠
본 콘텐츠는 r/ClaudeAI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기