AX Labs
← 블로그 에이전트 제품 설계

품질 게이트는 프롬프트가 아니라 hooks다

Claude Code 운영은 모델 성능보다 실행 직전 통제가 먼저다

리포지토리에 Claude Code를 붙이면 초반엔 다들 비슷한 장면을 본다. 수정 속도는 빨라졌는데, 커밋 직전부터 사람이 다시 붙는다. lint가 깨지고, 테스트 범위가 들쭉날쭉하고, 금지 파일이 건드려졌는지 불안해서 git diff를 다시 훑는다. 문제는 모델이 코드를 못 짜서가 아니다. 실행 직전 통제가 없어서다.

많은 팀이 이 구간을 프롬프트로 해결하려 든다. “항상 테스트를 돌려라”, “민감 파일은 수정하지 마라” 같은 지시를 길게 적는다. 현장에서는 오래 못 간다. 세션이 바뀌면 잊히고, 컨텍스트가 압축되면 약해지고, 사람마다 다르게 쓴다. 반면 Claude Code hooks는 도구 실행 전후와 세션 이벤트에 맞춰 명령을 걸 수 있고, 설정 파일 단위로 팀에 공유된다. Anthropic 공식 문서는 hooks를 settings.json의 공식 설정 메커니즘 안에서 관리하며, PreToolUsePostToolUse 같은 이벤트에 명령을 연결하도록 안내한다. https://code.claude.com/docs/en/hooks, https://docs.anthropic.com/en/docs/claude-code/settings

커밋 전 품질은 AI에게 부탁하는 항목이 아니라, 실패하면 멈추는 운영 규칙이어야 한다.

커밋 전 품질 게이트는 리뷰 체크리스트의 자동화가 아니다

현장에서 필요한 게이트는 화려한 평가 체계가 아니다. 커밋 전에 반드시 걸러야 할 실패를 짧게 고정하는 일이다. Claude Code hooks의 핵심은 여기 있다. PreToolUse에서 막고, PostToolUse에서 정리하고, 필요하면 SessionStart에서 규칙을 다시 주입한다. 공식 문서에 따르면 hooks는 도구 패턴별 matcher를 지원하고, 여러 hook를 병렬로 실행하며, 동일 명령은 deduplicate된다. 또 정책 강제는 일반적인 exit 1이 아니라 exit 2로 설계해야 실제로 동작이 차단된다. https://code.claude.com/docs/en/hooks, https://code.claude.com/docs/en/hooks-guide

이 차이는 크다. 많은 팀이 쉘 스크립트를 붙여놓고 “실패하면 막히겠지”라고 생각하지만, Claude Code hooks에서는 관성대로 exit 1을 쓰면 비차단 에러로 처리될 수 있다. 운영 규칙을 만들었는데 실제로는 통과시키는 셈이다. 이건 모델 문제가 아니라 하네스 설계 실패다.

구분 프롬프트 중심 운영 hooks 중심 운영
규칙 위치 대화 안쪽 설정 파일과 스크립트
일관성 세션마다 흔들림 프로젝트 단위로 공유 가능
강제력 모델 순응에 의존 exit 2로 차단 가능
감사 가능성 대화 로그 의존 스크립트와 설정 diff로 추적
확장성 사람별 편차 큼 repo 표준으로 복제 가능

이 주제는 에이전트 설계의 본질과도 맞닿아 있다. 최근 표준 흐름은 모델을 더 똑똑하게 만드는 것보다, 도구 호출과 컨텍스트 주입을 더 엄격하게 설계하는 쪽으로 이동했다. MCP는 외부 도구와 데이터 연결의 표준 인터페이스를 정의하고 있고, OpenAI도 Responses API에서 원격 MCP 서버 지원과 구조화된 출력을 강화했다. 시장의 방향은 같다. 에이전트의 품질은 모델 단품이 아니라 orchestration과 guardrail에서 결정된다. https://modelcontextprotocol.io/specification/, https://openai.com/index/new-tools-and-features-in-the-responses-api/

좋은 게이트는 세 가지만 막고, 나머지는 흘려보낸다

커밋 전 게이트를 설계할 때 실패하는 팀의 공통점은 욕심이다. 보안, 아키텍처, 스타일, 테스트, 문서, 커버리지, 커밋 메시지까지 한 번에 다 걸려고 한다. 그러면 개발자는 우회하고, hook는 꺼진다. Anthropic도 settings에서 disableAllHooks를 제공한다. 즉, 과도한 규칙은 기술 문제가 아니라 운영 저항을 만든다. https://docs.anthropic.com/en/docs/claude-code/settings

실무에서는 세 가지만 먼저 고정하면 된다.

  • 금지 파일 수정 차단: .env, 배포 설정, 인증 키 저장 경로 같은 영역은 PreToolUse에서 막는다.
  • 최소 검증 강제: git diff --cached 기준으로 관련 테스트나 lint를 돌리고, 실패 시 커밋을 멈춘다.
  • 포맷 정리 자동화: 사람이 고치지 말고 PostToolUse에서 formatter를 태운다.

Claude Code 공식 가이드는 보호 파일 차단, 편집 후 자동 포맷, 세션 시작 시 컨텍스트 재주입 같은 패턴을 예제로 직접 제시한다. 중요한 점은 이 예제들이 모두 “더 잘 쓰게 돕는 기능”이 아니라 “실수를 운영에서 제거하는 기능”이라는 것이다. https://code.claude.com/docs/en/hooks-guide

여기에 커밋 전 품질 게이트를 얹는 가장 실용적인 방식은 .claude/settings.json에는 이벤트와 호출 경로만 두고, 실제 판단은 .claude/hooks/ 아래의 스크립트로 분리하는 것이다. 그래야 규칙을 diff로 리뷰할 수 있고, 팀 표준으로 재사용할 수 있다. 예를 들면 PreToolUse에서 Bash 또는 Edit|Write 직전에 검증 스크립트를 부르고, 스크립트 안에서 staged file 패턴, 테스트 범위, 금지 경로를 함께 판단한다.

hooks를 붙였다고 품질 게이트가 되지는 않는다

많은 조직이 여기서 한 번 더 미끄러진다. hook를 달았는데도 결국 사람 리뷰가 줄지 않는다. 이유는 두 가지다.

첫째, 게이트 결과가 구조화돼 있지 않다. 성공/실패만 찍으면 Claude도 사람도 다음 행동을 정하기 어렵다. 둘째, 차단 조건과 안내 문구가 섞여 있다. 실제 운영에서는 “무엇 때문에 막혔는지”, “어떻게 풀 수 있는지”가 분리되어야 한다. 이 지점에서 구조화된 출력이 중요해진다. OpenAI의 Structured Outputs는 모델 출력이 JSON Schema를 따르도록 강제하는 기능을 공식화했고, 이런 흐름은 에이전트 하네스 전반의 기준이 됐다. 게이트 스크립트도 같은 원리로 설계해야 한다. 사람 친화적 문장 하나보다, 기계가 읽을 수 있는 판정 결과가 우선이다. https://platform.openai.com/docs/guides/structured-outputs?lang=javascript, https://openai.com/index/introducing-structured-outputs-in-the-api/

권장하는 출력 구조는 단순하다.

  • status: pass | fail
  • reason: 차단 사유의 짧은 코드
  • next_action: 개발자가 취할 다음 조치
  • evidence: 실패 파일, 테스트 이름, 명령 결과 요약

이렇게 만들면 Claude Code 내부 hook, CI, PR bot, 대시보드가 같은 판정 구조를 재사용할 수 있다. 같은 규칙을 터미널에서 한 번, CI에서 또 한 번, 리뷰 코멘트에서 세 번째로 다시 쓰지 않아도 된다. 이게 AX Ops에서 말하는 운영 단일화다. 규칙은 문서가 아니라 실행 경로에 박아야 한다.

커밋 전 게이트의 목표는 완벽이 아니라 운영비 절감이다

품질 게이트를 두면 처음에는 답답하다는 반응이 나온다. 맞다. 하지만 그 답답함의 정체를 봐야 한다. 사람의 암묵지를 repo 안의 명시 규칙으로 바꾸는 과정에서 생기는 마찰이다. 이걸 지나야 리뷰어가 같은 말을 반복하지 않고, 팀장이 “이번엔 왜 그냥 머지됐냐”를 묻지 않게 된다.

Claude Code hooks는 그 전환의 출발점으로 적합하다. 프로젝트 설정 파일에 공유할 수 있고, 도구 실행 시점에 개입할 수 있고, 차단과 자동수정을 분리할 수 있다. 2025년 10월에는 Anthropic이 plugins를 발표하면서 slash commands, agents, MCP servers, hooks를 하나의 배포 단위로 묶을 수 있게 했다. 이제 hook는 개인의 터미널 요령이 아니라 팀 배포 자산으로 다뤄야 한다. https://claude.com/blog/claude-code-plugins

정리하면, 커밋 전 품질 게이트의 질문은 “Claude가 얼마나 똑똑한가”가 아니다. “우리 팀은 어디에서 반드시 멈추게 할 것인가”다. 이 질문에 답하지 못하면 AI 코딩은 빨라져도 운영은 더 비싸진다. 답을 정했다면, 이제 프롬프트가 아니라 hook로 옮겨야 한다. AX Ops 방법론 →

참고