Claude Code 쓰다 보면 /help나 /clear 같은 기본 슬래시 명령어들은 금방 익숙해지는데,
사실 이것보다 훨씬 유용한 기능이 있습니다.
바로 명령어를 직접 만들 수 있다는 건데요, 저는 이걸 알고 나서 반복 작업이 확 줄었습니다.
아래 강의를 참고했습니다 :D
https://anthropic.skilljar.com/claude-code-in-action/303234
Claude Code in Action
Integrate Claude Code into your development workflow
anthropic.skilljar.com
폴더 구조부터 잡기
방법 자체는 단순합니다.
프로젝트 루트에 있는 .claude 폴더 안에 commands 디렉터리를 만들고, 거기에 마크다운 파일을 넣으면 됩니다.
your-project/
└── .claude/
└── commands/
├── audit.md
└── write_tests.md
파일 이름이 그대로 명령어 이름이 됩니다.
audit.md를 만들면 /audit으로 쓸 수 있고, deploy.md를 만들면 /deploy가 생기는 식입니다.
파일 만들고 나서 Claude Code를 한 번 재시작해야 명령어가 인식됩니다.
이거 빠뜨리면 왜 안 되지 하고 한참 헤매게 됩니다.;;
프로젝트 명령어 vs 글로벌 명령어
명령어를 저장하는 위치가 두 군데입니다.
- .claude/commands/ — 현재 프로젝트에서만 쓰는 명령어. git에 올리면 팀원들도 같이 쓸 수 있습니다.
- ~/.claude/commands/ — 내 컴퓨터 전체에서 쓰는 개인 명령어. 어떤 프로젝트에서든 불러올 수 있습니다.
팀 컨벤션 관련된 건 프로젝트에, 내가 어디서든 쓰는 건 글로벌에 넣는 식으로 나눠쓰면 됩니다.
실제로 써먹는 예시
/audit — 의존성 취약점 검사
매번 npm audit 돌리고, 고치고, 테스트 돌리는 걸 손으로 하고 있었다면 이렇게 하나로 묶을 수 있습니다.
.claude/commands/audit.md:
프로젝트 의존성 보안 감사를 실행합니다:
1. `npm audit`을 실행해서 취약한 패키지를 확인합니다
2. `npm audit fix`로 자동 업데이트를 적용합니다
3. 테스트를 돌려서 업데이트가 뭔가를 망가뜨리지 않았는지 확인합니다
/commit — 커밋 메시지 자동 작성
솔직히 이게 제일 자주 쓰게 되는 명령어입니다.
변경 사항을 보고 커밋 메시지를 직접 써주거든요.
$ARGUMENTS를 활용해서 메시지를 직접 넘길 수도 있고,
그냥 /commit만 쳐도 Claude가 알아서 diff를 읽고 메시지를 만들어줍니다.
.claude/commands/commit.md:
스테이징된 변경 사항을 검토하고 커밋합니다: $ARGUMENTS
- 커밋 메시지가 주어지면 그걸 사용하고, 없으면 변경 내용을 보고 적절한 메시지를 작성합니다
- 커밋 전에 임시 테스트 코드, TODO 주석, 디버그용 console.log가 남아있지 않은지 확인합니다
- 커밋 메시지는 Conventional Commits 형식을 따릅니다 (feat:, fix:, chore: 등)
이게 좋은 이유가, Claude는 단순 린터랑 달리 "이 로직이 하드코딩된 것 같은데 괜찮냐"처럼 맥락을 이해하고 잡아냅니다.
/catchup — 컨텍스트 다시 불러오기
대화가 길어지면 /clear로 컨텍스트를 초기화해야 할 때가 있습니다. 그런데 그러면 지금까지 작업한 내용을 Claude가 모르게 되죠. 이럴 때 쓰는 명령어입니다.
.claude/commands/catchup.md:
현재 작업 중인 내용을 파악합니다.
모든 미커밋 git 변경사항을 읽고, 어떤 작업이 진행 중인지 파악한 뒤
현재 상태를 간략히 요약해주세요.
/clear로 대화 초기화 → /catchup으로 작업 내용 재로드, 이 패턴을 반복하면 컨텍스트 창을 효율적으로 관리할 수 있습니다.
/create-pr — PR 생성까지 한 번에
브랜치 만들고, 커밋하고, PR 올리는 걸 매번 따로 하고 있다면 이것도 묶을 수 있습니다.
.claude/commands/create-pr.md:
현재 변경사항으로 Pull Request를 생성합니다:
1. 변경사항을 확인하고 적절한 브랜치명을 제안합니다
2. 새 브랜치를 만들고 변경사항을 커밋합니다
3. GitHub CLI(`gh pr create`)로 PR을 생성합니다
4. PR 제목과 본문은 변경사항을 바탕으로 작성합니다
- 어떤 문제를 해결하는지
- 어떻게 해결했는지
- 테스트 방법
GitHub CLI(gh)가 설치돼 있어야 동작합니다.
$ARGUMENTS로 더 유연하게
$ARGUMENTS를 쓰면 실행할 때 값을 넘길 수 있어서 훨씬 범용적으로 쓸 수 있습니다.
예를 들어 테스트 작성 명령어를 이렇게 만들면:
.claude/commands/write_tests.md:
다음 대상에 대한 테스트를 작성하세요: $ARGUMENTS
규칙:
* Vitest + React Testing Library 사용
* 테스트 파일은 소스 파일 옆 __tests__ 폴더에
* 파일명은 [filename].test.ts(x)
* 임포트는 @/ 접두사 사용
커버해야 할 것들:
* 정상 동작
* 엣지 케이스
* 에러 상태
이렇게 사용합니다:
/write_tests hooks 디렉터리의 use-auth.ts 파일
$ARGUMENTS 자리에 뒤에 쓴 문자열이 그대로 들어갑니다. 파일 경로 말고도 아무 내용이나 넘길 수 있어서, 명령어 하나를 다양한 상황에 재활용할 수 있습니다.
커스텀 명령어가 오히려 독이 되는 경우
명령어를 만드는 게 항상 좋은 건 아닙니다.
잘못 쓰면 오히려 귀찮아지거나, 기대한 결과가 안 나오거나, 관리 부담만 늘어납니다.
한 번만 쓸 작업엔 만들지 마세요. 명령어는 반복적인 작업에 가치가 있습니다.
이번 릴리즈에서만 필요한 마이그레이션이라든지, 일회성 데이터 정리 같은 건 그냥 그때그때 프롬프트로 주는 게 낫습니다.
명령어 만들고 나서 두 번 다시 안 쓰는 경우가 생각보다 많습니다.
# ❌ 이런 건 명령어로 만들 필요 없음
users 테이블의 created_at 컬럼을 timestamp로 변환하는 마이그레이션 작성해줘
(이번 릴리즈 한 번만 쓸 거니까 그냥 직접 치는 게 낫다)
매번 맥락이 달라지는 작업도 맞지 않습니다.
"이번 스프린트 이슈 정리해줘" 같은 건 상황마다 다른 배경 설명이 필요합니다.
명령어로 고정해놓으면 오히려 Claude가 엉뚱한 방향으로 작업할 수 있습니다.
# ❌ 이것도 명령어보단 직접 대화가 나음
/sprint-review
→ Claude 입장에서는 "어떤 기준으로?", "이번 스프린트 목표가 뭔데?" 를 모름
# ✅ 이렇게 그냥 치는 게 훨씬 낫다
이번 스프린트 목표는 결제 모듈 안정화였고, #123 #145 #167 이슈를 작업했어.
완료된 것과 이월된 것 정리해줘.
내용이 짧은 명령어는 효과가 없습니다.
명령어의 진가는 길고 반복적인 프롬프트를 하나로 압축할 때 나옵니다.
# ❌ 이 정도면 그냥 타이핑하는 게 낫다
# .claude/commands/catchup.md
미커밋 변경사항을 읽어줘
# ✅ 이 정도 분량은 명령어로 만들 만하다
# .claude/commands/catchup.md
미커밋된 모든 git 변경사항을 읽고:
1. 어떤 작업이 진행 중인지 파악해줘
2. 변경된 파일 목록을 보여줘
3. 아직 완료되지 않은 부분이 있으면 알려줘
4. 다음에 이어서 작업할 사항을 요약해줘
명령어가 너무 추상적이면 결과가 들쭉날쭉합니다.
/review만 덩그러니 써놓으면 Claude가 매번 다르게 해석합니다.
어떤 관점으로, 어떤 기준으로 리뷰할지 구체적으로 적어둬야 합니다.
# ❌ 너무 추상적 — 매번 다른 결과가 나옴
# .claude/commands/review.md
코드를 리뷰해줘
# ✅ 기준이 명확하면 일관된 결과가 나옴
# .claude/commands/review.md
현재 브랜치의 변경사항을 리뷰합니다. 다음 기준으로만 검토해주세요:
- 버그 또는 잠재적 런타임 에러
- 보안 취약점 (SQL 인젝션, XSS 등)
- 명백한 성능 문제
스타일, 변수명, 주석 같은 사소한 것들은 언급하지 마세요.
커스텀 명령어 vs CLAUDE.md
비슷해 보이지만 용도가 다릅니다.
CLAUDE.md는 Claude가 세션을 시작할 때 자동으로 읽는 파일입니다.
항상 알고 있어야 하는 프로젝트 규칙을 여기에 넣습니다.
커스텀 명령어는 명시적으로 호출할 때만 동작합니다.
특정 시점에 특정 작업을 트리거하고 싶을 때 씁니다.
# CLAUDE.md — "항상 알고 있어야 하는 것"
## 프로젝트 개요
이 프로젝트는 Next.js 14 + TypeScript로 작성된 이커머스 플랫폼입니다.
## 코딩 컨벤션
- 컴포넌트는 함수형으로 작성
- 상태 관리는 Zustand 사용
- 스타일은 Tailwind CSS
- 커밋 메시지는 Conventional Commits 형식
# .claude/commands/create-pr.md — "필요할 때만 꺼내쓰는 것"
현재 브랜치의 변경사항으로 PR을 생성합니다:
1. 변경사항을 요약해서 PR 제목과 본문을 작성합니다
2. `gh pr create`로 PR을 생성합니다
...
실제로는 둘을 조합해서 쓰는 경우가 많습니다.
CLAUDE.md에 프로젝트 컨텍스트를 깔아두고, 커스텀 명령어는 그 위에서 세부 작업을 지시하는 방식입니다.
예를 들어 CLAUDE.md에 "커밋은 Conventional Commits"라고 적어두면, /commit 명령어는 그 규칙을 전제로 동작합니다.
그래서 언제 만들면 좋냐면
결국 기준은 하나입니다. Claude한테 같은 설명을 세 번 이상 반복하고 있다면, 그 설명을 파일에 옮겨 담으면 됩니다.
# 이런 상황이 반복된다면 명령어로 만들 타이밍
"테스트는 Vitest 써줘. 파일은 __tests__ 폴더에 넣고,
임포트는 @/ 쓰고, happy path랑 에러 케이스 둘 다 써줘."
→ 이 말을 매번 치고 있다면 → /write_tests 명령어로
명령어 개수에 제한이 있을까 ?.?
파일 개수 자체는 제한이 없습니다.
100개를 만들어도 오류가 나진 않습니다. 다만 현실적인 제약이 하나 있습니다.
Claude는 세션 시작 시 명령어들의 설명(description)을 컨텍스트에 로드합니다.
이 설명들의 총 글자 수가 16,000자(컨텍스트 창의 약 2%)를 넘으면, 초과분은 조용히 제외됩니다.
그리고 경고도 딱히 눈에 띄지 않아서, 자기가 만든 명령어가 누락됐는지 모르고 쓰는 경우도 생길 수 있습니다.
확인하고 싶으면 세션 중에 /context를 실행해보면 됩니다. 제외된 명령어가 있으면 거기서 경고로 알려줍니다.
한도를 올리고 싶다면 환경 변수로 조정할 수 있습니다:
export SLASH_COMMAND_TOOL_CHAR_BUDGET=32000
결국 이 제약도 "꼭 필요한 명령어만 만들어라"는 이유가 하나 더 생기는 셈입니다. 명령어를 계속 쌓다 보면 어느 순간 뒤쪽에 있는 명령어들이 슬그머니 빠지기 시작합니다.
참고 링크
'AI > Claude' 카테고리의 다른 글
| [Claude] Discord에서 개발하기 (0) | 2026.03.22 |
|---|---|
| [Claude] Claude를 잘 써보자. 기본 명령어로... (0) | 2026.03.21 |