slowlp
← 블로그
방법 2026.06.11 · 5분 읽기

에이전트가 내 말을 안 듣는다면

Claude Code의 CLAUDE.md·스킬·커맨드·훅, 4가지 컨트롤 레버의 신뢰도 차이와 고르는 기준

방법

”btw 명령어 정확히 뭐임?”

시작은 이 질문이었습니다. Claude Code의 /btw가 정확히 뭐 하는 건지 궁금해서 물어본 건데, 30분 뒤에 대화는 훅까지 가 있었어요. 커맨드가 뭔지, 스킬이랑 뭐가 다른지, CLAUDE.md랑은 또 뭐가 다른지, 그럼 훅은 뭔지. 하나 물어보면 옆 개념이 궁금해지는 식으로 꼬리를 물었습니다.

그 중간에 제 오래된 문제가 하나 껴 있었습니다. 저는 그때까지 스킬을 안 쓰고 있었거든요. 규칙이든 절차든 전부 CLAUDE.md 컨벤션으로 처리해왔고, 그래서 이렇게 물었습니다.

“내가 스킬 안 쓰고 여지껏 컨벤션으로 다 처리했는데 누락이 좀 있긴 했거든. 스킬은 누락이 좀 덜한가?”

이 질문의 답이 이 글의 전부입니다. 누락은 모델 탓이 아니라 레버를 잘못 고른 탓이었습니다.

축은 하나, 언제 로드되냐

넷 다 .md 파일이거나 설정 파일이라 헷갈리는데, 정리하는 축은 하나였습니다. 언제 컨텍스트에 로드되냐.

  • CLAUDE.md는 항상. 매 세션, 매 메시지마다 읽힙니다.
  • 스킬은 작업이 매칭될 때만. 평소엔 description 한 줄만 떠 있고 본문은 발동 시점에 로드됩니다.
  • 커맨드는 제가 /이름을 칠 때만.
  • 훅은 아예 다른 층입니다. 모델이 읽는 게 아니라, 툴 호출 주변에서 쉘 명령이 그냥 실행됩니다.

로드 타이밍이 다르면 토큰 비용이 다르고 신뢰도도 다릅니다. 이걸 모른 채 죄다 CLAUDE.md에 넣으면 어떻게 되는지가 제 케이스였고요.

레버 1: CLAUDE.md

CLAUDE.md에 쓴 글자는 전부 세션 내내 매 요청 비용에 얹힙니다. 항상 떠 있으니까 항상 지켜질 거라고 생각하기 쉬운데, 실제로는 반대에 가까웠습니다. 파일이 길어질수록 모델의 attention이 늘어난 컨텍스트 전체에 퍼지면서 개별 규칙이 우선순위에서 밀려납니다. “있긴 한데 무시됨”. 제 누락의 원인이 이거였습니다. 과적재.

판단 기준으로 받은 질문이 하나 있습니다. “이 내용을 매 메시지마다 들고 다닐 가치가 있나?” 패키지 매니저 설정, 코드 스타일, 상시 적용 규칙 정도만 남기고 나머지는 다른 레버로 빼는 게 맞습니다.

레버 2: 스킬

스킬은 .claude/skills/이름/SKILL.md 구조로 만듭니다. 발동 전까지는 description 한 줄만 떠 있어서 비용이 거의 없습니다. 무거운 절차를 CLAUDE.md에서 스킬로 빼면 이득이 두 번 생깁니다. 뺀 절차는 발동되는 그 순간 작업 바로 옆에 새로 주입되니까 또렷하게 지켜지고, 남은 CLAUDE.md 규칙들도 희석이 줄어서 준수율이 올라갑니다.

대신 누락의 성격이 바뀝니다. CLAUDE.md는 희석돼도 적어도 떠 있긴 한데, 스킬은 description이 작업과 매칭이 안 되면 통째로 안 나옵니다. “들쭉날쭉 적용됨”에서 “아예 안 터짐”으로 바뀌는 거라 공짜가 아니에요. 그래서 description 품질이 곧 누락률입니다. “주식 관련”처럼 뭉뚱그리면 발동이 들쭉날쭉해지고, “P&L 계산이나 손익 관련 로직을 작성·수정할 때”처럼 써야 필요할 때 꺼내집니다.

레버 3: 커맨드

커맨드는 수동입니다. /이름을 직접 쳐야 발동하고, 모델 판단이 안 끼니까 신뢰도는 100%입니다.

대화 중에 “리뷰는 프롬프트로 봐달라는 거랑 뭐가 달라?”라고 물었는데, 답이 정직했습니다. 까놓고 보면 잘 만들어진 프롬프트고, 품질 좋은 리뷰 프롬프트를 직접 매번 똑같이 칠 수 있으면 거의 차이가 없다고요. 커맨드의 가치는 그 잘 짠 프롬프트를 한 단어로, 일관되게, 버전관리되는 형태로 쓴다는 데 있습니다.

그래서 자리가 명확합니다. 스킬로 만들기 전에 프로세스를 테스트하는 중간 단계, 그리고 자동 발동이 오히려 방해되는 작업. “지금 이거 해”라고 의도적으로 거는 것들이요.

레버 4: 훅

여기서 제가 물은 게 “훅은 머지~ ㅋㅋㅋ”였습니다. 답은 앞의 셋과 층이 달랐어요. 훅은 프롬프트가 아니라 쉘 명령어입니다. 모델이 “할지 말지” 판단하는 과정 자체가 없고, 툴 호출 주변 이벤트에서 결정론적으로 실행됩니다. 모델이 까먹을 수도, 대화가 길어졌다고 건너뛸 수도 없습니다.

settings.jsonhooks 키 아래에 이벤트, matcher, 핸들러 3단으로 정의하고, 핵심 메커니즘은 exit code입니다.

  • PreToolUse: 툴 실행 전 가로채기. exit 2면 차단, 0이면 허용. rm -rfDROP TABLE 같은 위험 명령을 모델이 판단하기도 전에 막는 용도.
  • PostToolUse: 툴 실행 후 뒷정리. 파일 수정할 때마다 자동 포맷 거는 것 같은 거.
  • Stop: Claude가 끝내려 할 때 게이트. npm test || exit 2를 걸어두면 테스트가 실패하는 한 못 끝냅니다.

자주 까먹는 절차는 스킬로, 한 번도 빠지면 안 되는 건 훅으로. 이렇게 나누면 누락 고민이 거의 잡힙니다. 다만 훅은 제 머신에서 진짜 쉘 명령이 도는 거라, 잘못 짜면 워크플로를 막아버리거나 조용히 실패합니다. 만들어달라고 하면 Claude가 다 짜주긴 하는데, 이건 꼭 한 번 실제로 터뜨려서 의도대로 도는지 확인해야 합니다.

판단 트리

상황레버
자주 쓰고 + 자동 발동 필수스킬
가끔 + best-effort면 충분CLAUDE.md 포인터 (한 줄 + 파일 경로)
드물게 + 그 순간만 확실하게그때그때 @파일명 직접 멘션
절대 빠지면 안 되는 것

외울 건 이 표가 아니라 질문 세 개입니다. 이 행동은 항상 필요한가, 자동으로 떠야 하나, 절대 빠지면 안 되나. 이것만 구분되면 레버 선택은 거의 자동으로 따라오고, 나머지 문법은 그때그때 찾아 쓰면 됩니다.

그 대화의 마지막 질문

30분쯤 지나서 새 주제로 넘어가고 싶어졌습니다. 그래서 물었어요. “이 정도면 컨텍스트 어느 정도야? 옮기는 게 나을까?” 답은 새 챗으로 옮기라는 거였는데, 이유가 방금 배운 그대로였습니다. 안 옮기면 이 커맨드·훅 얘기가 새 주제의 매 메시지마다 따라붙어서 토큰도 새고 attention도 희석된다고요. CLAUDE.md 과적재랑 같은 원리입니다.

배운 걸 써먹는 데 1분도 안 걸렸네요. “ㅇㅇ 안녕~ 나중에 만나” 하고 대화를 옮겼습니다.

댓글