본문으로 건너뛰기
H
Harness 101
학습 경로/Act 1 — 생존/03. Hooks
Permissions·초중급·75분

그날 밤에 일어난 일

“Claude가 움직일 때 나도 움직이고 싶다”

Hooks — 행동 전후에 개입하는 23개의 문

이전 이야기에서: 지민은 CLAUDE.md로 Claude에게 프로젝트를 기억시켰다. 이제 "Next.js 14 프로젝트야"를 매번 말할 필요가 없었다. Claude가 더 자신감 있게 일하기 시작했다. 파일을 수정하고, 코드를 실행하고... 그러던 어느 날 밤.

Harness = Tools + Knowledge + Context + Permissions

Hooks는 Harness의 Permissions 제어 메커니즘이다. "Claude가 움직일 때 나도 움직이고 싶다"


그날 밤에 일어난 일

지민이 자고 있는 동안 Claude가 코드 리뷰를 하고 있었다. 테스트가 실패했다. Claude는 "수정하겠습니다"라며 코드를 고쳤다. 그리고 git push를 main 브랜치에 실행했다.

아침에 Slack 알림이 7개 와 있었다.

현우: @지민 프로덕션 빌드 실패함. 누가 main에 직접 push 했어?
현우: 새벽 2시에?

지민은 깨달았다. Claude에게 기억(CLAUDE.md)을 줬더니 자신감이 생겼다. 하지만 경계가 없었다.

CLAUDE.md로 Claude가 프로젝트를 기억하게 됐다. Claude는 이제 더 자신감 있게 행동했다. 파일을 고치고, 터미널 명령을 실행하고, 여러 파일을 한꺼번에 수정했다.

그런데 개발자들에게 불편함이 생겼다.

Claude가 파일을 수정함
  → 나는 수동으로 lint를 돌려야 함
  → 나는 수동으로 테스트를 실행해야 함
  → 나는 수동으로 포매터를 실행해야 함
  → ...

더 답답한 상황도 있었다.

Claude가 git push를 실행하려 함
  → 내가 원하지 않는 순간일 수 있음
  → 막을 방법이 없음

그리고 아주 사소하지만 삶의 질과 직결된 욕구도 있었다.

Claude가 30분짜리 작업을 하고 있음
  → 나는 딴 일을 하고 있음
  → 작업이 끝났는지 계속 탭을 확인해야 함
  → "끝나면 소리 내줘" 같은 게 있으면 좋겠다

"Claude의 모든 행동에 내가 개입할 수 있는 방법이 필요하다."


해결책의 탄생: "이벤트 시스템"

Anthropic은 Claude Code에 이벤트 기반 훅 시스템을 도입했다.

Agent Loop의 관점에서 보면, Hooks는 루프의 각 단계에 끼어드는 인터셉터다:

def agent_loop(messages):
    while True:
        response = client.messages.create(...)

        for block in response.content:
            if block.type == "tool_use":
                # ← PreToolUse 훅 (허용/차단)
                output = TOOL_HANDLERS[block.name](**block.input)
                # ← PostToolUse 훅 (반응/주입)

핵심 아이디어는 단순하다: Claude가 특정 행동을 할 때마다, 지정한 스크립트를 실행한다.

{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Edit|Write",
      "hooks": [{
        "type": "command",
        "command": "npm run lint"
      }]
    }]
  }
}

Claude가 파일을 수정할 때마다(Edit|Write) → lint 자동 실행. 한 줄의 설정으로 수동 작업이 자동화됐다.


Harness에서 Hooks의 위치

Permissions 레이어가 없는 Harness:
  Claude가 어떤 툴이든 아무 때나 실행 가능
  → rm -rf 실수, git push 실수, 프로덕션 DB 수정 실수

Permissions 레이어가 있는 Harness:
  PreToolUse: 실행 전 차단/허용 결정
  PostToolUse: 실행 후 반응 (린트, 테스트, 알림)
  UserPromptSubmit: 입력에 컨텍스트 주입
  → Claude는 같은 루프를 돌지만, 행동 경계가 명확해진다

Permissions 레이어의 핵심 원칙:

"에이전트에게 필요한 권한만 준다. 최소 권한이 실수를 방지한다." Hooks는 이 원칙을 동적으로 실행한다.