-
Claude Code 스킬과 훅 — AI 코딩 도구에 왜 통제 체계가 필요한가IT 2026. 4. 22. 21:00
AI 코딩 도구를 쓰다 보면 처음엔 단순한 질문-답변으로 시작한다. "이 코드 리팩토링해줘", "테스트 짜줘". 그런데 어느 순간부터 반복되는 패턴이 보이기 시작한다. 매번 같은 맥락을 설명하고, 같은 절차를 지시하고, 같은 실수를 교정한다.
Claude Code를 본격적으로 쓰면서 이 문제를 해결하기 위해 스킬(Skill)과 훅(Hook) 시스템을 만들었고, 11개 스킬과 8개 파이프라인 검증 체계로 성장했다. 이 글은 그 과정에서 깨달은 것들을 정리한다.
1. 스킬이 왜 필요한가 — 반복 지시의 제거
Claude Code에게 "일정 노트를 동기화해줘"라고 말하면 이 한 문장 뒤에는 실제로 수십 줄의 절차가 숨어 있다.
- Google Calendar API로 이벤트를 가져온다
- 관련 참고 자료를 시간대 기준으로 매칭한다
- 외부 AI에 프롬프트를 보내 노트를 구조화한다
- RAG 시스템에서 관련 지식을 검색해 주입한다
- @AI 질문에 답변을 생성한다
- git commit & push 후 텔레그램으로 알린다
이 절차를 매번 말로 지시하면 두 가지 문제가 생긴다. 첫째, 빠뜨림. "참고 자료 연결은 했어?" "텔레그램 알림은?" 매번 체크리스트를 머릿속에 들고 있어야 한다. 둘째, 변종. 어제는 이렇게 했는데 오늘은 저렇게 하면 결과물 품질이 들쭉날쭉해진다.
스킬은 이 문제를 해결한다. 한 번 정의하면, 트리거 키워드로 전체 절차가 로딩된다. "데이터 동기화"라고 말하면 Claude Code가 6단계 파이프라인 전체를 알고 있는 상태에서 작업을 시작한다.
스킬의 본질: 도메인 지식의 코드화
스킬 파일(SKILL.md)은 프로그래밍 코드가 아니라 마크다운으로 작성된 절차서다. 어떤 명령을 실행하고, 어떤 순서로 진행하고, 어떤 조건에서 분기하는지가 자연어로 기술되어 있다. Claude Code는 이 문서를 읽고 맥락을 이해한 상태에서 작업한다.
스킬이 어떤 식으로 쓰이는지 감을 잡기 위해, 전형적인 유형별 예시를 들어보겠다:
유형 예시 하는 일 데이터 동기화 외부 서비스 → 로컬 노트 API로 데이터를 가져와 마크다운 노트로 변환, 관련 자료 연결, AI 후처리 콘텐츠 생성 노트 → 블로그 발행 원본 노트를 HTML로 변환, RAG로 지식 보강, 플랫폼에 자동 발행 코드 품질 TDD 강제 워크플로우 코드 변경 감지 → 테스트 작성 → 통과 확인 → 커밋 허용 외부 연동 GitHub 이슈/PR 관리 메신저에서 명령 → GitHub API 호출 → 결과 보고 미디어 관리 사진 정리/분석 저장장치 스캔 → 중복 탐지 → AI 분석 → 라이브러리 구성 이런 스킬이 하나둘 쌓이면 금방 10개 이상이 된다. 도메인이 다양해도 패턴은 비슷하다: 외부 데이터 수집 → 변환/처리 → 산출물 생성 → 저장/배포.
2. 훅이 왜 필요한가 — "했다고 했는데 안 한" 문제
스킬만으로는 부족한 지점이 있다. 스킬은 "무엇을 해야 하는지"를 알려주지만, "실제로 했는지"는 보장하지 않는다.
실제로 겪은 상황이 이렇다. 데이터 동기화를 요청했는데, Claude Code가 Step 1(데이터 수집)과 Step 2(참고 자료 연결)는 했지만 Step 3(AI 콘텐츠 통합)을 건너뛰고 바로 git commit을 시도했다. 결과물은 원본 데이터가 그대로 복사된 미정리 노트였다.
또 다른 사례: 블로그 드래프트를 생성했는데 본문이 마크다운으로 작성되어 있었다. 블로그 publisher가 HTML을 에디터에 직접 주입하는 구조였는데, 마크다운 텍스트가 그대로 노출됐다.
이런 문제를 잡으려면 자동화된 검증 계층이 필요하다. 이것이 훅(Hook)이다.
훅의 동작 원리
Claude Code의 훅 시스템은 4개 시점에 개입할 수 있다:
시점 역할 활용 예시 PostToolUse 도구 실행 후 상태 추적 동기화 단계 마킹, 콘텐츠 생성 감지 PreToolUse 도구 실행 전 차단 미완료 파이프라인에서 git commit 차단 PostToolUse(Edit) 파일 편집 감지 노트 편집 시 리뷰 상태 생성, 프로젝트 코드 변경 감지 Stop 세션 종료 전 검증 파이프라인 미완료 시 종료 차단 훅 스크립트는 exit code로 의사를 전달한다.
0이면 통과,2면 차단. 차단 시 stderr에 이유를 출력하면 Claude Code가 그 메시지를 받아 자기 교정한다.3. 디스패처가 왜 필요한가 — 스킬 확장의 필연적 귀결
처음에는 데이터 동기화 스킬 하나에만 훅이 걸려 있었다. 4개 파일로 충분했다.
그런데 스킬이 10개 이상으로 늘어나자 문제가 생겼다. 스킬마다 별도 훅 스크립트를 만들면 settings.json의 같은 matcher에 여러 훅이 등록되고, 매 도구 호출마다 모든 훅이 실행된다.
ls -la같은 단순 명령에도 10개 스크립트가 돌아간다면 성능 저하가 심각하다.해법은 통합 디스패처(Unified Dispatcher)다.
hooks/ common.py ← 공통 유틸 (세션 PID, 상태 관리) dispatcher_post_bash.py ← Bash 명령 후 전체 파이프라인 분기 dispatcher_pre_bash.py ← git commit 전 검증 dispatcher_post_edit.py ← 파일 편집 감지 dispatcher_stop.py ← 종료 전 전체 검증 pipelines/ data_sync.py ← 다단계 동기화 파이프라인 추적 data_review.py ← 노트 편집/AI 답변 검증 content_publish.py ← 콘텐츠 발행 품질 검증 code_quality.py ← TDD 강제 (테스트 통과 필수) report_pipeline.py ← 리포트 산출물 확인 media_manager.py ← 미디어 관리 커맨드 추적 ...디스패처는 하나의 진입점으로 모든 파이프라인을 처리한다. 핵심은 상태 파일(
/tmp/.{pipeline}_state) 유무로 O(1) 분기하는 것이다. 활성 파이프라인이 없으면 즉시 종료(exit 0)하므로, 일반 명령에 대한 오버헤드가 거의 없다.통합 인터페이스
모든 파이프라인 모듈은 동일한 4개 함수를 구현한다:
def track_bash(cmd, data) → bool # Bash 명령 추적 def track_edit(file_path, data) → bool # 파일 편집 추적 def pre_commit(cmd, data) → (bool, str) # 커밋 전 검증 def check_completion(state) → list[str] # 종료 전 완료 확인이 인터페이스 덕분에 새 스킬을 추가할 때
pipelines/에 모듈 하나만 만들면 된다. settings.json은 건드릴 필요가 없다.4. Harness Engineering의 실전 적용
이 구조를 Harness Engineering 관점에서 보면, 정확히 Control Plane을 구축한 것이다.
Harness 구성 요소 실제 구현 Hook / Guardrail 4개 디스패처 (PreToolUse, PostToolUse, Stop) 피드백 루프 상태 파일 기반 단계 추적 + additionalContext 주입 HITL Policy pre_commit에서 미완료 단계 차단 → Claude가 자기 교정 Governance 세션 PID 격리 (병렬 세션 간 간섭 방지) Martin Fowler가 쓴 Harness Engineering 글의 핵심 메시지는 이것이다: "모델을 바꾸기 전에 Harness를 바꿔라." 같은 Claude 모델이라도 스킬과 훅이 잘 설계되어 있으면 극적으로 다른 결과를 낸다.
5. 실전에서 배운 것들
노트 품질 감별이 핵심이다
데이터 동기화에서 가장 중요한 검증은 "노트가 실제로 정리되었는가"였다. 단순히 "Step 3을 실행했는가"가 아니라, 산출물 자체를 검사해야 한다.
구현한 감별 기준은 단순하다:
- 본문이 200자 이상인데
##섹션이 1개 이하이고Organized by마커가 없으면 → 미정리 @AI태그가 있는데> [!ai]응답이 없으면 → 미응답
이 두 조건만으로 "원본 데이터를 그대로 복사해서 커밋한" 케이스를 정확히 잡아낸다.
스킬마다 검증 강도가 다르다
모든 스킬에 동일한 수준의 검증을 걸면 과도하다. 실제로 운영하면서 3단계로 분류했다:
강도 검증 방식 스킬 예시 강함 파이프라인 추적 + 커밋 차단 + 종료 차단 다단계 파이프라인 (예: 데이터 동기화, TDD 워크플로우) 보통 산출물 존재 확인 + 종료 시 경고 콘텐츠 생성 (예: 블로그 발행, 리포트 생성) 약함 실행 기록만 (차단 없음) 외부 API 연동 (결과가 즉시 확인되는 경우) 세션 격리가 중요하다
여러 터미널에서 Claude Code를 동시에 쓸 때, 한쪽의 파이프라인 상태가 다른 쪽을 차단하면 안 된다.
_find_claude_pid()로 프로세스 트리를 거슬러 올라가 각 세션의 claude 메인 PID를 추적하고, 상태 파일에 기록된 PID와 비교해서 다른 세션이면 무시한다.마무리
처음에는 스킬 하나, 훅 없이 시작했다. 스킬이 늘어나자 빠뜨림이 생겼고, 훅을 넣었다. 훅이 늘어나자 성능 문제가 생겼고, 디스패처를 만들었다. 디스패처가 생기자 공통 유틸이 필요했고, 인터페이스를 통일했다.
이 진화 과정은 필연적이었다. AI 코딩 도구의 생산성은 프롬프트를 잘 쓰는 것만으로는 한계가 있다. 절차를 코드화(스킬)하고, 실행을 검증(훅)하고, 검증을 확장 가능하게 구조화(디스패처)하는 — 이 세 단계를 거쳐야 비로소 AI를 실무 파이프라인에 올릴 수 있다.
Harness Engineering이라는 거창한 이름을 붙이지 않더라도, 실무에서 AI 도구를 심도 있게 활용하는 사람이라면 자연스럽게 이 방향으로 흘러갈 수밖에 없다. 왜냐하면 AI는 강력하지만 비결정적이기 때문이다. 그 비결정성을 프로덕션 수준으로 길들이려면, 결국 마구(Harness)가 필요하다.
이 글은 생성형 AI의 도움을 받아 작성되었습니다. 원본 자료를 기반으로 AI가 초안을 생성하고, 작성자가 검토·편집하였습니다.
'IT' 카테고리의 다른 글
Claude Code settings.json vs settings.local.json — 왜 둘로 나뉘었나 (0) 2026.04.23 AI 에이전트가 뭘 했는지 추적하기 — 경량 감사 로그 구축기 (0) 2026.04.23 AI 코딩 에이전트의 권한 관리 — 화이트리스트에서 블랙리스트로 전환한 이유 (0) 2026.04.22 코딩 에이전트는 README.md를 읽을까? — 2026년 4월 실측 현황 (0) 2026.04.22 Context Engineering — AI 코딩 에이전트에 맥락을 주입하는 우선순위 체계 (0) 2026.04.22 텔레그램으로 GitHub 이슈 관리 자동화하기 (1) 2026.04.21 6개월 만에 4세대, 智谱AI GLM 모델 패밀리 완전 정리 (1) 2026.04.20 Google One 해지와 클라우드 탈출기 — 구글에 남긴 건 메일과 캘린더뿐 (1) 2026.04.19 Microsoft 365 구독 해지와 AI 마이그레이션 — 556GB를 구출한 일주일 (0) 2026.04.19 ChatGPT 유료 구독 취소 후 달라진 3가지 (0) 2026.04.19