한 줄 요약: 비동기 훅(Async Hook)이란, 이벤트 발생 시 핸들러를 메인 실행 흐름과 독립적으로 비동기로 실행해, 메인 작업의 성능에 영향 없이 부가 처리(로깅, 알림, 분석)를 수행하는 훅 패턴이다.


1. 비동기 훅이란 무엇인가?

주문을 받고 음식을 만드는 동안 영수증을 프린트하는 레스토랑을 생각해 보세요. 요리사는 영수증이 출력될 때까지 기다리지 않습니다. 영수증 출력은 별도로 진행되고, 요리사는 음식 만들기에 집중합니다. 이것이 비동기 훅의 본질입니다.

동기 훅 vs 비동기 훅:

[동기 훅]
이벤트 → 훅 실행(3초 대기) → 메인 작업 계속
                   ↑ 사용자가 3초 대기

[비동기 훅]
이벤트 → 메인 작업 계속 (즉시)
         └→ 훅 실행 (백그라운드, 3초 소요)

2. 핵심 개념 이해하기

비동기 훅의 실행 모델

메인 스레드:
  이벤트 발생 → 훅 등록(즉시) → 다음 작업 → ...
                        ↓
이벤트 루프:
  훅1 처리 → 훅2 처리 → 훅3 처리 (백그라운드)

Fire-and-Forget vs Awaited Async

패턴 특성 사용 시점
Fire-and-Forget 결과 무시, 완전 비동기 로그 기록, 알림 발송
Awaited Async 완료 대기하지만 병렬 실행 결과가 필요한 검증
Callback 완료 시 콜백 함수 호출 연쇄 비동기 처리

Claude Code의 비동기 훅

Claude Code에서 "background": true 설정으로 비동기 훅을 구성합니다:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "python scripts/async_analyzer.py",
            "background": true   비동기 실행
          }
        ]
      }
    ]
  }
}

3. 실무 적용 예시

Python asyncio를 활용한 비동기 훅 시스템 구현입니다.

import asyncio
import aiohttp
import logging
from datetime import datetime
from typing import Callable, Any
from dataclasses import dataclass

@dataclass
class HookEvent:
    name: str
    data: dict
    timestamp: datetime = None

    def __post_init__(self):
        if self.timestamp is None:
            self.timestamp = datetime.now()

class AsyncHookSystem:
    def __init__(self):
        self._hooks: dict[str, list[Callable]] = {}
        self._background_tasks = set()

    def register(self, event_name: str, handler: Callable):
        """훅 핸들러를 등록합니다."""
        if event_name not in self._hooks:
            self._hooks[event_name] = []
        self._hooks[event_name].append(handler)

    def fire(self, event: HookEvent):
        """이벤트를 발생시키고 훅을 비동기로 실행합니다."""
        if event.name not in self._hooks:
            return

        for handler in self._hooks[event.name]:
            # 백그라운드 태스크로 등록 (메인 흐름 차단 없음)
            task = asyncio.create_task(self._safe_run(handler, event))
            self._background_tasks.add(task)
            task.add_done_callback(self._background_tasks.discard)

    async def _safe_run(self, handler: Callable, event: HookEvent):
        """오류가 발생해도 메인 흐름에 영향 없이 실행합니다."""
        try:
            await handler(event)
        except Exception as e:
            logging.error(f"훅 오류 [{handler.__name__}]: {e}")

# 비동기 훅 핸들러 정의
async def slack_notify(event: HookEvent):
    """Slack 알림 전송 (비동기)."""
    async with aiohttp.ClientSession() as session:
        await session.post(
            "https://hooks.slack.com/services/...",
            json={"text": f"🤖 AI가 파일 변경: {event.data.get('file')}"}
        )
    print(f"[Slack] 알림 전송 완료: {event.data}")

async def analytics_track(event: HookEvent):
    """분석 이벤트 트래킹 (비동기)."""
    await asyncio.sleep(0.1)  # 분석 서버 전송 시뮬레이션
    logging.info(f"Analytics: {event.name} - {event.data}")

async def audit_log(event: HookEvent):
    """감사 로그 기록 (비동기)."""
    with open("audit.log", "a") as f:
        f.write(f"{event.timestamp.isoformat()} | {event.name} | {event.data}\n")

# 훅 시스템 초기화 및 핸들러 등록
hook_system = AsyncHookSystem()
hook_system.register("file_written", slack_notify)
hook_system.register("file_written", analytics_track)
hook_system.register("file_written", audit_log)

async def main():
    # AI가 파일을 쓰는 메인 작업
    print("파일 작성 중...")
    # ... 실제 파일 작성 로직 ...

    # 훅 발동 (비동기, 즉시 반환)
    hook_system.fire(HookEvent(
        name="file_written",
        data={"file": "output.md", "lines": 150}
    ))

    print("메인 작업 완료 (훅은 백그라운드에서 실행 중)")
    # 잠시 대기해서 백그라운드 훅이 완료되도록
    await asyncio.sleep(1)

asyncio.run(main())

4. 비동기 훅 vs 유사 개념 비교

구분 비동기 훅 동기 훅 메시지 큐
메인 흐름 차단 ❌ 차단 없음 ✅ 차단 ❌ 차단 없음
실행 보장 보통 ✅ 강함 ✅ 강함
순서 보장
구현 복잡도 중간 낮음 높음
사용 예 로그, 알림 검증, 차단 대규모 이벤트 처리

5. 마치며

비동기 훅은 사용자 경험과 시스템 무결성 사이의 균형을 맞추는 핵심 패턴입니다. 차단이 필요한 검증에는 동기 훅을, 로깅·알림·분석 같은 부가 작업에는 비동기 훅을 사용하는 것이 이상적입니다. 훅 시스템(Hook System)의 기본 개념을 이해한 후 비동기 훅을 학습하면 고성능 이벤트 기반 AI 시스템을 설계할 수 있습니다.

참고 자료

함께 읽으면 좋은 용어

이 개념과 함께 알아두면 이해가 깊어지는 관련 용어들입니다.

댓글 남기기