Free

Slash Command ขั้นสูง: Subagent และการประสานเครื่องมือ

ใช้การอ้างอิง @file, allowed-tools, subagent และเครื่องมือ MCP เพื่ออัปเกรด slash command จากทางลัดเป็นคลัง workflow ของทีม


สองบทความแรกพูดถึงว่า slash command คืออะไร (ไฟล์ Markdown ไฟล์หนึ่ง) และวิธีใช้ prefix ! เพื่อฉีด output ของ shell เข้าไปใน context บทความนี้ไปไกลกว่านั้น: วิธีทำให้คำสั่งเดียวประสานความสามารถที่แข็งแกร่งที่สุดของ Claude Code — การอ้างอิงไฟล์, subagent, เครื่องมือ MCP — พร้อมคุมสิทธิ์ไว้ให้ได้

พอมาถึงชั้นนี้ command ก็ไม่ใช่แค่ "ทางลัดของ prompt" อีกต่อไป แต่กลายเป็น workflow ขนาดเล็กที่ใช้ซ้ำได้


การอ้างอิง @file: การฉีดเนื้อหาแบบคงที่ที่เหมาะกว่า !cat

!cat file.md สามารถยัดเนื้อหาของไฟล์เข้า context ได้ก็จริง แต่มันวิ่งผ่าน shell จึงมีข้อเสียอยู่หลายข้อ: ทุกครั้งที่เรียกต้องเปิด subprocess; ถ้า path ไฟล์มีช่องว่างหรืออักขระพิเศษก็ต้อง escape เพิ่ม; และ Claude Code จะไม่มอง path นั้นว่าเป็น "ไฟล์หนึ่งไฟล์" มันจะเป็นแค่ข้อความก้อนหนึ่งเท่านั้น

การอ้างอิง @ เป็นของ native:

---
description: รีวิวการเปลี่ยนแปลงตามมาตรฐานโปรเจกต์
---

อ้างอิงมาตรฐานต่อไปนี้:

@.claude/context/coding-standards.md
@.claude/context/security-checklist.md

ตอนนี้รีวิวการเปลี่ยนแปลงใน git diff และชี้ทุกจุดที่ละเมิดมาตรฐาน

!`git diff HEAD`

@path เป็นการบอก Claude Code ว่า "ให้แนบไฟล์นี้เข้ากับบทสนทนาเสมือนเป็น attachment" ความต่างอยู่ที่:

สถานการณ์ ใช้ !cat ใช้ @
Path มาจาก argument ($ARGUMENTS) ✅ ใช้ได้แค่ !cat @ ไม่รองรับการขยายตัวแปร
มาตรฐาน/เทมเพลตโปรเจกต์ที่คงที่ ⚠️ ใช้ได้แต่หนัก ✅ Native ประหยัดการเรียก shell
เนื้อหาไดนามิก (diff, log, ผลเทสต์) ✅ ต้อง ! ❌ ใช้ไม่ได้

กฎทั่วไป: ไฟล์คงที่ใช้ @, output ไดนามิกใช้ !, path ที่เป็นพารามิเตอร์ใช้ !cat $ARGUMENTS


allowed-tools: ตีเส้นขอบเขตสิทธิ์ให้ command

โดยดีฟอลต์ ตอนรัน command โมเดลจะใช้ได้ทุกเครื่องมือใน session นี่บางทีก็ไม่ใช่สิ่งที่คุณอยากได้ — เช่น /review เป็นงานรีวิวแบบ read-only คุณไม่อยากให้มัน "เผลอมือ" ไปแก้โค้ดแม้สักบรรทัด

ใส่ allowed-tools ใน frontmatter ตอน command กำลังทำงาน จะอนุญาตเฉพาะเครื่องมือที่อยู่ในรายชื่อเท่านั้น:

---
description: รีวิวโค้ดแบบอ่านอย่างเดียว
allowed-tools: Read, Grep, Glob, Bash(git diff:*), Bash(git log:*)
---

รีวิวความต่างระหว่างบรานช์ปัจจุบันกับ master อ่านอย่างเดียว ห้ามแก้

!`git diff master...HEAD`

จุดสำคัญ:

  • Bash(git diff:*) เป็นการให้สิทธิ์แบบละเอียด — อนุญาตเฉพาะคำสั่ง bash ที่ขึ้นต้นด้วย git diff, git push จะโดนบล็อก
  • Read / Grep / Glob ระบุชัดเจนว่าให้เฉพาะเครื่องมือ read-only
  • ไม่ได้ใส่ Edit / Write ไว้ ดังนั้นถึงโมเดลจะอยากแก้โค้ดก็เรียกไม่ได้

ในทางเดียวกัน command สิทธิ์สูงอย่าง /deploy ก็ให้สิทธิ์ย้อนทางได้:

---
description: Deploy บรานช์ปัจจุบัน
allowed-tools: Bash(kamal deploy:*), Bash(git push:*), Read
---

การเขียนตายตัวว่า "command นี้ทำอะไรได้บ้าง" เชื่อถือได้กว่าการพึ่งให้คนมานั่งรีวิว prompt bash แต่ละครั้งเป็นไหนๆ


การเรียก subagent: แยกงานที่กิน context ออกไปทำที่อื่น

งานบางประเภททำให้ context ของบทสนทนาหลักระเบิด — ไล่อ่านไฟล์หลายสิบไฟล์เพื่อหา call site ทุกจุดของฟังก์ชัน, รันสถิติ codebase, ดึง log ก้อนใหญ่มาวิเคราะห์ ถ้าทำตรงๆ ในบทสนทนาหลัก output หลายพันบรรทัดจะค้างอยู่ใน context แล้วบทสนทนาช่วงต่อไปก็จะช้าลงและโง่ลง

วิธีที่ถูกคือโยนงานแบบนี้ให้ subagent: subagent รันใน context ของตัวเอง พอรันเสร็จก็แค่หอบข้อสรุปกลับมาที่บทสนทนาหลัก ใน command แค่สั่งให้ชัดเจนเท่านั้น:

---
description: สำรวจทุกการใช้งานของสัญลักษณ์อย่างลึก
allowed-tools: Task
---

ใช้ Explore subagent สำรวจทุกการใช้งานของสัญลักษณ์ต่อไปนี้อย่างลึก: $ARGUMENTS

ให้ subagent ครอบคลุม:
- call site ทุกจุด (รวมไฟล์เทสต์)
- สถานการณ์ทางธุรกิจที่ครอบคลุม
- มีการ implement ทางเลือกที่เทียบเท่ากันหรือไม่

หลัง subagent กลับมา ให้ฉันเฉพาะสรุปความยาว ≤300 คำ อย่าแปะโค้ดดิบๆ

ทริก /trace SomeClass#some_method แล้ว Claude Code จะเปิด Explore subagent กวาด codebase แบบขนาน บทสนทนาหลักรับแค่ข้อสรุปที่กลั่นแล้ว ไม่มี output จาก grep ไม่มี snippet ของไฟล์ context ก็สะอาด

การเล่นที่สูงขึ้นไปอีก:

---
description: สำรวจทางเลือกสามแบบแบบขนาน
allowed-tools: Task
---

เปิด 3 subagent พร้อมกัน สำรวจเส้นทางการ implement สามแบบต่อไปนี้:

1. ใช้ ActiveJob + Sidekiq ที่มีอยู่แล้ว
2. ใช้ Solid Queue
3. สร้าง queue น้ำหนักเบาขึ้นเอง

แต่ละ agent ตอบ: ปริมาณงาน, ความเสี่ยง, ระดับการแทรกซึมเข้าโค้ดเดิม หลังได้ข้อสรุปทั้งสามฝั่งกลับมา เดี๋ยวฉันจะเอามาเทียบเอง

สาม subagent รันขนานกัน บทสนทนาหลักรอผลแค่รอบเดียว นี่คือ leverage ที่ใหญ่ที่สุดตัวหนึ่งที่ command ให้ได้ — แปลงงานวิจัยที่ "ต้องใช้ token เยอะมากกว่าจะได้ข้อสรุป" ให้กลายเป็น workflow แบบแตะครั้งเดียว


การเรียกเครื่องมือ MCP: ให้ command เอื้อมไปยังระบบภายนอก

ถ้า session เชื่อมต่อกับ MCP server (Linear, GitHub, Sentry, proxy ฐานข้อมูลที่สร้างเอง ฯลฯ) command ก็สั่งโมเดลเรียกเครื่องมือเหล่านี้ได้ตรงๆ:

---
description: สร้าง todo การ implement จาก Linear issue
allowed-tools: mcp__linear__*, Read, Grep
---

อ่านรายละเอียดและคอมเมนต์ทั้งหมดของ Linear issue $ARGUMENTS

เอามาผสมกับสถานะปัจจุบันของ codebase (ใช้ Grep/Read หาไฟล์ที่เกี่ยวข้องเอง) แล้วเรียงเป็น todo การ implement:
- ต้องแก้ไฟล์ไหนบ้าง
- แต่ละขั้นแยก commit หรือรวมกัน
- มีจุดคลุมเครือที่ต้องเคลียร์กับ PM ก่อนไหม

อย่าเพิ่งเขียนโค้ด ออกแค่แผน

mcp__linear__* ให้สิทธิ์เครื่องมือ Linear MCP ทั้งหมด โมเดลจะดึงรายละเอียด issue, คอมเมนต์, สถานะได้ ทั้ง command นี้จึงกลายเป็นจุดเริ่ม workflow "จาก ticket สู่แผนการ implement"

จุดสำคัญ: เวลาเขียนชื่อเครื่องมือ MCP ใน allowed-tools ต้องใช้ prefix เต็มของมัน (mcp__<server>__<tool>) ไม่อย่างนั้นสิทธิ์จะไม่มีผล


กับดักของการคอมโพส command: slash ไม่ขยายแบบรีเคอร์ซีฟ

ความเข้าใจผิดที่เจอบ่อยมาก: เขียน /test ในไฟล์ของ /review แล้วคิดว่าจะไปทริก test command ไม่ไปทริก slash command จะถูกขยายแค่ครั้งเดียวในชั้น input ระดับบนสุดของผู้ใช้เท่านั้น; /xxx ที่อยู่ใน command เป็นแค่ข้อความธรรมดา โมเดลจะอ่านมันได้ แต่ Claude Code ไม่ไปรันให้

ถ้าอยากคอมโพสหลาย command วิธีที่ถูกมีหลายแบบ:

วิธี A: แยก logic ที่ใช้ร่วมเป็นไฟล์ context แต่ละ command ก็ใช้ @ หรือ !cat อ้างอิง

@.claude/context/review-checklist.md
@.claude/context/security-checklist.md

วิธี B: ใน command เขียนตรงๆ ว่า "ทำเหมือน /review" + ทวนคำสั่งสำคัญซ้ำ

ไม่สง่างามแต่ใช้ได้ แค่ prompt ชัดเจนพอ โมเดลก็จะทำตามแนวทางเดิม

วิธี C: ให้ command หนึ่งใช้เครื่องมือ Task เปิด subagent แล้วใน prompt ของ subagent ก็เรียกใช้ชุดไฟล์ context ชุดเดียวกันอีกที

การประสาน workflow จริงๆ ใช้เส้นทางนี้ทั้งหมด command แม่ทำหน้าที่จัดคิวและสรุป ส่วน subagent ทำหน้าที่รันขั้นตอนจริง

Anti-pattern ที่ต้องเลี่ยง: เขียน command ยาวเป็นร้อยบรรทัด พยายามให้คำสั่งเดียวทำทุกอย่างจบ พอ granularity ระเบิดแล้วต้นทุนการดูแลจะพุ่ง และงบ token ต่อรอบก็จะถูก command ตัวเดียวกินเกลี้ยง


เวลาที่ควรใช้สามเกลอ

เขียนมาถึงตรงนี้ กลไกการฉีด "ความสามารถภายนอก" เข้ากับ command ใน Claude Code ก็ครบแล้ว เลือกใช้งานยังไง:

ความต้องการ กลไกที่ควรเลือก
มาตรฐาน/เทมเพลต/เอกสาร context ที่คงที่ การอ้างอิง @file
สถานะ real-time (diff, log, ผลเทสต์, query DB) การฉีด !shell
เนื้อหาไฟล์ที่เป็นพารามิเตอร์ !cat $ARGUMENTS
งานวิจัยกิน context, ค้นหาข้ามไฟล์ subagent ผ่าน Task
ระบบภายนอก (issue tracker, monitoring, ข้อมูล production) เครื่องมือ MCP + allowed-tools
Workflow หลายขั้นแบบต่อเนื่อง/ขนาน command แม่เรียก subagent

ขอบเขตสิทธิ์ประกาศชัดเจนผ่าน allowed-tools โดยเฉพาะ command ที่ใช้ร่วมกันในทีม — เขียนล็อกไว้ว่ามันทำอะไรได้ เชื่อถือได้กว่าพึ่งการอนุมัติด้วยมือทุกครั้ง


ตัวอย่างใกล้เคียงโปรดักชัน

เอาทุกอย่างมารวมกัน ดู command "สำรวจเส้นทางการ implement จาก Linear ticket" กัน:

---
description: สร้างแผนการ implement จาก Linear ticket
allowed-tools: mcp__linear__*, Task, Read, Grep, Glob, Bash(git log:*)
---

## Context

@.claude/context/architecture.md
@.claude/context/coding-standards.md

## สถานะ codebase ปัจจุบัน

!`git log --oneline -10`

## ภารกิจ

ดึงรายละเอียด, คอมเมนต์, และ ticket ที่เกี่ยวข้องของ Linear ticket $ARGUMENTS

จากนั้นเปิด subagent สองตัวรันขนานกัน:
1. ตัวแรก: ไปหาใน codebase ว่ามี implementation ที่เกี่ยวข้องอะไรอยู่แล้วบ้าง มีโมดูลที่ใช้ซ้ำได้ไหม
2. ตัวที่สอง: ประเมินความเสี่ยง — การเปลี่ยนแปลงครั้งนี้จะไปแตะเส้นทางโค้ดที่ traffic สูงตัวไหน มีช่องโหว่ test coverage ตรงไหน

หลังทั้งสอง agent กลับมา ออกผลลัพธ์:
- ขั้นตอนการ implement (เรียงตามลำดับ dependency)
- รายการความเสี่ยง
- ระดับ granularity ของ commit ที่แนะนำ

ยังไม่ต้องเขียนโค้ด

ทริก /plan ENG-4213 คำสั่งเดียวรันจบหมด: ดึง ticket → สำรวจ codebase แบบขนาน → ประเมินความเสี่ยง → สรุปแผน ผู้ใช้มีหน้าที่แค่อ่านข้อสรุปแล้วตัดสินใจว่าจะลงมือ


นี่คือเส้นโค้งที่ครบถ้วนของ slash command สามบทแรก: นิยาม prompt ที่ใช้ซ้ำได้ (intro) → ฉีด context แบบไดนามิก (context) → ประสานเครื่องมือและ subagent (บทนี้) พอมาถึงชั้นนี้ .claude/commands/ ก็ไม่ใช่ทางลัดอีกต่อไปแล้ว แต่เป็นคลัง workflow ขนาดเล็กของทีม