บทเรียน 54 · Day 9 · วิธีทำงานกับ AI agent

ให้ AI agent เขียนโค้ดแทน: Self Coding, Pure Agent และ Agent Skills

~20 นาที · ไม่มีโค้ด Go ให้รันในบทนี้ · ควรผ่าน บทเรียน 35 (query · body · header) มาก่อน เพราะสไลด์ใช้ resource ชุด recipes เป็นโจทย์ — และถ้าอยากเห็นโครง endpoint ของ recipes เต็มชุด ให้ย้อนดูบทเรียน 42 (Wongnok: ออกแบบ API spec จากโจทย์จริง)

บทนี้มาจากสไลด์ Day 9 หน้า 55–68 (พร้อมตัวอย่าง prompt จากหน้า 54) และมันไม่ใช่บท Go
ชื่อคอร์สคือ "Enterprise Go Engineering with AI Integration" — ครึ่งหลังของชื่อคือหัวข้อของบทนี้พอดี
สไลด์ทำสิ่งที่ตรงไปตรงมามาก: เอา resource ชุดเดียว (recipes) มาทำทีละ endpoint แล้วเปลี่ยนโหมดการทำงานไปเรื่อย ๆ — เขียนเองสองอัน · ให้ agent ทำล้วน ๆ หนึ่งอัน · แล้วที่เหลือให้ agent ทำแล้วเรารีวิว
ระหว่างทางมีของแทรกเข้ามาชุดหนึ่งคือ agent skills — ซึ่งเป็นคำตอบว่า "จะทำให้ agent มีวินัยได้ยังไง"
ผมจะทำสามอย่างในบทนี้: อธิบายว่าโหมดไหนเหมาะกับงานแบบไหนและเสี่ยงอะไร · วัด progressive disclosure ออกมาเป็นตัวเลขจริง จาก skill ที่ติดตั้งอยู่บนเครื่องผม · และเล่าความผิดพลาดของ agent ที่เจอกับตัวเองตอนทำเว็บบทเรียนชุดนี้

🧰 ของที่ใช้ในบทนี้ (ตรวจวันที่ 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 หน้าออกมาเป็นตารางให้เห็นภาพรวมทีเดียว:

หน้าสไลด์ป้ายโหมดงานที่ทำ
55Self CodingImplement · Create recipes
56Self CodingImplement · Get recipes
57Pure AgentGenerate · Get recipe by id
58–63แทรกเรื่อง agent skills กับวิธีติดตั้ง (หัวข้อ 4–7 ของบทนี้)
64Pure Agent & ReviewGenerate · Get recipe by id (ซ้ำกับหน้า 57)
65Pure Agent & ReviewGenerate · Update recipe by id
66Pure Agent & ReviewGenerate · Delete recipe by id
67Pure Agent & ReviewGenerate · Get my profile
68Pure Agent & ReviewGenerate · 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 ถึงจะรันได้

⚠️ สามเรื่องที่ README บอก แต่สไลด์ไม่ได้บอก — และสองเรื่องแรกทำให้พังจริง

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 อยู่
ผู้เรียนที่รันตามจะไม่เห็นข้อความนี้ แล้วนึกว่าตัวเองทำผิด
⚠️ กับดักที่ไม่มีใครเตือน: output ที่ agent copy มา อาจมาจากเครื่องที่ไม่เหมือนของคุณ

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 สองตัวที่อ่านข้อมูลชุดเดียวกัน ผิดพร้อมกันได้ง่ายมาก — ความเห็นตรงกันไม่ใช่หลักฐาน ผลรันต่างหากที่เป็น

🛠️ ภารกิจ — ลอง skill จริงกับโค้ด Go ของตัวเอง แล้วเทียบกับที่เขียนเอง

บทนี้ไม่มีโค้ดให้พิมพ์ตาม เพราะของที่ต้องวัดคือวิธีทำงาน ไม่ใช่ syntax
ภารกิจนี้ให้ทำกับโปรเจกต์ wongnok ของคุณเอง และหัวใจอยู่ที่ ทำงานเดียวกันสองรอบ แล้วเทียบ — เหมือนที่สไลด์ทำกับ Get recipe by id

  1. ติดตั้ง 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 หนึ่งครั้ง ในโฟลเดอร์โปรเจกต์
  2. ยืนยันว่ามีของจริง ไม่ใช่แค่คำสั่งผ่าน: หาโฟลเดอร์ skill ให้เจอ แล้วสั่ง head -4 ใส่ SKILL.md ของ tdd
    ต้องเห็นบรรทัด name: กับ description: อยู่ระหว่างขีดสามขีด ถ้าไม่เห็น แปลว่าติดตั้งยังไม่สำเร็จจริง
  3. รอบที่ 1 — Self Coding: เขียน GET /api/v1/recipes/:id เองทั้งอัน ห้ามให้ agent แตะ · จับเวลาไว้ แล้ว commit
  4. รอบที่ 2 — Pure Agent: สร้าง branch ใหม่จาก commit ก่อน ข้อ 3 ด้วย git switch -c agent-round HEAD~1 (HEAD~1 = commit ก่อนหน้าหนึ่งขั้น — ก็คือจุดก่อนที่คุณจะ commit งานในข้อ 3)
    แล้วสั่ง agent ให้ทำงานเดียวกัน โดยยังไม่เปิด skill ใด ๆ · จับเวลาเหมือนกัน
  5. เทียบสองรอบ: git diff <branch-ของคุณ>...<branch-ของ-agent>
    สามจุดไม่ใช่สองจุด — สามจุดคือเทียบจากจุดที่สอง branch แยกจากกัน (merge-base) ไม่ใช่เทียบปลายต่อปลาย · ผมลองในโปรเจกต์เปล่าแล้วเห็นชัด: branch ที่แยกจากจุดเดียวกันแล้วต่างคนต่างแก้ไฟล์เดียวกัน สองจุดรายงาน 1 insertion(+), 1 deletion(-) (เห็นบรรทัดของอีกฝั่งโผล่มาเป็นของที่ถูกลบ) แต่สามจุดรายงาน 1 insertion(+) — เห็นแค่สิ่งที่ branch นี้ทำเพิ่ม ซึ่งเป็นสิ่งที่คุณอยากรีวิว
    ตอบสามข้อ: ต่างกันตรงไหนบ้าง · มีจุดไหนที่ agent ทำดีกว่าคุณ · มีจุดไหนที่คุณ "อ่านผ่าน" เพราะมันดูเหมือนโค้ดปกติ
    ข้อสุดท้ายคือข้อที่ต้องซื่อสัตย์ที่สุด
  6. รอบที่ 3 — เปิด skill: บน branch ของ agent สั่ง /code-review โดยปักหมุดที่ commit ก่อนหน้า
    อ่านรายงานทั้งสองแกนแยกกัน แล้วตอบว่า มันชี้จุดที่ข้อ 5 คุณมองข้ามไปไหม
  7. ลอง tdd กับงานถัดไป: เอา endpoint ที่ยังไม่ได้ทำ (เช่น DELETE /api/v1/recipes/:id) มาสั่ง /tdd
    สังเกตว่ามันขอให้คุณตกลง seam ก่อนเขียนเทส ไหม — (seam = จุดที่เป็น interface สาธารณะ ซึ่งเป็นที่ที่เทสควรอยู่)
    เทียบกับตอนที่คุณสั่ง "เขียนเทสให้หน่อย" เฉย ๆ ว่าได้ผลต่างกันยังไง
  8. ท้าทาย — ทำให้ 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 เล็กกว่าเนื้อหาหลายสิบเท่า) ไม่ใช่ตัวเลขเป๊ะ ๆ · ถ้าลำดับความใหญ่ต่างจากนี้มาก ส่งมาได้เลย

อ้างอิง