Free

จาก Slash Commands สู่ Skills: เมื่อไหร่ควรย้าย และย้ายอย่างไร

custom commands ถูกรวมเข้ากับ Skills. เมื่อไหร่ควรย้ายไป `.claude/skills/` และได้อะไรเพิ่ม


สามบทความก่อนหน้าได้อธิบายวิธีใช้ slash command ครบถ้วนแล้ว: ตั้งแต่ไฟล์ Markdown ไปจนถึงการฉีด !command และการจัดวงดนตรีของ subagent กับ MCP เนื้อหาเหล่านั้นยังใช้ได้อยู่—แต่เบื้องหลัง ทีมทางการได้ทำการรวมไว้แล้ว: custom commands ได้ถูกผนวกเข้าไปใน Skills

ไฟล์ .claude/commands/review.md ของคุณยังรันได้ /review ยังใช้ได้ ไม่ต้องแก้อะไรเลย แต่ถ้าอยากให้ command เติบโตมีความสามารถมากขึ้น (หลายไฟล์ รันแบบ fork เปิดใช้อัตโนมัติตาม path) เส้นทางใหม่คือ .claude/skills/review/SKILL.md บทความนี้จะพูดให้ชัดสองเรื่อง: ย้ายอย่างไร และคุ้มที่จะย้ายไหม


การย้ายขั้นต่ำสุด: เปลี่ยนแค่ path เดียว ที่เหลือไม่ต้องแตะ

คำมั่นเรื่องความเข้ากันได้จากทางการชัดเจนมาก: .claude/commands/deploy.md และ .claude/skills/deploy/SKILL.md ทั้งคู่จะถูกลงทะเบียนเป็น /deploy และทำงานเหมือนกันทุกประการ เมื่อชื่อชนกัน skills จะได้รับความสำคัญก่อน

ขั้นตอนการย้ายขั้นต่ำสุด:

cd .claude/commands
mkdir -p ../skills/review
mv review.md ../skills/review/SKILL.md

เนื้อหาในไฟล์ไม่ต้องแก้แม้แต่บรรทัดเดียว YAML frontmatter, !`command`, @file, $ARGUMENTS—ทั้งหมดเข้ากันได้

แต่ถ้าทำแค่นั้น คนอ่านจะถามว่า: แล้วย้ายทำไม คำตอบคือ ไดเรกทอรีของ skill สามารถใส่ไฟล์ได้หลายไฟล์ ในขณะที่ command ใส่ได้แค่ไฟล์เดียว


ทำไมต้องย้าย: สี่สิ่งที่ SKILL.md เพิ่มเข้ามา

1. ไฟล์สนับสนุน: แยกเอกสารยาว ๆ ออกไป

SKILL.md คือทางเข้า ไดเรกทอรีเดียวกันใส่ไฟล์ประกอบอะไรก็ได้ ลองนึกภาพโครงสร้างแบบนี้:

.claude/skills/review/
├── SKILL.md            # ทางเข้า คำสั่งสั้น ๆ + การอ้างอิง
├── checklist.md        # checklist ตรวจ code ยาว ๆ
├── examples/
│   └── good-diff.md    # ตัวอย่างที่ดี
└── scripts/
    └── lint.sh         # script ที่ SKILL.md เรียกได้

ใน SKILL.md อ้างอิงด้วย path แบบ relative:

ตรวจสอบ diff ปัจจุบันตามมาตรฐานใน [checklist.md](checklist.md)
ดู [examples/good-diff.md](examples/good-diff.md) เพื่อเข้าใจรูปแบบ output ที่คาดหวัง

ไฟล์สนับสนุนเหล่านี้จะไม่ถูกโหลดเข้า context อัตโนมัติ—Claude จะอ่านเมื่อจำเป็นเท่านั้น คำแนะนำจากทางการคือให้คุม SKILL.md ไว้ไม่เกิน 500 บรรทัด ที่เหลือย้ายไปไว้ในไฟล์สนับสนุน

2. disable-model-invocation: skill ไหนที่คุณต้องเป็นคนกดเองเท่านั้น

โดย default เมื่อ Claude เห็นจังหวะเหมาะสม มันจะเรียก skill ใดก็ได้ด้วยตัวเอง สิ่งนี้อันตรายสำหรับ command ที่มีผลข้างเคียง เช่น /deploy, /commit, /send-email—คุณไม่อยากให้มัน "เห็นโค้ดดูดีก็เลยไป deploy เลย"

---
name: deploy
description: deploy ไปยัง production
disable-model-invocation: true
allowed-tools: Bash(kamal deploy:*), Bash(git push:*)
---

พอเติมบรรทัดนี้ /deploy จะถูกเรียกได้ก็ต่อเมื่อคุณพิมพ์เองเท่านั้น Claude จะไม่เรียกเองกลางบทสนทนา

ในทางกลับกัน user-invocable: false แปลว่า "Claude เท่านั้นที่เรียกได้ แต่จะไม่ปรากฏในเมนู /"—เหมาะกับ skill ประเภทความรู้เบื้องหลัง (เช่น legacy-system-context: ในสถานการณ์ที่เกี่ยวข้อง Claude จะโหลดเอง ส่วนคุณกดเองไม่มีความหมาย)

3. context: fork: ให้ skill รันใน subagent

นี่คือการอัปเกรดที่ใหญ่ที่สุด บทก่อนพูดว่า command สามารถใช้ allowed-tools: Task เพื่อให้โมเดลเปิด subagent ได้—แต่คุณต้องบรรยายใน prompt เองว่า "เปิด Explore subagent ทำ..."

SKILL จัดการได้ด้วย frontmatter บรรทัดเดียว:

---
name: deep-research
description: วิจัยเชิงลึกเกี่ยวกับสัญลักษณ์หนึ่ง
context: fork
agent: Explore
---

วิจัยการใช้งานทั้งหมดของ $ARGUMENTS:
- จุดที่ถูกเรียกทั้งหมด
- สถานการณ์ทางธุรกิจ
- การ implement ทางเลือก

ส่งคืนสรุปไม่เกิน 300 คำ

เมื่อกด /deep-research SomeClass: ทั้ง SKILL.md จะกลายเป็น prompt ของ subagent แยกอิสระ รันด้วย agent type Explore พอเสร็จส่งคืนแต่ข้อสรุป context ของบทสนทนาหลักสะอาดสนิท

เท่ากับว่าการ "เปิด subagent" เปลี่ยนจากข้อความบรรยายใน prompt มาเป็นแอตทริบิวต์ที่ประกาศของ skill

4. paths: เปิดใช้อัตโนมัติตามประเภทไฟล์

---
name: rails-conventions
description: แนวปฏิบัติการเขียนโค้ดสำหรับโปรเจกต์ Rails
paths: ["app/**/*.rb", "config/**/*.rb"]
---

ปฏิบัติตามแนวทาง Rails ของโปรเจกต์นี้:
- ใช้ service object แทน fat controller
- ActiveRecord scope ต้องมีชื่อ
...

เมื่อคุณกำลังแก้ไข app/models/user.rb skill นี้จะถูกเติมเข้า context อัตโนมัติ ส่วนการแก้ไข package.json จะไม่ถูกเติม แม่นยำกว่า CLAUDE.md ที่เป็นแบบ global—เปรียบเสมือน "CLAUDE.md แบ่งชั้นตาม path"


ลงมือจริง: อัปเกรด /plan ให้กลายเป็น skill

ตัวอย่าง /plan ตอนท้ายของบทก่อน เดิมทีเป็น command ไฟล์เดียว:

.claude/commands/plan.md

อัปเกรดเป็น skill:

.claude/skills/plan/
├── SKILL.md
├── research-prompt.md     # คำสั่งของ subagent 1
└── risk-prompt.md         # คำสั่งของ subagent 2

SKILL.md:

---
name: plan
description: สร้างแผนการดำเนินงานจาก Linear ticket
disable-model-invocation: true
allowed-tools: mcp__linear__*, Task, Read, Grep, Bash(git log:*)
---

## Context

@.claude/context/architecture.md

## สถานะ

!`git log --oneline -10`

## ภารกิจ

ดึงคำอธิบายและคอมเมนต์ของ Linear ticket $ARGUMENTS

ใช้ Task รัน subagent สองตัวขนานกัน:
1. วิจัยโค้ด: prompt ดูที่ [research-prompt.md](research-prompt.md)
2. ประเมินความเสี่ยง: prompt ดูที่ [risk-prompt.md](risk-prompt.md)

รวมผลทั้งสองแล้วออกเป็นขั้นตอนการดำเนินงาน + รายการความเสี่ยง + คำแนะนำเรื่อง granularity ของ commit

prompt ของ subagent ทั้งสองแยกไว้ในไฟล์ต่างหาก เวลาบำรุงรักษาแก้ที่เดียวไม่ต้องไปแตะ SKILL.md ตัว skill เองสะอาดภายใน 30 บรรทัด ส่วนไฟล์สนับสนุนแต่ละไฟล์จะยาวเป็นหลายร้อยบรรทัดก็ได้

ถ้าไม่อยากจัดการ subagent เอง จะเอาให้สุดยิ่งกว่า—โยนทั้ง skill เข้าไปใน fork ให้ Explore agent รันรวดเดียว:

---
name: plan
context: fork
agent: Explore
allowed-tools: mcp__linear__*
---

เมื่อกด /plan ENG-4213 → Explore agent ใน context อิสระรับเนื้อหาทั้ง SKILL.md เป็นภารกิจไปทำ → ส่งคืนแค่แผนสุดท้าย บทสนทนาหลักไม่เปื้อนเลย


เมื่อไหร่ที่ไม่จำเป็นต้องย้าย

ไม่ใช่ทุก command ที่ควรค่าแก่การอัปเกรด กรณีที่ยังเหมาะจะอยู่ใน .claude/commands/:

  • Markdown ไฟล์เดียวก็พอ: ไม่มี checklist, examples, scripts ที่ต้องแยกออก
  • ไม่จำเป็นต้องรันแบบ fork: ภารกิจผูกแน่นกับบทสนทนาหลัก ต้องเห็นประวัติทั้งหมด
  • ไม่จำเป็นต้องเปิดใช้อัตโนมัติตาม path: ผู้ใช้กดเองอยู่แล้ว
  • ไม่จำเป็นต้องควบคุมการเข้าถึง: ให้ Claude เรียกเองก็ไม่เกิดเรื่อง

/commit, /pr-desc แบบเรียบง่ายก็แค่ frontmatter กับ prompt ไม่กี่บรรทัด—อยู่ใน .claude/commands/ ยิ่งตรงไปตรงมา ทางการบอกไว้ชัดว่า ทั้งสองรูปแบบอยู่คู่กัน และไม่มีตัวไหนจะถูก deprecate


สถานะของการอยู่ร่วมกัน

การจัดระเบียบ .claude/ ที่สะอาดที่สุดตอนนี้:

.claude/
├── commands/           # เบา: ไฟล์เดียว + prompt ง่าย ๆ
│   ├── commit.md
│   └── pr-desc.md
├── skills/             # หนัก: หลายไฟล์ / fork / ควบคุมสิทธิ์
│   ├── plan/
│   │   ├── SKILL.md
│   │   ├── research-prompt.md
│   │   └── risk-prompt.md
│   ├── deploy/
│   │   └── SKILL.md    # disable-model-invocation
│   └── rails-conventions/
│       └── SKILL.md    # เปิดใช้อัตโนมัติผ่าน paths glob
└── context/
    └── coding-standards.md

อย่ายกโขยงย้ายทั้งหมด เงื่อนไขกระตุ้นให้ย้ายคือ "command นี้เริ่มบวม"—เนื้อหาเกิน 200 บรรทัด ต้องแยกเอกสาร อยากให้ subagent ไปทำ ถึงตอนนั้นค่อยเปลี่ยน path เรื่องแค่ไม่กี่นาที


สรุป

ความสามารถที่ต้องการ commands/ skills/
ทางลัด prompt ไฟล์เดียว
!`command` / @file / $ARGUMENTS
ควบคุมสิทธิ์ด้วย allowed-tools
ไฟล์สนับสนุน (reference, scripts)
disable-model-invocation ป้องกันถูกเรียกผิด
context: fork + agent: รันแบบแยก
เปิดใช้อัตโนมัติด้วย paths: glob

สามข้อแรก commands กับ skills เทียบเท่ากันทุกประการ สี่ข้อที่เหลือเป็นของ skills โดยเฉพาะ ต้องการอันไหนใช้อันนั้น ไม่ต้องการก็อย่าไปเสียเวลา

เส้นทางของทางการเริ่มเอียงไปทาง skills แต่คำมั่นเรื่องความเข้ากันได้ของ commands/ ชัดเจนมาก—นี่ไม่ใช่การเปลี่ยนแปลงแบบ "ย้ายทันทีไม่งั้นตกรุ่น" แต่เป็นการขยาย "ให้ความสามารถใหม่กับคุณแต่ไม่บังคับ" เข้าใจความต่าง ย้ายตามความจำเป็น อย่าไล่ตามความเป็นระเบียบบนเปลือก