🧰 ของที่ใช้ในบทนี้ (ตรวจวันที่ 22 สิงหาคม 2026)
github.com/mattpocock/skills # อ่าน README ของจริงเพื่อยืนยันคำสั่งติดตั้ง
skills ที่ติดตั้งไว้บนเครื่องผม # 32 โฟลเดอร์ ใน ~/.agents/skills/
# ลงด้วยเส้นทาง npx (symlink) ไม่ใช่เส้นทาง plugin
บทนี้ไม่มีโค้ด Go — ตัวเลขทุกตัวที่โผล่มาเป็นการวัดไฟล์ skill จริงด้วย
wc -c ซึ่งคุณรันตามได้ถ้าติดตั้ง skill ชุดเดียวกัน
สิ่งที่ผมยืนยันไม่ได้ในเซสชันนี้: คำสั่ง claude plugins install
ผมรันไม่ได้เพราะ claude ไม่ได้อยู่ใน PATH ของ shell ที่ผมใช้ตรวจ —
ผมจึงยืนยันคำสั่งนั้นจากการอ่าน README ของ repo เท่านั้น ไม่ได้รันเอง
ส่วนชื่อ skill ทั้งสี่ตัว ผมเปิดไฟล์จริงบนเครื่องอ่าน — ไม่ได้เชื่อสไลด์อย่างเดียว
1 · ทำไมบทที่ไม่มี Go ถึงอยู่ในคอร์ส Go
ตลอด 53 บทที่ผ่านมา เราถามว่า "เขียนยังไงให้ถูก"
บทนี้ถามคนละคำถาม: "ใครเขียน แล้วใครตรวจ"
เหตุผลที่คำถามนี้สำคัญพอจะกินเวลา 14 หน้าสไลด์ คือความเร็ว
agent เขียน CRUD หนึ่งชุดเสร็จในเวลาที่คุณยังอ่าน spec ไม่จบ —
ซึ่งฟังดูดี จนกระทั่งคุณนึกออกว่าของที่โตเร็วขึ้นไม่ได้มีแค่ฟีเจอร์
หนี้ทางเทคนิคก็โตเร็วขึ้นด้วยอัตราเดียวกัน
เครื่องมือที่ทำให้คุณผลิตโค้ดเร็วขึ้น 10 เท่า
ก็ทำให้คุณผลิตโค้ดที่ผิดเร็วขึ้น 10 เท่าเหมือนกัน
สิ่งที่ไม่ได้เร็วขึ้นตามอัตโนมัติคือความสามารถในการตรวจ —
และนั่นคือช่องว่างที่ทั้งบทนี้พยายามปิด
2 · สามโหมดที่สไลด์แบ่งไว้
สไลด์ไม่ได้อธิบายทฤษฎีอะไร มันแค่ทำงานให้ดูทีละ endpoint แล้วติดป้ายโหมดไว้มุมบนขวา
ผมไล่ทั้ง 14 หน้าออกมาเป็นตารางให้เห็นภาพรวมทีเดียว:
| หน้าสไลด์ | ป้ายโหมด | งานที่ทำ |
|---|---|---|
| 55 | Self Coding | Implement · Create recipes |
| 56 | Self Coding | Implement · Get recipes |
| 57 | Pure Agent | Generate · Get recipe by id |
| 58–63 | แทรกเรื่อง agent skills กับวิธีติดตั้ง (หัวข้อ 4–7 ของบทนี้) | |
| 64 | Pure Agent & Review | Generate · Get recipe by id (ซ้ำกับหน้า 57) |
| 65 | Pure Agent & Review | Generate · Update recipe by id |
| 66 | Pure Agent & Review | Generate · Delete recipe by id |
| 67 | Pure Agent & Review | Generate · Get my profile |
| 68 | Pure Agent & Review | Generate · Update my profile |
📌 สังเกตแถวที่ผมเน้นไว้ — Get recipe by id โผล่สองครั้ง
ครั้งแรกในโหมด Pure Agent (หน้า 57) ครั้งที่สองในโหมด Pure Agent & Review (หน้า 64)
นี่ไม่ใช่สไลด์พิมพ์ซ้ำ แต่คืองานเดียวกันทำสองรอบด้วยสองโหมด —
ซึ่งเป็นวิธีเทียบที่ตรงที่สุด เพราะตัวแปรที่ต่างมีตัวเดียวคือ "มีรีวิวหรือไม่มี"
ถ้าคุณอยากได้อะไรกลับบ้านจากบทนี้จริง ๆ ให้ทำแบบนี้: ทำงานเดิมสองรอบ แล้วเทียบ diff
คำว่า Implement กับ Generate ต่างกันตรงไหน
สังเกตอีกจุดในตาราง: สองหน้าแรกใช้คำว่า Implement ส่วนหน้าที่เหลือใช้ Generate
ไม่ใช่คำสวย ๆ — มันบอกว่าใครเป็นคนพิมพ์
| คำ | ใครลงมือ | หน่วยของงานที่คุณจับต้อง |
|---|---|---|
| Implement | คุณ | บรรทัดโค้ด — คุณตัดสินใจทีละบรรทัด และรู้ว่าทำไมมันถึงเป็นแบบนั้น |
| Generate | agent | prompt กับ diff — คุณตัดสินใจแค่สองจุด: สั่งว่าอะไร และรับ/ไม่รับผลที่ได้ |
ตรงนี้คือจุดที่คนใหม่พลาดบ่อยที่สุด: พอย้ายมาโหมด Generate แล้ว
งานของคุณไม่ได้หายไป มันย้ายที่
จากเดิมที่ใช้เวลาไปกับ "พิมพ์ให้ถูก" กลายเป็นใช้เวลาไปกับ
"สั่งให้ชัด" และ "อ่าน diff ให้เป็น" — ซึ่งเป็นทักษะคนละตัวกัน และไม่ได้มาฟรี
3 · โหมดไหนเหมาะกับงานแบบไหน และเสี่ยงอะไร
สไลด์ไม่ได้เขียนตารางนี้ไว้ให้ — มันแค่ทำให้ดู
ผมสรุปเป็นตารางเพื่อให้ตัดสินใจได้เองในโปรเจกต์จริง โดยอ่านจากลำดับที่สไลด์เลือกใช้:
| โหมด | เหมาะกับงานแบบไหน | ความเสี่ยงหลัก | อะไรลดความเสี่ยงลงได้ |
|---|---|---|---|
| Self Coding เขียนเองทุกบรรทัด |
งานชิ้นแรกของ resource ที่ยังไม่มีแบบในโปรเจกต์ให้ลอก · งานที่คุณยังไม่เข้าใจและต้องเข้าใจ · จุดที่ตัดสินใจเรื่องโครงสร้าง (จะแบ่ง layer ยังไง error จะห่อแบบไหน) | ช้า — และถ้าคุณวางโครงผิดตั้งแต่ชิ้นแรก โครงที่ผิดนั้นจะกลายเป็นแบบที่ agent ลอกต่อไปทั้ง resource | ทำชิ้นแรกให้ถูกจริง ๆ ก่อน แล้วค่อยส่งต่อ · ถือว่าโค้ดชิ้นแรกคือเอกสารที่ agent จะอ่าน ไม่ใช่แค่โค้ด |
| Pure Agent สั่งแล้วรับผลไปเลย |
งานที่"เหมือนของเดิม" ชัด ๆ — มีแบบอยู่แล้วในโปรเจกต์ · โค้ดที่ทิ้งได้ (prototype, script ใช้ครั้งเดียว, ไฟล์ทดลอง) | โค้ดที่อ่านผ่านตาแล้วดูถูก แต่ผิด spec · complexity โตขึ้นเงียบ ๆ ทีละนิดจนกลายเป็น ball of mud · และคุณไม่รู้ว่าตัวเองไม่รู้อะไร เพราะไม่ได้อ่าน | จำกัดขอบเขตใน prompt — สไลด์หน้า 54 มีตัวอย่างท่านี้ตรง ๆ (ดูกล่องข้างล่าง) |
| Pure Agent & Review agent ทำ แล้วอ่าน diff ก่อน commit |
ทุกอย่างที่จะขึ้น production · และทุกครั้งที่งานนั้นมี "ของเดิม" ให้กระทบ | รีวิวแบบผ่าน ๆ — พอ diff ยาว 400 บรรทัด คนกด approve เร็วกว่าอ่าน · รีวิวที่ไม่ได้อ่านจริงแย่กว่าไม่รีวิว เพราะมันสร้างความมั่นใจปลอม | ให้ skill รีวิวรอบแรกอย่างเป็นระบบ แล้วคุณอ่านเฉพาะจุดที่มันชี้ — หัวข้อ 6 ว่าด้วยเรื่องนี้ |
ตัวอย่าง prompt จำกัดขอบเขต จากสไลด์หน้า 54 (Migrate recipes) — อ่านให้ดีว่าครึ่งหลังทำอะไร:
# Prompt
สร้างไฟล์ migrations ตาม docs/ARCHITECTURE.md
โดยให้ทำเพียงสร้างไฟล์อย่างเดียวเท่านั้นเพื่อนำไปรีวิวก่อน
ไม่ต้องตรวจสอบและ migrate จริง
ประโยคแรกบอกงาน ประโยคที่สองบอกเพดาน —
"สร้างไฟล์อย่างเดียว ห้ามรันจริง"
ทำไมถึงสำคัญ: migrate คือคำสั่งที่ย้อนกลับยาก
ถ้า agent เดาผิดแล้วรันไปแล้ว คุณไม่ได้แค่ลบไฟล์ทิ้ง — คุณต้องแก้ฐานข้อมูล
กฎที่ใช้ได้จริง: ทุก prompt ที่งานมีผลข้างเคียงถาวร
(แก้ DB · ลบไฟล์ · ยิง API จริง · git push) ให้เขียนเพดานไว้เสมอ
ว่าให้หยุดตรงไหนเพื่อรอรีวิว
สมมติคุณรับหน้าที่หาข้าวเที่ยงให้เพื่อนร่วมทีม 10 คน มีสามท่าให้เลือก:
· ทำเองที่บ้าน — ช้าที่สุด แต่คุณรู้ทุกอย่างที่ใส่ลงไป → Self Coding
· สั่งเดลิเวอรี่แล้ววางบนโต๊ะเลย — เร็วที่สุด
แต่ถ้าร้านใส่กุ้งมาในกล่องของคนแพ้กุ้ง คุณจะรู้ตอนเขากินไปแล้ว → Pure Agent
· สั่งเดลิเวอรี่ แล้วเปิดฝาดูทุกกล่องก่อนวาง —
ช้ากว่าท่าที่สองนิดเดียว แต่จับของผิดได้ก่อนถึงปาก → Pure Agent & Review
สังเกตว่าท่าที่สามไม่ได้แปลว่า "ไม่ไว้ใจร้าน" — มันแปลว่าของที่กินแล้วย้อนไม่ได้ ต้องดูก่อน ซึ่งเป็นเหตุผลเดียวกับที่ prompt ในกล่องข้างบนสั่งว่า "สร้างไฟล์อย่างเดียว ไม่ต้อง migrate จริง"
ที่ไม่เหมือนกัน: เปิดฝากล่องข้าวใช้เวลา 3 วินาที
และของผิดมองเห็นด้วยตา — แต่ diff ยาว 400 บรรทัดใช้เวลาอ่านจริง
และโค้ดที่ผิด spec หน้าตาเหมือนโค้ดที่ถูกทุกประการ
นี่คือเหตุผลที่ตารางข้างบนเขียนว่า "รีวิวแบบผ่าน ๆ แย่กว่าไม่รีวิว" —
กล่องข้าวไม่มีปัญหานี้ แต่ diff มี
- diff
- "ส่วนที่ต่าง" ระหว่างโค้ดก่อนแก้กับหลังแก้ — ไม่ใช่โค้ดทั้งไฟล์ · พิมพ์สั่ง AI ได้เลยว่า "ขอดู diff ก่อน ยังไม่ต้อง commit" หรือกับรุ่นพี่ว่า "ช่วยอ่าน diff ให้หน่อย ดูไม่ออกว่ามันเพิ่มอะไร"
- scope
- ขอบเขตของงาน — เส้นที่บอกว่างานนี้ครอบคลุมถึงไหน และหยุดตรงไหน · พิมพ์ต่อท้าย prompt ได้เลยว่า "ทำแค่สร้างไฟล์อย่างเดียว ห้ามรันคำสั่งใด ๆ" · เวลา senior พูดว่า "อันนี้ out of scope นะ" แปลว่า "เกินจากที่ตกลงกันไว้"
- side effect
- ผลข้างเคียงที่คำสั่งทิ้งไว้กับโลกภายนอก และมักย้อนกลับยาก —
แก้ฐานข้อมูล · ลบไฟล์ · ยิง API จริง ·
git push· ถามก่อนลงมือได้ว่า "คำสั่งนี้มี side effect อะไรบ้าง ถ้ารันผิดย้อนได้ไหม" - ball of mud
- codebase ที่ทุกส่วนพันกันจนแยกไม่ออก แก้ที่หนึ่งพังอีกที่ · เป็นคำที่ dev ใช้จริงตอนรีวิว: "ถ้าปล่อยแบบนี้ไปอีกสามเดือน มันจะกลายเป็น ball of mud"
4 · Agent skill คืออะไร
ก่อนอ่านเหตุผล ต้องรู้ก่อนว่าหน้าตามันเป็นยังไง เพราะมันเรียบง่ายกว่าที่ชื่อทำให้คิด
Skill คือโฟลเดอร์หนึ่งโฟลเดอร์ ที่มีไฟล์ชื่อ SKILL.md อยู่ข้างใน จบแค่นั้น
ข้างในไฟล์แบ่งเป็นสองส่วน — ส่วนหัวที่คั่นด้วย ---
(เรียกว่า front matter) กับเนื้อความที่เป็น Markdown ธรรมดา
นี่คือ 4 บรรทัดแรกของ skill ชื่อ tdd ที่ติดตั้งอยู่บนเครื่องผมจริง ๆ:
$ head -4 ~/.agents/skills/tdd/SKILL.md
---
name: tdd
description: Test-driven development. Use when the user wants to build features or fix bugs test-first, mentions "red-green-refactor", or wants integration tests.
---
สองบรรทัดใน front matter ทำหน้าที่ต่างกันคนละขั้ว และนี่คือหัวใจของทั้งเรื่อง:
| บรรทัด | ใครอ่าน และอ่านตอนไหน |
|---|---|
name |
ชื่อที่ใช้เรียก skill — เช่นพิมพ์ /tdd |
description |
agent เห็นบรรทัดนี้ตลอดเวลา ของทุก skill — มันคือป้ายที่บอกว่า "งานแบบไหนถึงควรหยิบฉันมาใช้" (ในวงการเรียกว่า trigger) |
เนื้อความข้างล่าง --- |
agent อ่านเฉพาะตอนที่ตัดสินใจหยิบ skill นี้มาใช้แล้วเท่านั้น |
4 เหตุผลที่สไลด์ยกมา (หน้า 58)
| เหตุผล | แปลว่าอะไร |
|---|---|
| Progressive disclosure (ทยอยเปิดเผย) |
agent ไม่ต้องโหลดทุก instruction เข้า context ตลอดเวลา
แต่จะ "ดึง" skill ที่เกี่ยวข้องมาใช้เฉพาะตอนที่งานตรงกับ trigger เท่านั้น
— ประหยัด token
(context = ข้อความทั้งหมดที่ agent มองเห็นในรอบนั้น ซึ่งมีเพดานจำกัด · token = หน่วยที่ใช้นับปริมาณข้อความ) |
| ความสม่ำเสมอ (consistency) |
ไม่ว่าจะรันกี่ session หรือใครเป็นคนสั่ง agent ก็ทำตาม process เดิมทุกครั้ง
— ไม่ต้องพิมพ์อธิบายซ้ำทุกรอบ
(session = การคุยกับ agent หนึ่งรอบ ซึ่งจบแล้วมันจำอะไรไม่ได้) |
| แก้ failure mode เฉพาะจุด | เช่น agent เขียนโค้ดมั่ว · debug มั่ว · ไม่ตรง spec · code สกปรกขึ้นเรื่อย ๆ
skill คือ "วินัย" ที่บังคับ flow ให้ agent เดินตามขั้นตอนที่ พิสูจน์แล้วว่าได้ผลดีกว่า (failure mode = ท่าพังประจำ ไม่ใช่ bug ตัวเดียว แต่เป็นแบบของการพังที่เกิดซ้ำ ๆ) |
| Reusable & portable | เขียนครั้งเดียว ใช้ได้ทุกโปรเจกต์ ทุก session และถ้าเขียนแบบ agent-agnostic (ไม่ผูกกับ agent ยี่ห้อใดยี่ห้อหนึ่ง) ก็ใช้ได้กับหลาย coding agent ไม่ใช่แค่ Claude |
5 · Progressive disclosure วัดออกมาเป็นตัวเลขได้
ข้อแรกในสี่ข้อนั้นเป็นข้อเดียวที่วัดได้ตรง ๆ — ไม่ต้องเชื่อ ไม่ต้องเถียง
วิธีวัด: เทียบขนาดของบรรทัด description (ของที่ agent แบกไว้ตลอดเวลา)
กับขนาดของเนื้อหาทั้งโฟลเดอร์ (ของที่มันดึงมาเฉพาะตอนใช้)
ทายก่อนรัน — ผมวัด skill ทั้งสี่ตัวที่คอร์สนี้จะใช้ ด้วยคำสั่งนี้ (นับเป็น ไบต์ ไม่ใช่ token)
$ cd ~/.agents/skills
$ for s in tdd diagnosing-bugs codebase-design code-review; do
printf '%-16s desc=%4s SKILL.md=%5s ทั้งโฟลเดอร์=%6s\n' "$s" \
"$(grep -m1 '^description:' $s/SKILL.md | wc -c | tr -d ' ')" \
"$(wc -c < $s/SKILL.md | tr -d ' ')" \
"$(cat $(find -L $s -type f) | wc -c | tr -d ' ')"
done
ทายว่าบรรทัด description ทั้งสี่ตัวรวมกัน คิดเป็นกี่เปอร์เซ็นต์ของเนื้อหาทั้งหมด
เลือกจากช่วงนี้: ราว ๆ 30% · ราว ๆ 10% · ราว ๆ 3% · ต่ำกว่า 1%
และคำถามที่สำคัญกว่า: ถ้าเปอร์เซ็นต์นี้ต่ำมาก มันแปลว่าอะไรกับคนที่เขียน skill?
tdd desc= 163 SKILL.md= 3568 ทั้งโฟลเดอร์= 7350
diagnosing-bugs desc= 170 SKILL.md= 8536 ทั้งโฟลเดอร์= 9803
codebase-design desc= 279 SKILL.md= 6488 ทั้งโฟลเดอร์= 11861
code-review desc= 434 SKILL.md= 6731 ทั้งโฟลเดอร์= 6831
รวม description ทั้งสี่ = 1,046 ไบต์ ·
รวมเนื้อหาทั้งหมด = 35,845 ไบต์ → ประมาณ 2.9%
ผมวัดซ้ำกับทั้ง 32 skillที่ติดตั้งอยู่บนเครื่องด้วยวิธีเดียวกัน ได้
5,386 ไบต์ จาก 250,847 ไบต์ = ประมาณ 2.1%
(32 ตัวนี้ไม่ได้มาจาก repo เดียว — ผมเช็ค tree ของ
mattpocock/skills วันนี้แล้วมี 7 ตัวบนเครื่องผมที่ไม่ได้อยู่ในนั้น
คือ caveman · diagnose · to-issues · to-prd ·
write-a-skill · writing-great-skills · zoom-out ·
ส่วนหัวข้อ Reference ใน README ของ repo นับได้ 25 ตัวพอดี)
แปลตรง ๆ: agent แบกไว้ตลอดเวลาแค่ราว 2% ของเนื้อหาทั้งหมด
อีก 98% ถูกดึงมาเฉพาะตอนที่งานตรงกับ trigger
ถ้าไม่มีกลไกนี้ เนื้อหา 250 กิโลไบต์จะต้องอยู่ใน context ทุกรอบ
ทั้งรอบที่คุณแค่ถามว่าไฟล์นี้ทำอะไร
ผมวัดเป็นไบต์ ไม่ใช่ token — สองอย่างนี้ไม่เท่ากัน
และอัตราแปลงก็ไม่คงที่ (ภาษาอังกฤษกับภาษาไทยแปลงได้คนละอัตรา)
ตัวเลข 2% จึงใช้บอกลำดับความใหญ่ได้ แต่อย่าเอาไปคำนวณค่าใช้จ่ายตรง ๆ
อีกจุดที่ต้องซื่อสัตย์: grep | wc -c นับทั้งบรรทัดรวมคำว่า
description: และตัวขึ้นบรรทัดใหม่ด้วย — ตัวเลขจึงสูงกว่าตัว description เปล่า ๆ นิดหน่อย
แล้วมันแปลว่าอะไรกับคนเขียน skill? แปลว่า description
คือบรรทัดที่สำคัญที่สุดในไฟล์ —
ถ้ามันเขียนไม่ชัดว่างานแบบไหนควรหยิบ skill นี้ agent จะไม่มีวันเปิดอ่านอีก 98% ที่เหลือเลย
เนื้อหาดีแค่ไหนก็ไม่มีความหมาย ถ้าป้ายหน้าประตูเขียนไม่ชัด
ร้านตามสั่งหน้าปากซอยติดป้ายเมนูไว้ 40 อย่าง ป้ายทั้งป้ายกวาดตาทีเดียวก็อ่านจบ
แต่ "วิธีทำ" ของทั้ง 40 เมนูนั้นไม่ได้อยู่บนป้าย — มันอยู่ในหัวแม่ครัว
และถูกดึงออกมาใช้เฉพาะเมนูที่มีคนสั่งเท่านั้น
· ป้ายเมนู = บรรทัด description ของทุก skill — agent แบกไว้ตลอดเวลา
· สูตรในครัว = เนื้อความใต้ --- กับไฟล์ลูก — เปิดอ่านเฉพาะตอนงานตรงกับ trigger
ตัวเลขที่วัดได้ข้างบนก็คือสัดส่วนนี้พอดี: ป้ายกินที่ราว 2% ที่เหลืออีก 98% อยู่ในครัว
ที่ไม่เหมือนกัน: ลูกค้าที่อ่านป้ายแล้วงง
เดินเข้าไปถามแม่ครัวได้ — แต่ agent ไม่ถาม
ถ้า description เขียนไม่ตรงกับงานที่คุณสั่ง
มันจะไม่เปิดไฟล์นั้นเลย และไม่บอกคุณด้วยว่ามันไม่ได้เปิด
ความเงียบตรงนี้จึงอันตรายกว่าป้ายเมนูที่เขียนงง ๆ มาก
- progressive disclosure
- "ทยอยเปิดเผย" — ให้เห็นแค่ป้ายก่อน แล้วค่อยดึงของเต็มมาเมื่อจำเป็น · พิมพ์สั่ง AI ได้เลยว่า "ช่วยเขียน SKILL.md แบบ progressive disclosure — description สั้นแต่ตรง แล้วแยกรายละเอียดไปไฟล์ลูก"
- context
- ข้อความทั้งหมดที่ agent มองเห็นในรอบนั้น และมีเพดานจำกัด · ประโยคที่จะได้ยินบ่อย: "อันนี้มันกิน context เยอะไป" = ใส่ของเข้าไปมากจนเบียดที่ของสำคัญอย่างอื่น
- token
- หน่วยที่โมเดลใช้นับปริมาณข้อความ — ไม่ใช่ตัวอักษร และไม่ใช่คำ · ตัวเลขในหัวข้อนี้วัดเป็นไบต์ ไม่ใช่ token จึงใช้เทียบขนาดกันได้ แต่คิดค่าใช้จ่ายตรง ๆ ไม่ได้
- trigger
- เงื่อนไขที่ทำให้ skill ถูกหยิบมาใช้ ซึ่งก็คือสิ่งที่เขียนอยู่ในบรรทัด
description· ถามรุ่นพี่ได้ว่า "skill ตัวนี้ trigger ตอนไหน" = "งานแบบไหนมันถึงจะทำงาน" - front matter
- ส่วนหัวของไฟล์ Markdown ที่คั่นด้วย
---บนล่าง ใช้เก็บข้อมูลกำกับไฟล์ (ที่นี่คือnameกับdescription) — ไม่ใช่เนื้อหาที่คนอ่าน · เจอชื่อนี้ในไฟล์ไหนก็หมายถึงสองขีดนี้เสมอ
6 · สี่ skill ที่คอร์สจะใช้ — และข้างในมันมีอะไรจริง ๆ
สไลด์หน้า 61 เลือกไว้สี่ตัว จาก repo github.com/mattpocock/skills
ผมเข้าไปตรวจ repo จริงแล้ว: ทั้งสี่ชื่อมีอยู่จริงทั้งหมด
อยู่ที่ skills/engineering/<ชื่อ>/SKILL.md
และผมยังเปิดไฟล์บนเครื่องอ่านเนื้อในซ้ำอีกชั้น
| skill | เหตุผลที่สไลด์ให้ | ข้างในบังคับอะไรจริง ๆ (จากไฟล์ที่ผมเปิดอ่าน) |
|---|---|---|
tdd |
บังคับให้ agent มี feedback ที่วัดผลได้ทุกก้าว ไม่ปล่อยให้เขียนกองใหญ่แล้วค่อยเทส | กฎที่เขียนไว้ตรง ๆ คือ red before green (เขียนเทสที่ fail ก่อน
แล้วเขียนโค้ดแค่พอให้ผ่าน) และ one slice at a time —
หนึ่งเทส หนึ่ง implementation ต่อรอบ
มันตั้งชื่อท่าพังที่เราจะเผลอทำว่า horizontal slicing: เขียนเทสทั้งกองก่อน แล้วค่อยเขียนโค้ดทั้งกอง — ซึ่งได้เทสที่ตรวจสิ่งที่จินตนาการไว้ ไม่ใช่พฤติกรรมจริง |
diagnosing-bugs |
ป้องกัน agent แก้ปัญหาแบบยิงมั่วจนโค้ดยิ่งพัง | แบ่งเป็น 6 เฟส และเฟสแรกคือทั้งหมดของเรื่อง:
สร้าง feedback loop ที่ "แดง" กับบั๊กตัวนี้ก่อน — คือคำสั่งที่รันแล้ว
บอกผ่าน/ไม่ผ่านได้ทันที
ไฟล์ถึงขั้นไล่วิธีสร้าง loop ให้ 10 แบบเรียงตามลำดับที่ควรลอง ตั้งแต่เขียนเทสที่ fail · ยิง curl · ไปจนถึงเขียน harness ทิ้ง ๆ ขึ้นมาใหม่ เหตุผลคือถ้าไม่มี loop การนั่งจ้องโค้ดไม่ช่วยอะไรเลย |
codebase-design |
สำคัญเพราะ agent coding เร็วมาก ถ้าไม่มีวินัยเรื่อง design
จะได้ codebase ที่ complexity โตเร็วกว่าปกติ (ball of mud) เร็วมาก
(ball of mud = โค้ดที่ทุกอย่างพันกันจนแยกส่วนไม่ออก แก้ตรงหนึ่งพังอีกที่) |
เป็น คำศัพท์กลาง มากกว่าเป็นขั้นตอน — บังคับให้ทุกคน (คนกับ agent)
เรียกของชิ้นเดียวกันด้วยคำเดียวกัน
เป้าหมายที่มันตั้งไว้คือ deep module: พฤติกรรมเยอะ ๆ ซ่อนอยู่หลัง interface เล็ก ๆ ตรงข้ามกับ shallow ที่ interface ซับซ้อนพอ ๆ กับไส้ใน ถึงขั้นห้ามใช้คำกำกวมด้วย — เช่นให้พูดว่า seam แทนคำว่า boundary |
code-review |
รีวิว diff ตั้งแต่จุดที่กำหนด ด้วย 2 แกนขนานกัน
(รันเป็น sub-agent แยกกัน) คือ Standards และ Spec
(sub-agent = agent ลูกที่ตัวแม่แตกออกไปทำงานย่อย มี context เป็นของตัวเอง แยกจากตัวแม่และแยกจากพี่น้อง — มันจึงไม่เห็นว่าอีกตัวคิดอะไร) สำคัญเพราะเป็นด่านสุดท้ายก่อน commit ที่ agent เช็คตัวเองอย่างเป็นระบบ |
ขั้นแรกคือ ปักหมุดจุดเทียบ (commit / branch / tag) แล้วเทียบด้วย
git diff <จุดที่ปัก>...HEAD
แกน Standards ถามว่าโค้ดตรงกับมาตรฐานของ repo ไหม บวกกับชุด code smell ของ Fowler 12 ข้อเป็นพื้นฐาน (เช่น Duplicated Code, Primitive Obsession, Shotgun Surgery) แกน Spec ถามคนละคำถามคือ ทำตรงกับที่โจทย์สั่งไหม — หาทั้งของที่ขาด และของที่เกินมาโดยไม่มีใครสั่ง |
ทำไม code-review ต้องแยกเป็นสองแกน แทนที่จะรีวิวทีเดียวจบ
เพราะงานชิ้นเดียวกันผ่านแกนหนึ่งแล้วตกอีกแกนได้ — และสองเคสนี้หน้าตาไม่เหมือนกันเลย:
· โค้ดสะอาด ตั้งชื่อดี ตรงมาตรฐานทุกข้อ แต่ทำผิดโจทย์ → Standards ผ่าน · Spec ตก
· ทำตรงตามโจทย์เป๊ะ แต่เขียนแบบที่ทีมนี้ไม่เขียนกัน → Spec ผ่าน · Standards ตก
ถ้ารวมสองแกนเป็นรายงานเดียว ข้อที่ผ่านจะกลบข้อที่ตก —
ไฟล์ถึงสั่งไว้ชัดว่าห้ามเอาสองรายงานมารวมหรือจัดอันดับใหม่
และห้ามสรุปว่า "โดยรวมผ่าน" ข้ามแกน
เหตุผลที่ต้องรันเป็น sub-agent แยก กัน: กันไม่ให้ผลของแกนหนึ่ง
ไปมีอิทธิพลกับความคิดของอีกแกน — เหมือนให้กรรมการสองคนตัดสินโดยไม่คุยกันก่อน
7 · ติดตั้งยังไง — และที่สไลด์ยังไม่ได้บอก
สไลด์หน้า 62 ให้คำสั่งมาแบบนี้:
# Plugin
claude plugins install mattpocock-skills
# Project-scope skills
npx skills@latest add mattpocock/skills
# Optional: Install node if not exists
mise use -g node@lts
mise reshim # Reload session
ผลการตรวจ: ผมเปิด README ของ repo จริงแล้ว —
ทั้งสองคำสั่งตรงกับที่ README เขียนไว้ทุกตัวอักษร
README ยังบอกทางที่สามด้วย คือพิมพ์ /plugin install mattpocock-skills
จากในเซสชันที่เปิดอยู่แล้ว
ส่วนสองบรรทัด mise ไม่ได้อยู่ใน README — เป็นของที่อาจารย์ใส่เพิ่ม
เพราะคำสั่ง npx ต้องมี Node.js ถึงจะรันได้
1. เลือกทางเดียว อย่าลงทั้งสองทาง — README เขียนไว้ตรง ๆ ว่าถ้าลงทั้ง plugin
และ npx คุณจะได้ skill ทุกตัวซ้ำสองชุด
ที่สไลด์เขียนสองคำสั่งไว้ติดกันจึงอ่านง่ายมากว่า "รันทั้งคู่" ซึ่งไม่ใช่
สองทางนี้ต่างกันที่ปรัชญา: ทาง plugin ได้ของอ่านอย่างเดียว
ที่อัปเดตให้อัตโนมัติ (คุณ "สมัครสมาชิก") · ทาง npx ได้ไฟล์ที่คุณเป็นเจ้าของ
แก้เองได้ แต่ต้องสั่ง npx skills update เองเมื่ออยากได้ของใหม่
2. ลงเสร็จแล้วยังไม่จบ ต้องรัน /setup-matt-pocock-skills หนึ่งครั้งต่อ repo
— มันจะถามว่าใช้ issue tracker อะไร ใช้ label อะไรตอน triage และอยากเก็บเอกสารไว้ที่ไหน
ข้ามขั้นนี้แล้ว skill บางตัวจะทำงานไม่ครบ — code-review เองก็มีบรรทัดบอกว่า
ถ้าไม่มีไฟล์ docs/agents/issue-tracker.md ให้ไปรันคำสั่งนี้ก่อน
3. ตอนลงทาง npx มันจะถามสองคำถามที่คุณต้องตอบ
(เห็นได้จากภาพหน้าจอในสไลด์หน้า 63): Installation scope —
Project (ลงในโฟลเดอร์นี้ ติดไปกับ repo ตอน commit) หรือ Global ·
และ Installation method — Symlink (แนะนำ: มีต้นฉบับชุดเดียว อัปเดตง่าย)
หรือ Copy to all agents
หน้าจอเดียวกันยังให้เลือกด้วยว่าจะติดตั้งลง agent ตัวไหนบ้าง — ไม่ได้มีแค่ Claude Code
และให้เลือกด้วยว่าจะเอา skill ตัวไหนบ้าง — ต้องติ๊ก setup-matt-pocock-skills
ติดมาด้วย ไม่งั้นจะรัน /setup-matt-pocock-skills ในข้อ 2 ข้างบนไม่ได้เลย
README เขียนไว้ตัวหนาตรงนี้เอง: "The installer lets you choose which skills to take,
so make sure setup-matt-pocock-skills is one of them."
เครื่องที่ผมใช้ตรวจบทนี้ลงไว้ทาง npx แบบ symlink
(symlink = ทางลัดที่ชี้ไปโฟลเดอร์จริงอีกที่หนึ่ง ไม่ใช่สำเนา — แก้ที่ต้นทางที่เดียว
ทุกทางลัดเห็นของใหม่พร้อมกัน) — ตรวจดูได้ว่ามันวางไฟล์ไว้จริง:
$ ls ~/.agents/skills/tdd
SKILL.md
agents
mocking.md
tests.md
ระวังจุดที่คนเข้าใจผิดบ่อย — ~/.agents/skills/tdd ที่เพิ่ง
ls ไปเป็นโฟลเดอร์จริง ไม่ใช่ symlink · ตัว symlink อยู่คนละที่
คือฝั่งที่ agent มาหยิบ ซึ่งดูได้ด้วย readlink:
$ readlink ~/.claude/skills/tdd
../../.agents/skills/tdd
บรรทัดเดียวนี้คือหัวใจของคำว่า symlink: ~/.claude/skills/tdd
ไม่ได้เก็บไฟล์เอง มันแค่ชี้กลับไปที่ ~/.agents/skills/tdd
ถ้าตอนติดตั้งคุณเลือก scope เป็น Project ไม่ใช่ Global
ไฟล์จะไม่ได้อยู่ที่ ~/.agents/skills/ — ให้ไปดูที่ .agents/skills/
ในโฟลเดอร์โปรเจกต์แทน
สังเกตว่า skill ตัวเดียวมีได้หลายไฟล์ — SKILL.md เป็นประตูหน้า
ส่วน tests.md กับ mocking.md เป็นเอกสารที่ SKILL.md ลิงก์ไปหา
ส่วน agents/ เก็บไฟล์ปรับให้เข้ากับ agent แต่ละยี่ห้อ — บนเครื่องผมข้างในมีไฟล์เดียวคือ
agents/openai.yaml ซึ่งเป็นรูปธรรมของคำว่า agent-agnostic
ในตารางหัวข้อ 4: เนื้อหาหลักใช้ร่วมกัน ส่วนที่ผูกกับยี่ห้อถูกแยกออกมาไว้โฟลเดอร์นี้
นี่คือ progressive disclosureอีกชั้นหนึ่ง: แม้แต่ตอนที่ agent เปิด
SKILL.md แล้ว มันก็ยังไม่อ่านไฟล์ลูกทั้งหมด —
จะเปิดต่อเมื่องานตรงนั้นต้องใช้จริง ๆ
8 · agent ผิดได้สองทาง — บทเรียนจากเว็บที่คุณกำลังอ่านอยู่
ตรงนี้ไม่มีในสไลด์ แต่ผมคิดว่าเป็นส่วนที่ใช้จริงที่สุดของบท
บทเรียนทั้ง 54 บทในเว็บนี้เขียนด้วยวิธีเดียวกับที่บทนี้สอน —
แตก agent หลายตัวขนานกัน ให้ชุดหนึ่งรันโค้ดตรวจข้อเท็จจริง ชุดหนึ่งเขียน อีกชุดตรวจงาน
ทำมาหลายวัน แล้วได้ข้อสรุปที่สำคัญกว่าเรื่องความเร็ว:
ผลที่ agent ส่งกลับมา เชื่อทันทีไม่ได้ และมันผิดได้สองทาง ไม่ใช่ทางเดียว
| ทางที่ผิด | เคสจริงที่เจอ | ทำไมมันอันตราย |
|---|---|---|
| ทางที่ 1 — false positive บอกว่า "ผิด" ทั้งที่ของนั้นถูกอยู่แล้ว |
agent ตัดสินว่าบทเรียนเรื่อง Redis eviction เขียนผิด —
มันรัน 5 ครั้งแล้วได้ รอบ 1: 0 ทุกครั้ง ไม่ใช่ รอบ 1: 1 อย่างที่บทเขียน
ผมรันตามบทเป๊ะ ๆ เอง ( maxmemory 3mb · allkeys-lru ·
3 รอบ รอบละ 50,000) แล้วได้ตรงกับบททุกบรรทัด
ต้นเหตุ: LRU ของ Redis เป็นแบบ approximate (สุ่ม sample ไม่ได้ไล่จริง) agent เปลี่ยนขนาด payload ไปทดลองเอง เลยได้คนละผล → บทถูก ไม่ต้องแก้ |
ถ้าเชื่อ คุณจะแก้ของที่ถูกให้กลายเป็นผิด
และนี่คือทางที่คนระวังน้อยที่สุด เพราะรายงานว่า "เจอปัญหา" ฟังดูเหมือน agent ทำงานดี |
| ทางที่ 2 — false negative บอกว่า "ผ่าน" ทั้งที่มีของผิดปนมา |
agent เขียนบทเรียนโดย copy ผลของคำสั่ง diff มาว่า
[ok] Files are identical
ซึ่ง diff ตัวจริงไม่พิมพ์แบบนั้น —
เวลาไฟล์เหมือนกัน diff ไม่พิมพ์อะไรเลย |
ผลรันเป็น "ของจริง" — แค่เป็นของจริงบนเครื่องที่มี wrapper ครอบ shell อยู่
ผู้เรียนที่รันตามจะไม่เห็นข้อความนี้ แล้วนึกว่าตัวเองทำผิด |
wrapper ในที่นี้คือโปรแกรมที่ครอบคำสั่ง shell ไว้อีกชั้น
แล้วจัดรูปแบบ output ใหม่ก่อนส่งให้เห็น (มีคนติดตั้งไว้เพื่อประหยัด token บ้าง เพื่อความสวยงามบ้าง)
ผลคือ agent เห็นข้อความหนึ่ง แต่คำสั่งตัวจริงพิมพ์อีกอย่าง —
และ agent ไม่มีทางรู้ เพราะมันไม่เคยเห็นของที่ไม่ถูกครอบ
ผมเจอกับตัวอีกครั้งตอนเขียนบทนี้: wc -c หลายไฟล์พร้อมกัน
ปกติบรรทัดสรุปจะเขียนว่า total แต่บนเครื่องนี้กลับได้เครื่องหมาย Σ แทน
ผมเลยตัดบรรทัดสรุปทิ้ง แล้วเปลี่ยนไปวัดทีละไฟล์แทน
ตัวเลขทุกตัวในหัวข้อ 5 จึงไม่มีบรรทัดที่ wrapper ยุ่งด้วยเลย
ท่าแก้ที่ใช้จริง: เวลาจะโชว์ว่า "ไฟล์สองไฟล์เหมือนกัน"
ให้ใช้คำสั่งที่พิมพ์ค่าออกมาให้เห็น เช่น md5
แทนคำสั่งที่ "เงียบเมื่อผ่าน" อย่าง diff
เพราะ "เงียบ" กับ "คำสั่งไม่ได้รัน" หน้าตาเหมือนกันเป๊ะ —
แต่ค่า hash สองค่าที่ตรงกัน ปลอมไม่ได้
เครื่องตรวจจับควันบนเพดานผิดได้สองทาง และสองทางนี้คนละเรื่องกัน:
· ร้องตอนคุณทอดปลา — ไม่มีไฟไหม้ แต่มันร้อง ·
วิธีที่คนส่วนใหญ่แก้คือถอดถ่านออก
ซึ่งคือการเอาของที่ทำงานถูกไปทำให้พัง
· ถ่านหมดอยู่ก่อน แล้วเกิดไฟไหม้จริง — มันเงียบสนิท
และ"เงียบเพราะปลอดภัย" กับ "เงียบเพราะเครื่องตาย" มองจากพื้นห้องเหมือนกันเป๊ะ
ทางแรกคือ false positive — ตรงกับเคสที่ agent ตัดสินว่าบท Redis eviction ผิด ทั้งที่บทถูก
ทางที่สองคือ false negative — ตรงกับเคสที่ agent ผ่านงานไป
ทั้งที่ copy ข้อความของ wrapper มาใส่โดยไม่รู้ตัว
ที่ไม่เหมือนกัน: เครื่องตรวจควันร้องเสียงเดียวทุกครั้ง
คุณจึงรู้ทันทีว่ามันกำลังเตือน — แต่ agent
รายงานด้วยน้ำเสียงมั่นใจเท่ากันทั้งตอนถูกและตอนผิด
แปลว่าคุณแยกไม่ออกจากตัวรายงาน ·
สิ่งเดียวที่แยกออกคือรันเองแล้วดูผล
- false positive
- "เตือนผิด" — บอกว่าเจอปัญหา ทั้งที่ไม่มีปัญหา · ประโยคที่ใช้ได้จริงตอนรีวิว: "ข้อนี้น่าจะเป็น false positive นะ ผมรันเองแล้วมันผ่าน"
- false negative
- "ปล่อยผ่าน" — บอกว่าไม่มีปัญหา ทั้งที่มี · อันตรายกว่าเพราะไม่มีอะไรมาสะกิดให้คุณไปดู · พูดได้ว่า "เทสชุดนี้อาจมี false negative อยู่ เพราะมันไม่ได้เช็คเคสนี้เลย"
- reproduce
- ทำให้ผลเดิมเกิดขึ้นอีกครั้งบนเครื่องเรา ด้วยขั้นตอนเดียวกันเป๊ะ · เป็นคำแรกที่ senior จะถาม: "reproduce ได้ไหม" = "รันแล้วเจอเหมือนกันหรือเปล่า" · ถ้ายัง reproduce ไม่ได้ ยังไม่ควรแก้อะไรทั้งนั้น
- wrapper
- โปรแกรมที่ครอบคำสั่งจริงไว้อีกชั้น แล้วจัดรูป output ใหม่ก่อนส่งให้เห็น · เวลาผลบนเครื่องคุณกับของเพื่อนไม่ตรงกัน ถามก่อนเลยว่า "เครื่องคุณมี wrapper หรือ alias ครอบคำสั่งนี้อยู่หรือเปล่า"
ประโยคเดียวที่กันเรื่องนี้ได้จริง
ทุก brief ที่ส่งให้ agent ในโปรเจกต์นี้มีประโยคนี้ต่อท้ายเสมอ:
ถ้าผลจริงต่างจากที่โจทย์บอก ให้รายงานตามจริง อย่าดัดให้ตรงโจทย์
ฟังดูเหมือนคำพูดลอย ๆ แต่มันจับโจทย์ที่คนเขียนผิดเองได้มาแล้วสองครั้งติด —
ครั้งหนึ่งเรื่องลำดับ route ใน Gin — ผมเขียนใน brief ของบท 38 ว่า
/users/:id ที่ลงทะเบียนก่อน /users/me จะทำให้ Gin panic
แต่ agent รันจริงแล้วได้ OK (no panic) ทั้งสองลำดับ — และผมรันซ้ำเองตอนเขียนบทนี้
(Gin v1.12.0 · Go 1.26.5) ก็ได้ OK (no panic) เหมือนกัน โดย /users/me
วิ่งเข้า handler ของ static ไม่ว่าจะลงทะเบียนก่อนหรือหลัง
อีกครั้งเรื่อง idempotency
ที่โจทย์สั่งให้ "ยิงซ้ำ 3 ครั้งแล้วดู status code ที่ต่างกัน"
แต่ agent รันจริงแล้วรายงานกลับว่ามันไม่ต่างกันเลย — ซึ่งถูกของ agent
🧭 ทำไมประโยคนี้ถึงจำเป็น — เพราะโดยธรรมชาติ agent มีแรงกดดันจะทำให้คำตอบตรงกับที่คุณสั่ง
ถ้าคุณเขียนโจทย์ว่า "พิสูจน์ว่า X" มันจะพยายามหาทางพิสูจน์ X แม้ X จะไม่จริง
ประโยคนี้ทำสิ่งเดียว: เปลี่ยนเป้าหมายจาก "ทำให้ตรงโจทย์" เป็น "รายงานความจริง"
และมันได้ผลกับคนด้วย — brief ที่คุณเขียนเองก็ต้องผ่านการตรวจเหมือนกัน
ไม่ได้ถูกโดยอัตโนมัติเพราะคุณเป็นคนเขียน
ทดสอบความเข้าใจ
1. "Progressive disclosure" ของ agent skill หมายถึงอะไร?
ผมวัดจากไฟล์จริงบนเครื่อง: บรรทัด description ของ skill ทั้งสี่ตัวรวมกัน
1,046 ไบต์ ขณะที่เนื้อหาทั้งหมด 35,845 ไบต์ —
ราว 2.9% · วัดกับทั้ง 32 skill ได้ 5,386 จาก 250,847 ไบต์ ≈ 2.1%
ส่วนที่ agent แบกตลอดเวลาคือ 2% นั้น อีก 98% ดึงมาเฉพาะตอนใช้
ตัวเลือกที่ 2 ผิดเพราะเป็นสิ่งตรงข้ามกับ progressive disclosure —
โหลดทุกอย่างตลอดเวลาคือปัญหาที่กลไกนี้เกิดมาแก้
ตัวเลือกที่ 1 พูดถึงเรื่องการโชว์ diff ซึ่งคนละเรื่องกัน
ตัวเลือกที่ 4 ผิดเพราะไม่มีการบีบอัดอะไรทั้งนั้น — ไฟล์ยังเป็น Markdown เต็ม ๆ
แค่ไม่ถูกเปิดอ่านจนกว่าจะจำเป็น
ผลพลอยได้ที่ควรจำ: description คือบรรทัดสำคัญที่สุดของไฟล์ —
เขียนไม่ชัด agent ก็ไม่มีวันเปิดอ่านส่วนที่เหลือ
2. คุณจะเพิ่ม endpoint DELETE /api/v1/recipes/:id ในโปรเจกต์ที่มี GET กับ POST เขียนไว้เรียบร้อยแล้ว และของนี้จะขึ้น production — ควรใช้โหมดไหน?
โจทย์มีสองสัญญาณ และมันชี้ไปคนละทาง — ต้องชั่งทั้งคู่
· "มีแบบให้ลอกแล้ว" → เข้าเงื่อนไขของ Pure Agent (งานที่เหมือนของเดิม)
· "ขึ้น production" → บังคับให้ต้องมีรีวิว
รวมกันได้ Pure Agent & Review ซึ่งตรงกับที่สไลด์หน้า 64–68 ใช้กับ
Update / Delete / profile พอดี
ตัวเลือกที่ 3 ทิ้งสัญญาณที่สองไป — และ DELETE เป็น endpoint ที่ผลข้างเคียงย้อนกลับยากที่สุดในชุด
ตัวเลือกที่ 2 แข็งเกินไป: สไลด์เองยังใช้ agent กับงานที่ขึ้น production —
สิ่งที่ห้ามคือ "ไม่รีวิว" ไม่ใช่ "ใช้ agent"
ตัวเลือกที่ 4 ผิดเพราะ skill ช่วยให้รีวิวเป็นระบบขึ้น ไม่ใช่เงื่อนไขที่ขาดไม่ได้ —
คุณอ่าน diff เองได้ตั้งแต่วันนี้
3. code-review แยกรีวิวเป็น Standards กับ Spec แล้วรันเป็น sub-agent คนละตัว ทำไมถึงห้ามเอาสองรายงานมารวมเป็นอันเดียว?
ไฟล์ SKILL.md ของ code-review ยกเคสไว้ตรง ๆ สองเคส:
· โค้ดที่ตามมาตรฐานครบทุกข้อ แต่ทำผิดโจทย์ → Standards ผ่าน · Spec ตก
· โค้ดที่ทำตรงโจทย์เป๊ะ แต่ผิดธรรมเนียมของ repo → Spec ผ่าน · Standards ตก
รายงานแยกกันจึงมีไว้เพื่อกันแกนหนึ่งบังอีกแกน —
และไฟล์ยังห้ามจัดอันดับข้ามแกนด้วย
ส่วนเหตุผลที่ต้องรันแยก sub-agent เป็นคนละเรื่องกับเรื่องรายงาน:
เพื่อไม่ให้ผลของแกนหนึ่งไปมีอิทธิพลกับความคิดของอีกแกน
เหมือนกรรมการสองคนที่ตัดสินโดยไม่คุยกันก่อน
ตัวเลือกที่ 1 ไม่ใช่เหตุผลที่ไฟล์ให้ไว้ (และรายงานถูกจำกัดไว้แกนละไม่เกิน 400 คำอยู่แล้ว)
ตัวเลือกที่ 2 ผิด — สองแกนรันขนานกัน ไม่มีลำดับก่อนหลัง
ตัวเลือกที่ 3 ผิด — ทั้งสองแกนดู diff จากจุดที่ปักหมุดชุดเดียวกัน
4. agent รายงานกลับมาว่า "ตรวจแล้วบทเรียนหัวข้อนี้เขียนผิด ต้องแก้" — ควรทำอะไรต่อ?
ในโปรเจกต์นี้เจอมาแล้วทั้งสองทาง — และทางที่ตัวเลือกนี้พูดถึงคือ
false positive: agent ตัดสินว่าบทเรื่อง Redis eviction ผิด ทั้งที่บทถูก —
มันไปเปลี่ยนขนาด payload เอง เลยได้คนละผล แล้วรายงานว่าบทผิด
ทางกลับกันก็เจอ (false negative): agent เขียนบทโดย copy [ok] Files are identical
ซึ่งมาจาก wrapper ไม่ใช่จาก diff ตัวจริง
ข้อสรุปจึงไม่ใช่ "เชื่อ" หรือ "ไม่เชื่อ" แต่คือ ทุกอย่างที่จะขึ้นเว็บต้องรันยืนยันเองก่อน
ตัวเลือกที่ 1 ผิดตรงคำว่า "ไม่มีอคติ" — agent มีแรงกดดันจะทำให้คำตอบตรงกับโจทย์ที่ได้รับ
ซึ่งเป็นอคติคนละแบบแต่ก็เป็นอคติ
ตัวเลือกที่ 3 เหวี่ยงไปอีกทาง — agent ก็จับโจทย์ที่คนเขียนผิดเองได้มาแล้วสองครั้ง
ตัวเลือกที่ 4 คือกับดักที่แนบเนียนที่สุด: agent สองตัวที่อ่านข้อมูลชุดเดียวกัน
ผิดพร้อมกันได้ง่ายมาก — ความเห็นตรงกันไม่ใช่หลักฐาน ผลรันต่างหากที่เป็น
บทนี้ไม่มีโค้ดให้พิมพ์ตาม เพราะของที่ต้องวัดคือวิธีทำงาน ไม่ใช่ syntax
ภารกิจนี้ให้ทำกับโปรเจกต์ wongnok ของคุณเอง และหัวใจอยู่ที่
ทำงานเดียวกันสองรอบ แล้วเทียบ — เหมือนที่สไลด์ทำกับ Get recipe by id
- ติดตั้ง skill: เลือกทางเดียว ไม่ใช่ทั้งสอง —
claude plugins install mattpocock-skillsหรือnpx skills@latest add mattpocock/skills
ถ้าเลือกทางnpxแล้วเครื่องยังไม่มี Node ให้ลงmise use -g node@ltsแล้วmise reshimก่อน
ถ้าเลือกทางnpxตอนมันถามว่าจะเอา skill ตัวไหน ต้องติ๊กsetup-matt-pocock-skillsติดมาด้วย
เสร็จแล้วรัน/setup-matt-pocock-skillsหนึ่งครั้ง ในโฟลเดอร์โปรเจกต์ - ยืนยันว่ามีของจริง ไม่ใช่แค่คำสั่งผ่าน: หาโฟลเดอร์ skill ให้เจอ
แล้วสั่ง
head -4ใส่SKILL.mdของtdd
ต้องเห็นบรรทัดname:กับdescription:อยู่ระหว่างขีดสามขีด ถ้าไม่เห็น แปลว่าติดตั้งยังไม่สำเร็จจริง - รอบที่ 1 — Self Coding: เขียน
GET /api/v1/recipes/:idเองทั้งอัน ห้ามให้ agent แตะ · จับเวลาไว้ แล้ว commit - รอบที่ 2 — Pure Agent: สร้าง branch ใหม่จาก commit ก่อน ข้อ 3 ด้วย
git switch -c agent-round HEAD~1(HEAD~1= commit ก่อนหน้าหนึ่งขั้น — ก็คือจุดก่อนที่คุณจะ commit งานในข้อ 3)
แล้วสั่ง agent ให้ทำงานเดียวกัน โดยยังไม่เปิด skill ใด ๆ · จับเวลาเหมือนกัน - เทียบสองรอบ:
git diff <branch-ของคุณ>...<branch-ของ-agent>
สามจุดไม่ใช่สองจุด — สามจุดคือเทียบจากจุดที่สอง branch แยกจากกัน (merge-base) ไม่ใช่เทียบปลายต่อปลาย · ผมลองในโปรเจกต์เปล่าแล้วเห็นชัด: branch ที่แยกจากจุดเดียวกันแล้วต่างคนต่างแก้ไฟล์เดียวกัน สองจุดรายงาน1 insertion(+), 1 deletion(-)(เห็นบรรทัดของอีกฝั่งโผล่มาเป็นของที่ถูกลบ) แต่สามจุดรายงาน1 insertion(+)— เห็นแค่สิ่งที่ branch นี้ทำเพิ่ม ซึ่งเป็นสิ่งที่คุณอยากรีวิว
ตอบสามข้อ: ต่างกันตรงไหนบ้าง · มีจุดไหนที่ agent ทำดีกว่าคุณ · มีจุดไหนที่คุณ "อ่านผ่าน" เพราะมันดูเหมือนโค้ดปกติ
ข้อสุดท้ายคือข้อที่ต้องซื่อสัตย์ที่สุด - รอบที่ 3 — เปิด skill: บน branch ของ agent สั่ง
/code-reviewโดยปักหมุดที่ commit ก่อนหน้า
อ่านรายงานทั้งสองแกนแยกกัน แล้วตอบว่า มันชี้จุดที่ข้อ 5 คุณมองข้ามไปไหม - ลอง
tddกับงานถัดไป: เอา endpoint ที่ยังไม่ได้ทำ (เช่นDELETE /api/v1/recipes/:id) มาสั่ง/tdd
สังเกตว่ามันขอให้คุณตกลง seam ก่อนเขียนเทส ไหม — (seam = จุดที่เป็น interface สาธารณะ ซึ่งเป็นที่ที่เทสควรอยู่)
เทียบกับตอนที่คุณสั่ง "เขียนเทสให้หน่อย" เฉย ๆ ว่าได้ผลต่างกันยังไง - ท้าทาย — ทำให้ agent ผิดให้ดู: สั่ง agent ว่า
"พิสูจน์ว่า endpoint นี้คืน 404 เมื่อ id ไม่มีในฐานข้อมูล"
โดยเลือก endpoint ที่คุณรู้ว่ามันคืน 500
ดูว่ามันดัดผลให้ตรงโจทย์ไหม · จากนั้นสั่งใหม่โดยเติมประโยคกันพลาด ("ถ้าผลจริงต่างจากที่โจทย์บอก ให้รายงานตามจริง อย่าดัดให้ตรงโจทย์") แล้วเทียบคำตอบสองครั้ง
ไม่มี "เฉลย" ของภารกิจนี้ เพราะโค้ดของแต่ละคนไม่เหมือนกัน — แต่มีสิ่งที่ควรสังเกตให้เจอ และถ้าไม่เจอแปลว่ายังทำไม่ครบ:
ข้อ 5 — สิ่งที่คนส่วนใหญ่เจอไม่ใช่ "agent เขียนผิด"
แต่เป็นagent เขียนถูกในแบบที่ไม่เหมือนของเดิม: ห่อ error คนละแบบ ·
ตั้งชื่อตัวแปรคนละสไตล์ · แยกฟังก์ชันคนละจุด
ทีละอันไม่เป็นไร แต่ทำแบบนี้ครบ 8 endpoint แล้ว repo จะมี 8 สไตล์ —
นี่คือ ball of mud ที่ codebase-design พูดถึง
และมันโตทีละนิดจนมองไม่เห็นตอนดู diff ทีละอัน
ข้อ 6 — จุดที่ควรสังเกตคือรายงานสองแกนชี้คนละเรื่องกัน
แกน Standards จะพูดเรื่องความสม่ำเสมอกับ code smell ·
แกน Spec จะพูดเรื่องของที่ขาดกับของที่เกินมาโดยไม่มีใครสั่ง
ถ้ารายงานทั้งสองแกนพูดเรื่องเดียวกันหมด ให้สงสัยไว้ก่อนว่า
คุณยังไม่ได้บอกมันว่า spec อยู่ที่ไหน — แกน Spec เลยไม่มีอะไรให้เทียบ
💬 ข้อ 8 คือข้อที่ผมอยากให้ทำจริง ๆ ของบทนี้ —
เพราะการเห็นกับตาว่า agent "ดัดผลให้ตรงโจทย์" ได้ยังไง
มีค่ากว่าอ่านคำเตือนสิบรอบ
และถ้าคุณติดตั้ง skill แล้วได้ตัวเลขไม่ตรงกับหัวข้อ 5 ก็ไม่แปลก —
ผมวัดจาก skill ที่ลงไว้บนเครื่องผมวันที่ 22 สิงหาคม 2026 ซึ่งrepo อัปเดตได้ตลอด
สิ่งที่ควรตรงกันคือลำดับความใหญ่ (description เล็กกว่าเนื้อหาหลายสิบเท่า)
ไม่ใช่ตัวเลขเป๊ะ ๆ · ถ้าลำดับความใหญ่ต่างจากนี้มาก ส่งมาได้เลย
อ้างอิง
- github.com/mattpocock/skills — ต้นทางของ skill ทั้งสี่ตัว · อ่านหัวข้อ Installation ให้จบก่อนพิมพ์คำสั่ง เพราะประโยคที่บอกว่า "ลงทั้งสองทางแล้วจะได้ skill ซ้ำสองชุด" อยู่ในย่อหน้าเปิด ไม่ได้อยู่ในกล่องโค้ด
code-review/SKILL.md— อ่านหัวข้อ Why two axes ท้ายไฟล์ ยาวไม่ถึง 10 บรรทัด และเป็นคำอธิบายที่ดีที่สุดว่าทำไมรีวิวรวมแกนเดียวถึงไม่พอtdd/SKILL.md— อ่านหัวข้อ Anti-patterns โดยเฉพาะ horizontal slicing ซึ่งเป็นท่าที่เกือบทุกคนเผลอสั่ง agent ทำ ("เขียนเทสให้ครบก่อน แล้วค่อยเขียนโค้ด")diagnosing-bugs/SKILL.md— อ่านแค่ Phase 1 ก็พอ มันบอกเองว่า "This is the skill" ส่วนอีกห้าเฟสเป็นงานกลไกcodebase-design/SKILL.md— อ่าน Glossary เพื่อเก็บคำว่า module · interface · depth · seam · adapter ไปใช้ตอนคุยกับ agent ให้ตรงกัน- บันทึกการเรียนรู้ 0010 —
ที่มาของหัวข้อ 8 ส่วนใหญ่: เคส
[ok] Files are identicalที่ agent copy มาจาก wrapper · เคสที่ brief เขียนผิดแล้ว agent จับได้ · และเหตุผลที่เปลี่ยนจากdiffมาใช้md5
ยกเว้นเคส Redis eviction — เคสนั้นอยู่ใน บันทึกการเรียนรู้ 0008 (learning-records/0008-day7-added.md) หัวข้อ "agent ตัดสินผิดหนึ่งจุด" ไม่ได้อยู่ใน 0010 - Claude Code — Plugins —
เอกสารทางการของกลไก plugin ที่คำสั่ง
claude plugins installใช้