byteforce

CPN 한국어 자습서 · Claude Code in Action

3 · 훅과 SDK

유용한 훅

Useful hooks

훅을 정의하고 구현하는 법을 배웠으니, 이제 실전에서 바로 쓸 만한 훅 두 가지를 봅니다. 하나는 타입 오류를 즉시 잡아 주고, 다른 하나는 또 다른 Claude Code 인스턴스를 띄워 중복 코드를 막습니다 — 다음 레슨에서 다룰 SDK가 처음 등장하는 지점입니다.

전체 내레이션영상 나레이션 한국어 번역 (전체)

Stephen Grider · Anthropic 기술 스태프

Claude Code 훅은 AI 보조 개발에서 자주 나타나는 약점을 메우는 데 큰 도움이 됩니다. 특히 규모가 큰 프로젝트에서 그렇습니다. 이 훅들은 Claude가 코드를 바꿀 때 자동으로 실행되어, 즉각적인 피드백을 주고 흔한 문제를 미리 막아 줍니다.

첫 번째는 타입스크립트 타입 검사 훅입니다. 근본적인 문제 하나를 해결합니다. Claude가 함수 시그니처를 고치면, 그 함수를 호출하는 자리를 전부 같이 고치지 못하는 경우가 많습니다. 예를 들어 schema.ts의 어떤 함수에 verbose 매개변수를 추가해 달라고 하면, 함수 정의는 잘 바꾸지만 main.ts의 호출부는 놓치곤 합니다. 그러면 Claude가 곧바로 알아채지 못하는 타입 오류가 생깁니다.

해법은 파일을 수정할 때마다 실행되는 post-tool-use 훅입니다. 이 훅은 타입스크립트 컴파일러를 돌려(tsc --noEmit) 타입 오류를 확인하고, 발견된 오류를 모아 Claude에게 곧바로 되먹입니다. 그러면 Claude가 다른 파일의 호출부까지 고치게 됩니다. 타입이 있는 언어라면 어디서든 통하고, 타입이 없는 언어라면 자동화된 테스트로 비슷하게 구현할 수 있습니다.

두 번째는 중복 쿼리 방지 훅입니다. 데이터베이스 쿼리가 많은 큰 프로젝트에서 Claude는 이미 있는 코드를 재사용하지 않고 같은 기능을 새로 만들기도 합니다. 데이터베이스 작업이 전체 작업의 한 부분일 뿐인 복잡한 다단계 작업을 줄 때 특히 그렇습니다.

예를 들어 queries 폴더에 수많은 SQL 함수가 든 쿼리 파일이 여러 개 있다고 합시다. “3일 넘게 대기 중인 주문을 알려 주는 슬랙 통합을 만들어 줘”라고 하면, 이미 있는 getPendingOrders 함수를 쓰지 않고 새 쿼리를 짤 수 있습니다.

중복 쿼리 훅은 이를 리뷰 절차로 해결합니다. Claude가 ./queries 디렉터리의 파일을 Write·Edit·MultiEdit로 건드리면 훅이 발동합니다. 훅은 Claude Code의 별도 사본을 프로그램으로 띄워, 그 인스턴스에게 queries 디렉터리를 조사해 비슷한 쿼리가 이미 있는지 확인하게 합니다. 중복이 있으면 원래 Claude에게 피드백을 줘서, 중복을 지우고 기존 기능을 쓰도록 바로잡을 기회를 줍니다.

구현 시 고려할 점이 있습니다. 두 훅 모두 pre-tool-use 또는 post-tool-use 시스템을 씁니다. 타입스크립트 훅은 비교적 가볍고 빠르게 끝납니다. 반면 중복 쿼리 훅은 리뷰마다 별도의 Claude 인스턴스를 띄우므로 자원을 더 씁니다. 그래서 쿼리 훅은 이득(중복 없는 깔끔한 코드베이스)과 비용(쿼리 디렉터리를 고칠 때마다 드는 추가 시간과 API 사용량)을 저울질해야 하고, 중요한 디렉터리만 감시하길 권합니다.

이 훅들은 Claude의 Agent SDK로 AI와 프로그램적으로 상호작용합니다. 한 Claude 인스턴스가 다른 인스턴스의 작업을 리뷰하고 피드백을 주는, 정교한 워크플로를 만들 수 있다는 뜻입니다 — 바로 다음 레슨에서 다룰 SDK입니다.

이 두 예시는 여러분 프로젝트에도 적용할 수 있는 더 넓은 원칙을 보여 줍니다. 컴파일러·린터 출력으로 즉각적인 피드백을 주기, 별도 AI 인스턴스로 코드 리뷰 절차 만들기, 일관성이 가장 중요한 고가치 디렉터리에 감시 집중하기, 그리고 자동화의 이득과 성능 비용을 저울질하기. 핵심은 내 개발 워크플로에서 구체적인 통증 지점을 찾아, 그것을 자동으로 해결하는 표적 훅을 만드는 것입니다.

이 장에서 배우는 것What you'll learn

약 8분
1

훅은 흔한 약점을 메우고 Claude의 변경에 자동으로 즉시 피드백을 준다

2

타입 검사 훅(PostToolUse): 수정 후 tsc --noEmit로 오류를 Claude에 되먹임

3

중복 쿼리 방지 훅: ./queries 변경 시 발동하는 리뷰 절차

4

쿼리 훅은 별도 Claude 인스턴스(Agent SDK)를 띄워 중복을 찾는다

5

가벼운 훅 vs 무거운 훅 — 이득과 성능 비용을 저울질한다

6

핵심: 내 워크플로의 통증 지점을 찾아 표적 훅으로 자동 해결

먼저 짚고 갈 용어
PostToolUse 훅
도구 사용이 끝난 뒤 실행되는 훅. 타입 검사 훅이 여기에 해당 — 수정 직후 컴파일러를 돌린다.
tsc --noEmit
타입스크립트 컴파일러를 결과 파일 생성 없이 돌려 타입 오류만 확인하는 명령.
PreToolUse 훅
도구가 실행되기 에 끼어드는 훅. 중복 쿼리 훅이 여기서 변경을 가로채 리뷰한다.
Agent SDK
Claude Code를 프로그램에서 호출하는 SDK. 한 인스턴스가 다른 인스턴스를 띄워 리뷰하게 해 준다.

훅이 메우는 약점

Why these hooks

Claude Code 훅은 AI 보조 개발에서 자주 나타나는 약점을 메웁니다 — 특히 큰 프로젝트에서요. Claude가 코드를 바꿀 때 자동으로 실행되어, 즉각적인 피드백을 주고 흔한 문제를 미리 막습니다. 이 레슨에서는 바로 쓸 만한 두 가지를 봅니다.

유용한 훅 두 가지 · 탭을 눌러 비교

문제 · Claude가 함수 시그니처를 바꾸면(예: schema.tsverbose 추가) 정의는 고치지만 main.ts호출부를 놓쳐 타입 오류가 남습니다.

  • Claude가 파일을 수정·작성한다 (Write/Edit)
  • PostToolUse 훅이 tsc --noEmit로 타입 오류를 검사한다
  • 발견된 오류를 모아 Claude에게 곧바로 되먹인다
  • Claude가 다른 파일의 호출부까지 고친다

문제 · 쿼리가 많은 프로젝트에서 Claude가 기존 getPendingOrders()를 두고 같은 쿼리를 새로 짭니다.

  • Claude가 ./queries의 파일을 Write/Edit/MultiEdit로 건드린다
  • PreToolUse 훅이 발동해 별도 Claude 인스턴스를 프로그램으로 띄운다
  • 그 인스턴스가 디렉터리를 조사해 비슷한 쿼리가 있는지 확인한다
  • 중복이 있으면 피드백 → Claude가 기존 함수를 쓰도록 바로잡는다

왼쪽은 가벼운 훅(컴파일러 한 번), 오른쪽은 무거운 훅(리뷰마다 새 인스턴스). 둘 다 Claude의 변경을 자동으로 점검한다는 점이 같습니다.

타입 검사 훅

TypeScript type-checking hook

Claude가 함수 시그니처를 고치면 정의는 바꾸지만 호출부를 놓치기 쉽습니다. 해법은 수정 직후 tsc --noEmit를 돌리는 PostToolUse 훅입니다. 오류를 모아 Claude에게 곧바로 되먹이면, Claude가 다른 파일의 호출부까지 고칩니다.

.claude/settings.json · PostToolUse 훅 등록
// .claude/settings.json — 수정 후 타입 검사 훅 (개념 예시)
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit",    // 파일을 바꾸는 도구만
        "hooks": [
          { "type": "command", "command": "node hooks/tsc.js" }
        ]
      }
    ]
  }
}
언어 불문

타입이 있는 언어라면 어디서든 통합니다(컴파일러·린터로 검사). 타입이 없는 언어라면 자동화된 테스트를 돌려 비슷하게 구현할 수 있습니다.

중복 쿼리 방지 훅

Query duplication prevention

쿼리가 많은 프로젝트에서 Claude는 기존 코드를 재사용하지 않고 같은 기능을 새로 만들기도 합니다. 이 훅은 ./queries 변경을 가로채, 별도 Claude 인스턴스(Agent SDK)에게 중복 여부를 리뷰시킵니다.

중복이 생기는 순간 · order_alerts_queries.ts
# 쿼리가 많은 프로젝트 — 이미 getPendingOrders()가 있는데도
# "3일 넘게 대기 중인 주문 슬랙 알림"을 시키면 새 쿼리를 짜기도 한다.

"Write"(src/queries/order_alerts_queries.ts)
  └ Wrote 24 lines

import { Database } from "sqlite";
export function getOrdersPendingTooLong(db: Database, days: number = 3) {
  const query = `
    SELECT o.order_number, o.created_at,
      CAST((julianday('now') - julianday(o.created_at)) AS INTEGER) AS days_pending
    ...                       # ✗ 기존 함수와 중복되는 새 쿼리
  `;
}

훅이 띄운 두 번째 Claude가 디렉터리를 조사해 중복을 찾고, 원래 Claude가 기존 함수를 쓰도록 바로잡습니다.

별도 인스턴스의 리뷰 · 중복 제거
# PreToolUse 훅이 ./queries 변경을 가로채 별도 Claude를 띄운다.
# 그 인스턴스가 디렉터리를 조사하고 중복을 찾는다:

Read(src/main.ts)                       └ Read 16 lines
Read(src/queries/order_queries.ts)      └ Read 251 lines

● Perfect! order_queries.ts에 이미 getPendingOrders 함수가
  있고, days_since_created 계산 필드까지 들어 있습니다. main.ts가
  이 함수를 쓰도록 바꾸고 3일 넘는 주문만 거르겠습니다.   # ✓ 중복 제거
자원 주의

이 훅은 리뷰마다 새 Claude 인스턴스를 띄우므로 가볍지 않습니다. 이득(중복 없는 깔끔한 코드)과 비용(추가 시간·API 사용량)을 저울질하고, 중요한 디렉터리만 감시하길 권합니다.

더 넓은 원칙 & 점검

Extending these concepts
가벼운 훅

타입 검사 훅 — 컴파일러를 한 번 돌릴 뿐이라 빠르게 끝납니다. 어떤 변경에든 켜 둘 만합니다.

무거운 훅

중복 쿼리 훅 — 리뷰마다 별도 인스턴스를 띄워 자원을 더 씁니다. 고가치 디렉터리에만 적용하세요.

적용할 수 있는 더 넓은 원칙
  • 컴파일러·린터 출력으로 즉각적인 피드백을 준다.
  • 별도 AI 인스턴스로 코드 리뷰 절차를 만든다(Agent SDK).
  • 일관성이 가장 중요한 고가치 디렉터리에 감시를 집중한다.
  • 자동화의 이득과 성능 비용을 저울질한다.

Q1타입 검사 훅은 언제 무엇을 하나요?

Q2중복 쿼리 방지 훅의 핵심 동작은?

Q3무거운 훅을 쓸 때 권장 사항은?