Claude Code 커스텀 슬래시 명령어(.claude/commands) 직접 만들기 구현 절차
요약
Claude Code의 커스텀 슬래시 명령어(.claude/commands)를 활용하여 반복적인 프롬프트 작업을 자동화하는 방법을 안내합니다. Markdown 파일에 명령어를 배치하고, 셸 명령어(`!`)와 인자($1, $2 등) 처리 방식을 이해해야 합니다.
핵심 포인트
- 커스텀 슬래시 명령어는 `.claude/commands/<이름>.md`에 파일을 배치하여 구현합니다.
- 프롬프트 전 실행되는 셸 명령어는 `!`를 사용하며, 이를 위해 `allowed-tools` 설정이 필요합니다.
- 인자는 공백 구분자이며, `$1`, `$2` 또는 모든 인자를 받는 `$ARGUMENTS`를 사용할 수 있습니다.
- 반복 작업(예: git diff 리뷰)에 유용하며, 전제 조건으로 파일 경로 등을 미리 가져와 컨텍스트로 제공할 수 있습니다.
‘PR 전에 셀프 리뷰해 줘’, ‘이 Issue 고쳐 줘’ — 매번 거의 같은 프롬프트를 Claude Code에 입력하고 있다면, 커스텀 슬래시 명령어로 만들어 두면 편리하다. 마크다운(Markdown) 파일 하나만 배치하면 /review처럼 호출할 수 있다.
다만, 실제로 만들다 보면 !로 작성한 셸 명령어(shell command)가 전개되지 않거나,
인수(argument)를 받는 방식이 예상과 다르거나,
하위 디렉터리에 나누니 이름 충돌이 발생하는 등 세 가지 지점에서 막히기 쉽다. 이 글은 그 절차와 회피책을 정리한다.
- 예상 독자: Claude Code를 일상적으로 사용하며, 정형화된 프롬프트를 재사용하고 싶은 사람
- 동작 확인 환경: Claude Code 2.x 계열 (2026년 10월 기준) / macOS / zsh / git 2.4x
- 전제:
.claude/디렉터리와settings.json의 위치를 알고 있어야 함.
최근 Claude Code에서는 슬래시 명령어와 Agent Skills 메커니즘이 통합되고 있는 추세이지만,
.claude/commands/*.md는 계속해서 그대로 작동한다. 동일한 이름의 Skill이 있다면 그쪽이 우선되므로, 마이그레이션 중인 사용자는 이름 중복에 주의해야 한다.
.claude/commands/<이름>.md를 배치하면/ <이름>으로 호출할 수 있다 (사용자 공통이라면~/.claude/commands/).- 본문 내의
!+ 백틱(``) 셸 실행은 프런트매터(frontmatter)의allowed-tools에 해당 Bash를 허용하지 않으면 작동하지 않는다. $1,$2는 공백 구분자이다. 자유 문장은$ARGUMENTS로 받고 마지막에 배치한다. 하위 디렉터리는 네임스페이스가 아니므로 파일 이름을 고유하게 해야 한다.
mkdir -p .claude/commands
cat > .claude/commands/explain.md <<'EOF'
다음 코드를, 5년 차 웹 엔지니어를 대상으로 3줄로 설명해 줘.
...
EOF
Claude Code를 열고 /를 치면, 후보 목록에 /explain이 (project)와 함께 나타난다.
> /explain @src/lib/retry.ts
@경로를 쓰면 파일 내용이 컨텍스트에 포함되므로, $ARGUMENTS를 통해 전달하면 그대로 설명하게 할 수 있다.
실용적인 것은 'git의 차분(diff)을 사전에 가져와 리뷰시키는' 패턴이다.
---
description: 스테이지된 차분을 셀프 리뷰한다
argument-hint: [중점적으로 보고 싶은 관점(선택)]
...
.claude/commands/review.md로 저장하고, /review 인가 관련처럼 호출한다. ! 줄은 프롬프트가 Claude에게 전달되기 전에 실행되며, 그 출력이 삽입된다. Claude가 스스로 git diff를 실행하는 것보다 왕복(round trip)이 한 번 줄고, 매번 같은 전제 조건으로 봐준다는 것이 장점이다.
---
description: Issue 번호와 우선도를 지정하여 수정 방침을 세운다
argument-hint: <issue번호> <우선도> [보충]
...
> /fix-issue 482 high
$1에 482, $2에 high가 들어간다.
/review 실행 후, Claude의 첫 응답에 차분 파일명이 구체적으로 나온다면 !가 전개된 것이다. 나오지 않고
처럼 넓게 취하면 편하지만, git push까지 통하기 때문에 피했다. 읽기 전용만 허용하는 것이 안전하다. 한 가지 더, !와 백틱 사이에 공백을 넣으면 단순 문자열로 처리되므로, !git diff``처럼 붙여서 작성한다.
증상: /fix-issue 482 로그인 후에 500이 나옴이라고 입력하면, $2에 '로그인 후에'만 들어간다.
원인: 위치 인수는 공백으로 단순 분리된다. 일본어 문장이라도 공백이 있으면 거기서 끊긴다.
회피책:
- 위치 인수는 'ID・플래그・우선순위' 등 공백을 포함하지 않는 값으로 한정한다 - 자유 문장은
$ARGUMENTS로 받는다. 다만$ARGUMENTS는 모든 인수의 문자열이므로,$1과 병용하면 첫 번째 값이 중복된다. 인수가 없는 경우에 대비하여 본문에 '비어있다면 〇〇로 처리한다'라는 문장을 한 줄 적어두는 것이 좋다 (빈 문자열 그대로 전달되므로).
Issue #$1을 대응한다.
보충 정보(전체 인수): $ARGUMENTS
※ 보충이 Issue 번호만인 경우, Issue 본문을 읽고 판단할 것.
증상: .claude/commands/frontend/test.md와 .claude/commands/backend/test.md를 만들었더니, /test가 한쪽만 기대대로 작동한다.
원인: 서브 디렉토리는 목록 설명란에 (project:frontend) 등으로 표시될 뿐, 명령어 이름에는 포함되지 않는다. 둘 다 /test가 된다. 프로젝트와 사용자(~/.claude/commands/)에 동일한 이름의 파일이 있는 경우도 마찬가지로 충돌한다. 회피책: 파일 자체에 접두사를 붙인다.
.claude/commands/
├── fe-test.md # /fe-test
├── be-test.md # /be-test
...
디렉토리 구분은 정리용으로 생각하고, 이름의 고유성은 파일명으로 보장한다.
description는 목록 표시뿐만 아니라, Claude 자체가 명령어를 호출해도 될지 판단하는 자료가 된다. 임의로 호출되면 안 되는 명령어(배포 관련 등)는 frontmatter에 disable-model-invocation: true를 붙여둔다 - model을 frontmatter에서 지정하면, 해당 명령어만 가벼운 모델로 구동할 수 있다. 요약・설명 계열은 가벼운 모델로 충분했다 -
.claude/commands/를 리포지토리에 커밋하면, 팀원 모두가 같은 명령어를 사용할 수 있다. 개인의 습관이 강한 것은 ~/.claude/commands/ 쪽에 두는 것이 좋다.
- 사용자 정의 슬래시 명령어는 Markdown 한 장으로 만들 수 있어, 정형 프롬프트 재작성이 사라진다 -
!의 사전 실행은allowed-tools에 읽기 계열 Bash를 접두사로 허용하지 않으면 작동하지 않는다 - 위치 인수는 공백 구분이다. 자유 문장은$ARGUMENTS이며, 빈 경우의 처리도 본문에 적는다 - 서브 디렉토리는 네임스페이스가 되지 않는다. 파일명에 접두사를 붙여 충돌을 피한다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기