Claude Code Workshop

하네스 엔지니어링

프롬프트는 부탁이고, Hook은 시스템이다.
Claude Code Hook으로 워크플로를 강제하는 법.

하네스 엔지니어링 — 워크플로 게이트 일러스트
01 — 핵심 개념

부탁 vs 강제,
무엇이 다른가?

프롬프트 엔지니어링은 에이전트에게 "이렇게 해줘"라고 부탁하는 것이고, 하네스 엔지니어링은 규칙을 어기면 도구 자체가 실행되지 않도록 만드는 것입니다.

Soft vs Hard Guardrail 비교
📋
Soft Guardrail

프롬프트 엔지니어링

CLAUDE.md에 "초안 전에 아웃라인을 먼저 작성하세요"라고 지침을 남깁니다. 대부분 따르지만, 맥락이 길어지거나 사용자가 재촉하면 무시될 수 있습니다.

비유: "출입증을 꼭 패용하세요" 공지문
🔒
Hard Guardrail

하네스 엔지니어링

Hook 스크립트가 outline.md 존재 여부를 검사합니다. 없으면 exit 2를 반환하여 Write 도구 자체를 물리적으로 차단합니다.

비유: 출입증 없으면 문이 안 열리는 시스템
02 — 실습 시나리오

책 챕터 작성에
워크플로 강제 걸기

"아웃라인 없이 초안 작성 불가"라는 규칙을 Hook으로 구현합니다. Claude가 아무리 시도해도, outline.md가 없으면 draft.md를 쓸 수 없습니다.

프로젝트 구조
각 챕터 폴더에 outline.md가 있어야 draft.md를 작성할 수 있습니다.
book/
  ch01/
    outline.md ← 이게 있어야
    draft.md ← 이걸 쓸 수 있음
  ch02/
    outline.md
  ch03/
    (아직 비어있음)
  .claude/
    settings.json
    hooks/
      require-outline.sh
03 — Hook 코드

규칙을 코드로 만들기

require-outline.sh
#!/bin/bash

# stdin으로 들어오는 JSON 파싱
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // ""')

# draft.md 작성 시도를 감지
if [[ ("$TOOL_NAME" == "Write" || \
      "$TOOL_NAME" == "Edit") && \
     "$FILE_PATH" == *"/draft.md" ]]; then

  # 같은 폴더에서 outline.md 확인
  CHAPTER_DIR=$(dirname "$FILE_PATH")
  OUTLINE="$CHAPTER_DIR/outline.md"

  if [[ ! -f "$OUTLINE" ]]; then
    echo "⛔ outline.md가 없습니다."
    echo "   아웃라인을 먼저 작성해주세요."
    exit 2  # ← 도구 실행 차단!
  fi
fi

exit 0  # ← 통과
settings.json — Hook 등록
.claude/settings.json
{
  "PreToolUse": [
    {
      "matcher": "Write|Edit",
      "hooks": [
        {
          "type": "command",
          "command": "bash .claude/hooks/require-outline.sh"
        }
      ]
    }
  ]
}
03-B — 프롬프트형 Hook

문체 윤문도
Hook으로 강제할 수 있다

아웃라인 검사는 "파일이 있냐 없냐"라서 bash로 충분했지만, 문법 교정이나 문체 일관성은 자연어 판단이 필요합니다. 이럴 때 prompt 타입 Hook을 쓰면 됩니다.

⚙️
Command Hook

결정론적 검사

파일 존재 여부, 줄 수 확인, 패턴 매칭 등.
bash 스크립트로 빠르게 판단.

예: outline.md 없으면 차단
🧠
Prompt Hook

LLM 기반 판단

문체 일관성, 맞춤법, 톤 검수 등.
자연어 추론이 필요한 품질 검사.

예: "~합니다" 문어체 → 구어체로 교정
시나리오: 초안 작성 후 문체 자동 검수
Claude가 draft.md를 작성하면, PostToolUse Hook이 자동으로 문체를 검수합니다. 딱딱한 문어체, "콜론+목록" 패턴, AI 냄새 나는 표현이 감지되면 Claude에게 피드백을 보내 스스로 수정하게 만듭니다.
.claude/settings.json
{
  "PostToolUse": [
    {
      "matcher": "Write|Edit",
      "hooks": [
        {
          "type": "prompt",
          "prompt": "방금 작성된 파일이 draft.md라면,
다음 문체 규칙을 위반했는지 검사하세요:

1. '~합니다/~됩니다'만 반복하는 딱딱한 문어체 금지
   → '~거든요', '~더라고요', '~예요' 같은 구어체 사용
2. 'XXX의 장점:' 뒤에 불릿 리스트 나열 금지
   → 자연어로 흐름을 이어갈 것
3. '또한', '뿐만 아니라', '이를 통해' 같은 AI 표현 금지

위반이 있으면 구체적 위치와 수정 제안을 반환하세요.
위반이 없으면 'approve'를 반환하세요."
        }
      ]
    }
  ]
}
Terminal — 문체 검수 Hook 작동
AI
ch03/draft.md 초안을 작성했습니다.
✅ Write → ch03/draft.md (통과 — 아웃라인 확인됨)
🧠
PostToolUse 문체 검수 결과:

⚠️ 3건 감지
• 2번째 문단: "이를 통해 성능이 향상됩니다"
  → "이렇게 하면 성능이 확 좋아지거든요"
• 4번째 문단: "MCP의 장점:" + 불릿 나열
  → 자연어로 풀어서 설명할 것
• 전반적 톤: "~됩니다" 12회 반복
  → 구어체 비율 높일 것
AI
문체 피드백을 반영하여 수정하겠습니다.
문어체를 구어체로, 목록을 자연어로 풀어서 다시 작성합니다.

Command vs Prompt — 언제 뭘 쓸까?

COMMAND

파일 존재 확인, 줄 수 제한, 금지 패턴 grep,
린트 실행, 테스트 통과 여부

PROMPT

문체 검수, 코드 리뷰, 보안 취약점 분석,
비즈니스 로직 검증, 완성도 판단

04 — Exit Code 규칙

세 가지 신호만 기억하세요

exit 0
통과
검사 OK.
도구 실행을 허용합니다.
exit 2
차단
규칙 위반 감지.
도구 실행을 물리적으로 막습니다.
echo
피드백
차단 시 출력한 메시지가
Claude에게 전달됩니다.
05 — 동작 흐름

Hook이 작동하는 순간

사용자 요청
"ch03 초안 작성해줘"
Claude 시도
Write → ch03/draft.md
PreToolUse Hook
outline.md 존재 여부 검사
없음 → exit 2
차단 + 피드백
"아웃라인부터 작성하겠습니다"
있음 → exit 0
통과
"초안 작성을 시작합니다"
06 — 실제 대화

Claude는 어떻게 반응할까?

Hook이 차단하면 Claude는 피드백 메시지를 읽고 스스로 우회 경로를 찾습니다.

Terminal — Claude Code
👤
ch03 드래프트 써줘. 주제는 MCP 서버 구축이야.
AI
ch03/draft.md를 작성하겠습니다.
Hook: outline.md가 없습니다.
아웃라인을 먼저 작성해주세요.
AI
ch03에 아웃라인이 없네요.
먼저 outline.md를 작성하겠습니다.
✅ Write → ch03/outline.md (통과!)
AI
아웃라인 완료. 이제 초안을 작성합니다.
✅ Write → ch03/draft.md (통과!)

outline.md는 draft.md가 아니므로 Hook에 걸리지 않아 자유롭게 생성됩니다.

07 — 자연어로 만들기

코드가 어려우면?
자연어로 Hook을 만들 수 있다

bash 스크립트나 settings.json 문법이 낯설어도 걱정 없습니다. Claude Code에게 자연어로 Hook을 설계해달라고 요청하면 됩니다.

예시 프롬프트 — Command Hook 생성
👤
Claude Code의 PreToolUse Hook을 만들어줘.
Write나 Edit 도구로 draft.md를 작성하려고 할 때,
같은 폴더에 outline.md가 없으면 차단하는
bash 스크립트와 settings.json 설정을 같이 생성해줘.
AI
require-outline.sh 스크립트와
settings.json 설정을 생성하겠습니다.
예시 프롬프트 — Prompt Hook 생성
👤
PostToolUse Hook을 만들어줘.
draft.md 파일을 작성한 뒤에 문체를 자동 검수하는
prompt 타입 Hook이야. 딱딱한 문어체, 콜론+목록 패턴,
AI 냄새 나는 표현을 감지해서 피드백을 주는
프롬프트를 작성해줘.
AI
PostToolUse prompt Hook을 생성하겠습니다.
문체 규칙 3가지를 검수하는 프롬프트를 작성합니다.
핵심 포인트

"어떤 상황에서, 어떤 도구를, 어떤 조건으로 차단/검수할지"만 자연어로 설명하면 됩니다.
Hook의 문법은 Claude가 알아서 처리합니다. 코드를 외울 필요가 없어요.

핵심 요약

프롬프트 엔지니어링이 "교육"이라면, 하네스 엔지니어링은 "시스템"입니다.
프롬프트는 확률적으로 대부분 따르지만, Hook은 결정론적으로 100% 강제합니다.
그리고 단순히 막는 것이 아니라, 피드백 메시지로 Claude를 올바른 방향으로 유도합니다.

CLAUDE.md + Hook = 왜(Why) + 강제(How)