Custom commands — Biến workflow lặp thành 1 lệnh

4 — Mở rộng & Tự động hóaTrung cấp25 phút

Quan sát developer bạn: họ gõ cùng một prompt cho Claude mỗi tuần:

Bạn sẽ học được
  • Tạo custom slash command (/audit, /write_tests, /review...) cho project
  • Dùng $ARGUMENTS placeholder để command nhận input động
  • Tổ chức folder .claude/commands/ theo cách team có thể share qua Git
  • Nhận ra 3 dấu hiệu "đáng tự động hóa thành command"
  • Tránh 5 anti-patterns khi thiết kế command

Custom command là gì?

Một custom command là file markdown nằm trong thư mục .claude/commands/ của project. Khi bạn gõ /tên-file trong Claude Code, nội dung file được gửi như prompt của bạn.

Anatomy

Tên file = tên command. File audit.md tạo command /audit. File write_tests.md tạo command /write_tests.

Ví dụ đơn giản

.claude/commands/audit.md:

Trong Claude Code:

<project-root>/
└── .claude/
    └── commands/
        ├── audit.md        →  /audit
        ├── write_tests.md  →  /write_tests
        └── review_pr.md    →  /review_pr
Run security audit:

1. Execute `npm audit --json` and parse the output
2. List all vulnerabilities with severity CRITICAL or HIGH
3. For each, show:
   - Package name and vulnerable version
   - Fix version if available
   - CVE ID and CVSS score
4. Run `npm audit fix` to apply automatic fixes
5. Run `npm test` to verify fixes didn't break anything
6. Report final status: fixed / needs manual review / tests failing

Ví dụ đơn giản

Claude nhận toàn bộ nội dung file trên như prompt của bạn. Execute từng bước.

Tiết kiệm: Bạn không phải nhớ/gõ lại 6 bước mỗi lần. Team mới onboard cũng dùng được ngay.

/audit

Cách tạo command

Bước 1: Tạo folder

Trong project root:

Bước 2: Viết command file

Ví dụ tạo /write_tests:

mkdir -p .claude/commands

Bước 2: Viết command file

Mở file, viết:

touch .claude/commands/write_tests.md

Cách tạo command (tiếp)

Lưu ý $ARGUMENTS — placeholder. Bạn sẽ thấy ngay.

Bước 3: Restart Claude Code

Cần restart để Claude Code scan .claude/commands/ lại:

Write comprehensive tests for: $ARGUMENTS

Testing conventions:
- Use Vitest with React Testing Library
- Place test files in __tests__/ directory next to source
- Name test files as [filename].test.ts(x)
- Use @/ prefix for imports

Coverage requirements:
- Happy path (primary use case)
- Edge cases (empty, null, max value, boundary)
- Error states (network fail, invalid input, race condition)

Output:
- Create test file(s) in correct location
- Run `npm run test [file]` to verify
- Report coverage if available

Bước 3: Restart Claude Code

Bước 4: Dùng

/exit
claude   # hoặc ấn lại trong cùng terminal

Bước 4: Dùng

Claude nhận prompt = nội dung file + $ARGUMENTS được thay bằng "the useAuth hook in src/hooks/".

Thực sự prompt Claude thấy:

/write_tests the useAuth hook in src/hooks/

Cách tạo command (tiếp)

Write comprehensive tests for: the useAuth hook in src/hooks/

Testing conventions:
- Use Vitest with React Testing Library
- Place test files in __tests__/ directory next to source
...

$ARGUMENTS — Làm command linh hoạt

Cơ chế

$ARGUMENTS trong file markdown = phần text bạn gõ sau command name.

Nhiều cách dùng $ARGUMENTS

Dạng 1: File path

Gọi: /refactor src/services/payment.ts

Dạng 2: Task description

Command bạn gõ$ARGUMENTS =
/write_tests the Button componentthe Button component
/audit payments/payments/
/review_pr #1234 focus on security1234 focus on security
Refactor $ARGUMENTS following SOLID principles...

Nhiều cách dùng $ARGUMENTS

Gọi: /feature invoice export to CSV with filter by date range

Dạng 3: PR number / ID

Create a new feature: $ARGUMENTS

Follow these steps:
1. Design the API interface first
2. Write tests
3. Implement

$ARGUMENTS — Làm command linh hoạt (tiếp)

Gọi: /review_pr 1234

Dạng 4: Multiple args (tự parse)

Review pull request $ARGUMENTS. Focus on:
- Security implications
- Code quality
- Missing tests

$ARGUMENTS — Làm command linh hoạt (tiếp)

Gọi: /migrate postgres to mysql

Migrate database from $ARGUMENTS

If $ARGUMENTS is "postgres to mysql": follow migration-pg-mysql.md
If $ARGUMENTS is "sqlite to postgres": follow migration-sqlite-pg.md
...

Tổ chức command cho team

Structure khuyến nghị

Commit hay không?

Project .claude/commands/ → commit vào Git (shared team).

Personal commands: ~/.claude/commands/ (global, không project-specific) → không commit, cá nhân.

Quy tắc đặt tên

  • Dùng snake_case hoặc kebab-case nhất quán
  • Tên phải động từ + object: /write_tests, /audit, /deploy_check, /review_pr
  • Tránh tên mơ hồ: /helper, /util, /do_thing
  • Tránh conflict với built-in: /init, /clear, /compact, /hooks, /mcp, /model
<project>/
└── .claude/
    ├── commands/
    │   ├── _shared/           ← shared snippets (nếu cần)
    │   ├── audit.md
    │   ├── feature.md
    │   ├── review_pr.md
    │   ├── write_tests.md
    │   ├── deploy_check.md
    │   └── generate_changelog.md
    └── settings.json

Command templates nâng cao

Template 1: Multi-step với verification

Deploy Check Report ($TIMESTAMP)

[✓] Git state: clean, on main, synced [✓] Quality: typecheck + lint + test pass [✗] Security: 2 HIGH vulns in lodash (fix: npm update) [✓] Migrations: no pending [?] Changelog: empty unreleased section — please update

Status: BLOCKED (fix security first)

# /deploy_check

Pre-deployment safety check. Halt and report if ANY step fails.

## Steps

1. **Git state**
   - Branch: must be `main` or `release/*`
   - Status: must be clean (no uncommitted)
   - Latest: must be synced with origin

2. **Code quality**
   - `npm run typecheck` → must pass
   - `npm run lint` → must pass
   - `npm run test` → must pass

3. **Security**
   - `npm audit --audit-level=high` → no HIGH/CRITICAL
   - Check for leaked secrets: `grep -r "sk-ant\|api_key\|password" src/`

4. **Migrations**
   - Any pending migrations? Check `prisma/migrations/`
   - If yes, list them

5. **Changelog**
   - Does CHANGELOG.md have unreleased section with changes?

## Output format

Template 1: Multi-step với verification

Gọi: /deploy_check

Template 2: Context-aware feature

Template 2: Context-aware feature

Template 3: Delegate to subagent

# /feature

Implement feature: $ARGUMENTS

## Context gathering first

1. Read @CLAUDE.md to understand conventions
2. Read @docs/architecture.md if exists
3. Check @src/features/ for similar existing patterns

## Implementation approach

Follow test-driven development:
1. Write failing test first
2. Implement minimum code to pass
3. Refactor
4. Repeat until feature complete

## Deliverables

- [ ] Feature code in appropriate location
- [ ] Test file with ≥3 test cases (happy + edge + error)
- [ ] Update @docs/features.md if public API changed
- [ ] Run full test suite to confirm no regression

## Constraints

- Do NOT modify files outside feature scope
- Do NOT add new dependencies without asking
- Do NOT touch DB schema without confirmation

Template 3: Delegate to subagent

Template 4: Onboard newcomer

# /parallel_refactor

Refactor $ARGUMENTS in parallel using subagents.

## Plan

1. Analyze files in $ARGUMENTS to split work
2. Spawn subagents for independent pieces
3. Each subagent: refactor 1 file, report back
4. Main agent: integrate, run test, verify

## Safety

- Commit before start (checkpoint)
- If any subagent fails: rollback that file
- Never have 2 subagents editing same file

Template 4: Onboard newcomer

Gọi: /onboard (khi dev mới vào)

# /onboard

For a developer new to this codebase.

1. Explain project purpose in 2 sentences
2. Draw ASCII architecture diagram
3. List 5 most important files to read first, with reason
4. Identify 3 "gotchas" unique to this project
5. Suggest a beginner-friendly task from TODO list
6. Create onboarding-notes.md file with above content

Keep answers concise. Newcomer should be productive in <2 hours.

Ví dụ thực chiến: Command set cho team fintech

Tình huống

Team 12 dev, app fintech. Compliance cao, test coverage bắt buộc >85%. Deploy có nhiều check.

Command suite

Workflow cá nhân/dev với commands

Morning:

Feature work:

.claude/commands/
├── audit_security.md      — run security scan
├── audit_pii.md          — scan code for PII leak
├── feature.md            — TDD feature implementation
├── review_pr.md          — comprehensive PR review
├── deploy_check.md       — pre-deploy gate
├── gen_changelog.md      — generate from commits
├── add_migration.md      — scaffolded DB migration
├── explain_incident.md   — post-mortem template
└── onboard.md            — new dev walkthrough
/audit_security   # check overnight CVE news
/audit_pii        # make sure code clean

Workflow cá nhân/dev với commands

Review PR:

/feature add support for SEPA instant payment

Ví dụ thực chiến: Command set cho team fintech (tiếp)

Deploy:

/review_pr 1456

Ví dụ thực chiến: Command set cho team fintech (tiếp)

Onboard new hire:

/deploy_check
# If pass:
/gen_changelog

Ví dụ thực chiến: Command set cho team fintech (tiếp)

Kết quả sau 3 tháng

  • Time mỗi dev dành để "gõ setup prompt": từ 45 phút/ngày xuống 5 phút
  • Consistency: 12 dev output giống nhau trên pattern lặp
  • Onboard dev mới: từ 2 tuần xuống 4 ngày (nhờ /onboard)
  • Deploy failure: -60% (deploy check bắt lỗi sớm)
/onboard

Case studies theo ngành

💼 Sales engineering — /prep_demo

Prompt trong command: "Prepare demo for customer $ARGUMENTS. Pull relevant features, customize with their industry, generate talk track..."

⚖️ Legal tech — /check_contract_template

Prompt: "Review file $ARGUMENTS against canonical template. Flag missing clauses, deviations, risky language. Output diff + priority."

🏥 Health tech — /validate_fhir

Prompt: "Validate $ARGUMENTS against FHIR spec. Check required fields, reference integrity, terminology codes."

🎮 Game dev — /balance_check

Prompt: "Analyze $ARGUMENTS (character/weapon stats file). Compare vs meta, suggest tweaks if outlier."

📣 Marketing — /repurpose_post

Prompt: "Take $ARGUMENTS (blog post path) and create: LinkedIn post, Twitter thread, email snippet, slide outline. Maintain voice."

  • Kết quả: Demo prep time 2 tiếng → 15 phút.
  • Kết quả: Legal review 3 tiếng → 30 phút, catch rate cao hơn.
  • Kết quả: FHIR validation trước test → test pass rate 95% (từ 60%).
  • Kết quả: Game designer dùng command hàng ngày, balance patches ship tuần thay vì tháng.
  • Kết quả: 1 post → 4 channel, tốn 15 phút thay vì nửa ngày.

Anti-patterns

❌ Command quá generic

Biểu hiện: /help_me_with_code $ARGUMENTS — chỉ là paraphrase câu hỏi bình thường.

Tại sao sai: Không add value. Tốt như chat bình thường.

Cách đúng: Command phải encode quy trình cụ thể (các bước, convention, constraint).

❌ Hardcode đường dẫn cá nhân trong command

Biểu hiện: cat /Users/john/templates/report.md

Tại sao sai: Commit vào Git → teammate không dùng được.

Cách đúng: Dùng path relative từ project root hoặc @mention.

❌ Command không có verification

Biểu hiện: /feature chỉ yêu cầu "implement X" — không có test/typecheck.

Tại sao sai: Claude có thể "done" mà code sai; test/check không được validate.

Cách đúng: Mỗi command có step cuối verify (run test, typecheck, lint).

❌ Nhồi 5 task vào 1 command

Biểu hiện: /daily_routine = audit + review + deploy + changelog + onboard

Tại sao sai: Làm 5 việc không liên quan → Claude confuse, có thể skip bước.

Cách đúng: 1 command = 1 workflow coherent. Nếu cần chain, gọi tuần tự.

❌ Không update command khi convention đổi

Biểu hiện: /write_tests vẫn reference "Jest" sau khi team đã migrate Vitest.

Cách đúng: Đưa .claude/commands/ vào review checklist khi có major convention change.

Mẹo nâng cao

Mẹo 1: Command gọi command khác

Trong .claude/commands/release.md:

Mẹo 2: Conditional logic

Vì command là Markdown và Claude đọc nó, bạn có thể viết logic bằng natural language:

Run release pipeline:

1. First, call /audit_security and report findings
2. Then call /deploy_check  
3. If both pass, call /gen_changelog for version $ARGUMENTS
4. Finally, `git tag v$ARGUMENTS && git push origin v$ARGUMENTS`

Mẹo 2: Conditional logic

Claude sẽ "hiểu" và route đúng.

Mẹo 3: Nạp template bằng @

If $ARGUMENTS contains "hotfix":
  - Skip CHANGELOG generation (hotfix không cần)
  - Auto-add "hotfix" label
Else:
  - Full release flow

Mẹo 3: Nạp template bằng @

Mẹo 4: Meta-command /list_commands

Generate PR description using template @.github/PULL_REQUEST_TEMPLATE.md

Fill in sections based on $ARGUMENTS (branch name).

Mẹo 4: Meta-command /list_commands

# /list_commands

List all available custom commands in this project.
For each, show:
- Command name
- First line of description (from file)
- Expected $ARGUMENTS format

Format as markdown table.

Áp dụng ngay

Bài tập 1: Tạo command đầu tiên (15 phút)

Bước 1: Nghĩ về một task bạn gõ prompt Claude tương tự nhiều lần trong tuần. Ví dụ:

Bước 2: Tạo file .claude/commands/ten_cua_ban.md. Viết prompt đầy đủ, có bước, convention, output format.

Bước 3: Restart Claude Code.

Bước 4: Gọi command, test. Ghi:

Bước 5: Commit .claude/commands/ vào Git. Share với teammate.

Bài tập 2 (optional, 20 phút): Build bộ command cho team

Liệt kê 5 task lặp bạn hoặc team làm thường xuyên:

Tạo 5 command tương ứng. Run thử mỗi cái ít nhất 1 lần.

Tạo .claude/commands/README.md documentation cho team:

  • Commit message từ diff
  • Write test cho component mới
  • Explain code legacy
  • Output như expected? ☐ Có ☐ Không
  • Cần iterate thêm gì? ____________
  • ____________
  • ____________
  • ____________
  • ____________
  • ____________
  • Command nào làm gì
  • Argument syntax
  • Khi nào dùng

Tóm tắt bài học

🎯 Custom command = file Markdown trong .claude/commands/ — gõ /tên-file để gọi.

🎯 $ARGUMENTS = dynamic input — linh hoạt cho nhiều variation cùng command.

🎯 Commit .claude/commands/ = share team — consistency + onboarding nhanh.

🎯 Command tốt = encode quy trình cụ thể — không phải chỉ paraphrase prompt.

🎯 Tự động hóa sau 3 lần làm tay — không over-engineer sớm, không underutilize trễ.

Tài liệu tham khảo
  • Claude Code docs — Custom commands
  • Anthropic slash commands blog
  • Bài 4.6 — CLAUDE.md (config lâu dài)
  • Bài 4.10 — MCP (thêm capability, không chỉ encode prompt)
Nội dung này có hữu ích không?