AICI/CDProductivity

Claude Code 커스텀 슬래시 커맨드로 PR 리뷰 스킬을 직접 만든 과정

Claude Code의 /review 대신, 프로젝트 컨벤션과 심각도 분류를 세밀하게 제어하는 커스텀 PR 리뷰 슬래시 커맨드를 .claude/commands/에 직접 만들어 팀에 공유한 경험을 정리합니다.

Srue2026년 5월 6일
Claude Code 커스텀 슬래시 커맨드로 PR 리뷰 스킬을 직접 만든 과정

이전 글에서 Claude Code의 /review와 claude-code-action으로 PR 리뷰를 자동화한 경험을 공유했습니다. /review --comment로 PR에 인라인 코멘트가 달리는 걸 보면서 "이것만으로도 충분하다"고 생각했습니다.

그런데 몇 주 운영하다 보니 아쉬운 점이 하나둘 보이기 시작했습니다. 보안 관련 이슈와 단순 네이밍 제안이 같은 무게로 나열되고, 리뷰 결과의 형식이 실행할 때마다 달랐습니다. CLAUDE.md에 "보안 취약점은 Critical로 분류하라"고 적어봤지만, /reviewCLAUDE.md를 컨텍스트로 참조할 뿐 리뷰의 흐름 자체를 바꾸지는 못했습니다.

결국 "리뷰 프로세스 자체를 내가 설계할 수 있으면 좋겠다"는 생각에 도달했습니다. 그리고 Claude Code의 커스텀 슬래시 커맨드(Custom Slash Command), 즉 커스텀 스킬이 정확히 그 역할을 해준다는 걸 알게 됐습니다.

커스텀 슬래시 커맨드란

Claude Code에서 /review/commit 같은 슬래시 커맨드를 사용해본 적이 있다면, 커스텀 슬래시 커맨드는 그 확장판입니다. .claude/commands/ 디렉토리에 마크다운(Markdown) 파일을 하나 만들면, 그 파일명이 곧 슬래시 커맨드가 됩니다.

.claude/commands/review-pr.md  →  /review-pr
.claude/commands/seo-audit.md  →  /seo-audit
.claude/commands/write-blog.md →  /write-blog

마크다운 파일 안에는 Claude Code가 해당 커맨드를 실행할 때 따라야 할 프롬프트를 작성합니다. 일반적인 프롬프트와 다를 게 없지만, 한 가지 특별한 점이 있습니다. $ARGUMENTS라는 플레이스홀더를 쓸 수 있다는 것입니다.

기본 구조
# 커맨드 이름
 
이 커맨드는 ~를 수행합니다.
 
대상: $ARGUMENTS

이렇게 만들어두면 /review-pr 42를 실행했을 때 $ARGUMENTS42로 치환됩니다. 이게 전부입니다. 복잡한 설정 파일이나 플러그인 시스템이 아니라, 마크다운 한 장이 곧 스킬입니다.

/review와 커스텀 스킬의 차이

커스텀 스킬을 만들기 전에, 내장 /review와 무엇이 다른지 정리해봤습니다.

항목/review (내장)커스텀 /review-pr
리뷰 기준CLAUDE.md 참조 + 범용 규칙프롬프트에서 직접 정의
출력 형식실행마다 다를 수 있음심각도별 분류 등 고정 가능
무시 규칙CLAUDE.md에 명시프롬프트에서 세밀하게 제어
PR 코멘트--comment 플래그 내장gh CLI 호출을 직접 포함
인자 전달--comment 42 형태$ARGUMENTS로 자유롭게
공유개인 환경에 의존git에 포함, 팀 공유 가능

핵심 차이는 제어의 범위입니다. /review는 Anthropic이 설계한 리뷰 흐름을 따르고, CLAUDE.md는 그 흐름에 힌트를 주는 역할입니다. 반면 커스텀 스킬은 리뷰의 흐름 자체를 내가 설계합니다. "먼저 보안 이슈를 찾고, 그 다음 컨벤션을 확인하고, 마지막에 개선 제안을 하라"처럼 순서까지 지정할 수 있습니다.

다만 트레이드오프도 있습니다. /review에는 --comment 플래그처럼 편리한 내장 기능이 있지만, 커스텀 스킬에서 같은 동작을 하려면 gh CLI 호출을 프롬프트에 직접 포함해야 합니다. 편의성과 제어력 사이의 선택입니다.

리뷰 스킬 만들기

이제 실제로 .claude/commands/review-pr.md를 작성해보겠습니다. 처음부터 완벽하게 만들려고 하지 않고, 핵심 기능부터 시작해서 점진적으로 개선했습니다.

1단계: PR diff 가져오기

리뷰의 시작은 변경 사항을 읽는 것입니다. gh CLI로 PR의 diff를 가져오도록 지시합니다.

.claude/commands/review-pr.md (1단계)
# PR 코드 리뷰
 
PR #$ARGUMENTS의 코드를 리뷰합니다.
 
## 리뷰 대상 가져오기
 
1. `gh pr diff $ARGUMENTS`로 변경된 코드를 가져옵니다.
2. `gh pr view $ARGUMENTS --json title,body,files`로 PR 정보를 확인합니다.

이것만으로도 /review-pr 42를 실행하면 Claude Code가 해당 PR의 diff를 읽고 리뷰를 시작합니다. 하지만 리뷰 기준이 없으니 결과가 매번 달라졌습니다.

2단계: CLAUDE.md 컨벤션 참조

프로젝트의 CLAUDE.md에 이미 코드 컨벤션이 정리되어 있었습니다. 스킬 프롬프트에서 이를 명시적으로 참조하도록 추가합니다.

CLAUDE.md 참조 지시 추가
## 리뷰 기준
 
CLAUDE.md를 읽고, 그 안에 정의된 코드 컨벤션을 리뷰 기준으로 사용합니다.
특히 다음을 확인합니다:
- 예외 처리 전략이 컨벤션과 일치하는지
- 트랜잭션 설정이 규칙대로 되어 있는지
- API 응답 구조가 표준을 따르는지

3단계: 심각도 분류

이 부분이 /review와 가장 큰 차이를 만든 지점이었습니다. 리뷰 결과를 세 단계로 분류하도록 지시합니다.

심각도 분류 기준 추가
## 리뷰 결과 형식
 
발견한 이슈를 다음 세 가지 심각도로 분류합니다:
 
### Critical (즉시 수정 필요)
- 보안 취약점 (SQL Injection, XSS, 인증 우회 등)
- 데이터 손실 가능성
- 프로덕션 장애를 유발할 수 있는 버그
 
### Warning (수정 권장)
- 프로젝트 컨벤션 위반
- 성능 문제 (N+1 쿼리, 불필요한 전체 조회 등)
- 에러 핸들링 누락
 
### Suggestion (개선 제안)
- 가독성 향상 방안
- 더 나은 설계 패턴 제안
- 테스트 커버리지 보완

4단계: gh CLI로 인라인 코멘트

/review --comment가 해주던 기능을 직접 구현합니다. gh CLI의 pr review 명령으로 PR에 코멘트를 남기도록 지시합니다.

인라인 코멘트 지시 추가
## PR에 코멘트 남기기
 
리뷰 완료 후 `gh` CLI로 PR에 인라인 코멘트를 남깁니다.
 
각 이슈에 대해:
```bash
gh api repos/{owner}/{repo}/pulls/$ARGUMENTS/comments \
  --method POST \
  -f body="[심각도] 설명" \
  -f commit_id="(최신 커밋 SHA)" \
  -f path="파일 경로" \
  -F line=라인번호 \
  -f side="RIGHT"

코멘트 본문에는 심각도 태그를 포함합니다:

  • 🔴 [Critical] — 즉시 수정 필요
  • 🟡 [Warning] — 수정 권장
  • 🟢 [Suggestion] — 개선 제안
 
## 완성된 스킬 파일
 
위의 1~4단계를 합치고, 무시 규칙과 긍정적 피드백을 더한 최종 버전입니다. 아래 내용을 그대로 `.claude/commands/review-pr.md`에 저장하면 `/review-pr 42`로 바로 실행할 수 있습니다.
 
먼저 스킬 파일의 전체 구조를 보겠습니다.
 
```text title=".claude/commands/review-pr.md — 전체 구조"
# PR 코드 리뷰
PR #$ARGUMENTS의 코드를 리뷰합니다.
 
## Step 1: PR 정보 수집       ← gh CLI로 diff, 커밋 SHA, owner/repo 확보
## Step 2: 프로젝트 컨벤션 로드  ← CLAUDE.md 읽기
## Step 3: 코드 리뷰           ← 심각도 3단계 분류 + 무시 규칙
## Step 4: 리뷰 요약 출력       ← 터미널에 결과 표시
## Step 5: PR에 인라인 코멘트    ← gh api로 해당 라인에 코멘트

각 Step의 실제 내용을 하나씩 보겠습니다.

Step 1: PR 정보 수집

스킬 파일에서 가장 중요한 부분입니다. 이후 Step 5에서 인라인 코멘트를 남기려면 커밋 SHAowner/repo가 필요하기 때문에, 여기서 먼저 확보해야 합니다.

Step 1 내용
## Step 1: PR 정보 수집
 
아래 명령을 실행해서 리뷰에 필요한 정보를 확보합니다.
 
1. PR 메타 정보:
   gh pr view $ARGUMENTS --json title,body,files
 
2. 변경된 코드:
   gh pr diff $ARGUMENTS
 
3. 최신 커밋 SHA (Step 5에서 사용):
   gh pr view $ARGUMENTS
     --json commits
     --jq '.commits[-1].oid'
 
4. owner/repo (Step 5에서 사용):
   gh repo view
     --json owner,name
     --jq '.owner.login + "/" + .name'
 
3번과 4번의 결과를 기억해두세요. Step 5에서 사용합니다.

Step 2~3: 컨벤션 로드와 코드 리뷰

Step 2~3 내용
## Step 2: 프로젝트 컨벤션 로드
 
CLAUDE.md를 읽고, 코드 컨벤션과 리뷰 시 주의사항을 파악합니다.
 
## Step 3: 코드 리뷰
 
diff를 분석하며 아래 세 단계 심각도로 분류합니다.
 
- Critical: 보안 취약점, 데이터 손실, 프로덕션 장애 유발 버그
- Warning: 컨벤션 위반, N+1 쿼리 등 성능 문제, 에러 핸들링 누락
- Suggestion: 가독성 향상, 더 나은 설계 패턴, 테스트 커버리지 보완
 
리뷰하지 않을 것:
- 단순 네이밍 취향, 포매팅, 테스트 스타일
- *.lock, *.json, **/generated/**, *.md 파일

Step 4: 리뷰 요약 출력

Step 4 내용
## Step 4: 리뷰 요약 출력
 
터미널에 아래 형식으로 결과를 출력합니다:
 
🔴 Critical (N건) — [파일:라인] 설명
🟡 Warning (N건) — [파일:라인] 설명
🟢 Suggestion (N건) — [파일:라인] 설명
👍 잘한 점 — 긍정적 피드백 1~2가지

Step 5: PR에 인라인 코멘트 남기기

이 부분이 핵심입니다. Step 1에서 확보한 커밋 SHA와 owner/repo를 사용해서, 발견한 이슈를 해당 코드 라인에 직접 코멘트합니다.

Step 5 내용
## Step 5: PR에 인라인 코멘트 남기기
 
Step 1에서 확보한 커밋 SHA와 owner/repo 값을 사용합니다.
발견한 각 이슈에 대해 아래 형식으로 인라인 코멘트를 남깁니다:
 
gh api repos/{owner/repo}/pulls/$ARGUMENTS/comments
  --method POST
  -f body="🔴 [Critical] 설명"
  -f commit_id="{커밋 SHA}"
  -f path="파일 경로"
  -F line=라인번호
  -f side="RIGHT"
 
각 파라미터 설명:
- owner/repo: Step 1의 4번에서 얻은 값
- commit_id: Step 1의 3번에서 얻은 값
- path: diff에서 확인한 실제 파일 경로
- line: diff에서 해당 이슈가 있는 실제 라인 번호
- body 심각도 태그: Critical → 🔴, Warning → 🟡, Suggestion → 🟢
 
모든 인라인 코멘트를 남긴 뒤, 전체 요약도 PR 코멘트로 남깁니다:
 
gh pr comment $ARGUMENTS
  --body "Step 4의 리뷰 요약 전문"

위 Step 1~5를 하나의 .claude/commands/review-pr.md 파일에 합치면 완성입니다. 파일 하나, 프레임워크 없음, 설정 없음. 이 단순함이 커스텀 스킬의 매력이었습니다.

스킬 파일은 스크립트가 아니라 "프롬프트"다

이 부분이 처음에 헷갈렸습니다. 스킬 파일을 보면 셸 스크립트처럼 생겼지만, 실제로는 Claude Code가 읽고 해석하는 프롬프트입니다. 동작 방식의 차이를 정리하면 이렇습니다.

셸 스크립트커스텀 스킬 (프롬프트)
변수COMMIT_SHA=$(...)로 명시 할당Claude Code가 실행 결과를 기억
파일 경로/라인파싱 로직 직접 구현 필요diff를 읽고 AI가 판단
에러 처리if/else로 분기Claude Code가 상황 판단
실행 흐름위에서 아래로 자동 실행AI가 맥락을 보며 단계별 실행

예를 들어 Step 5의 pathline 값은 어디서 오는 걸까요? Step 1에서 gh pr diff를 실행하면 diff 전체가 출력됩니다. Claude Code는 그 diff를 읽고 Step 3에서 "이 파일의 몇 번째 줄에 문제가 있다"를 분석합니다. Step 5에서 gh api 명령을 구성할 때, 분석 결과에서 파일 경로와 라인 번호를 꺼내서 실제 값으로 채워넣습니다.

커밋 SHA와 owner/repo도 마찬가지입니다. Step 1에서 gh pr view --json commits --jq ...를 실행하면 결과가 터미널에 출력되고, Claude Code는 그 값을 대화 맥락 안에서 기억합니다. Step 5에서 필요할 때 해당 값을 자동으로 넣어줍니다. 셸 변수처럼 명시적으로 $COMMIT_SHA를 할당하지 않아도 동작하는 이유입니다.

실행해보기

스킬 파일을 저장하고 Claude Code에서 바로 실행합니다.

실행
/review-pr 42

$ARGUMENTS42가 들어가면서, Claude Code는 순서대로 PR 정보를 수집하고, CLAUDE.md를 읽고, diff를 분석해서 심각도별로 분류한 뒤, gh CLI로 PR에 코멘트를 남깁니다.

처음 실행했을 때 인상적이었던 건, 터미널에 출력되는 리뷰 요약의 일관성이었습니다. /review를 쓸 때는 실행할 때마다 형식이 조금씩 달랐는데, 프롬프트에 출력 형식을 명시하니 매번 같은 구조로 결과가 나왔습니다. Critical이 0건이면 "이번 PR에는 Critical 이슈가 없습니다"가 아니라, ### 🔴 Critical (0건)으로 통일됩니다. 사소하지만 이런 일관성이 쌓이면 리뷰 결과를 파악하는 속도가 달라집니다.

운영하면서 개선한 것들

무시 규칙이 생각보다 중요했습니다

처음에는 "무엇을 봐라"에만 집중했는데, 실제로 리뷰 품질을 가장 크게 올린 건 "무엇을 보지 마라"였습니다. 포매팅, 네이밍 취향 같은 노이즈를 명시적으로 제외하자 거짓 양성(False Positive)이 크게 줄었습니다. 이건 이전 글에서 CLAUDE.md 운영 팁으로도 언급했던 부분인데, 커스텀 스킬에서는 더 세밀하게 제어할 수 있었습니다.

긍정적 피드백도 넣었습니다

리뷰가 지적 사항만 나열하면 받는 쪽에서 지칩니다. "잘한 점" 섹션을 추가하니 리뷰 결과를 읽는 경험이 훨씬 나아졌습니다. 사소하지만, 코드 리뷰의 목적이 "틀린 걸 찾는 것"이 아니라 "코드 품질을 함께 올리는 것"이라는 걸 프롬프트 설계에서도 반영한 셈입니다.

파일 필터링 추가

모든 파일을 리뷰하면 설정 파일이나 자동 생성 코드에도 코멘트가 달렸습니다. 프롬프트에 필터링 규칙을 추가했습니다.

필터링 규칙 예시
## 리뷰 제외 대상
- `*.lock`, `*.json` (패키지 매니저 락 파일, 설정 파일)
- `**/generated/**` (자동 생성 코드)
- `*.md` (문서 파일)
- 단순 import 추가만 있는 파일

팀에서 공유하기

커스텀 스킬의 결정적 장점은 .claude/commands/ 디렉토리가 프로젝트 저장소에 포함된다는 것입니다. git에 커밋하면 팀 전체가 같은 리뷰 스킬을 사용할 수 있습니다.

.claude/
└── commands/
    ├── review-pr.md      # PR 코드 리뷰
    ├── seo-audit.md      # SEO 점검
    └── write-blog.md     # 블로그 작성

새로 합류한 팀원이 별도 설정 없이 /review-pr 42만 실행하면 팀의 리뷰 기준으로 동작합니다. 리뷰 기준이 바뀌면 마크다운 파일을 수정하고 커밋하면 됩니다. 리뷰 가이드라인이 코드와 함께 버전 관리되는 구조입니다.

AI 코딩 도구를 비교했던 글에서 "도구의 가치는 워크플로우에 자연스럽게 녹아드는지에 달려 있다"고 썼는데, 커스텀 스킬이 정확히 그 지점을 잘 짚고 있었습니다. 팀 전체의 리뷰 워크플로우를 마크다운 파일 하나로 표준화할 수 있다는 건, 별도의 리뷰 도구나 봇을 도입하는 것보다 훨씬 가볍습니다.

한 가지 주의할 점은, .claude/commands/에 있는 스킬은 프로젝트 스코프입니다. 만약 개인적으로만 사용하고 싶은 스킬이 있다면 ~/.claude/commands/(홈 디렉토리)에 만들면 됩니다. 이 경우 git에 포함되지 않으므로 다른 사람에게 영향을 주지 않습니다.

마무리

처음에는 /review만으로 충분할 줄 알았습니다. 하지만 실제로 운영하다 보니 "리뷰 기준"과 "리뷰 프로세스"는 다른 문제라는 걸 깨달았습니다. CLAUDE.md는 기준을 정의하지만, 그 기준을 어떤 순서로, 어떤 형식으로, 어떤 도구를 써서 적용할지는 커스텀 스킬의 영역이었습니다.

결국 커스텀 리뷰 스킬을 만드는 과정은 "좋은 코드 리뷰란 무엇인가"를 구체적으로 설계하는 과정이기도 했습니다. 심각도를 어떻게 나눌 것인지, 무엇을 무시할 것인지, 피드백을 어떤 톤으로 전달할 것인지. 이런 질문들에 답하면서, 그동안 감각적으로만 해오던 코드 리뷰가 처음으로 체계를 갖추게 됐습니다.

마크다운 한 장이 팀의 리뷰 문화를 바꿀 수 있다는 건, 생각보다 꽤 강력한 일이었습니다.