13 min readAI
Grill Me: สอบถาม requirement จนชัดก่อนลงมือ
Agent เขียนโค้ดได้เร็วจนเราข้ามขั้นถามให้ชัด แล้วไปเจอทีหลังว่าคำเดาของมันถูกล็อกไว้ใน test ที่เขียวแล้ว บันทึกจากเดฟ·PM·PO ที่ลองนิสัย Grill Me — ให้ agent สัมภาษณ์เราทีละคำถามจนตกลงกันได้ก่อนแตะโค้ด — ว่าทำไมการถูกซักจนอึดอัดตอนยังเป็นประโยค ถึงถูกกว่าการรื้อฟีเจอร์ตอน UAT และงานแบบไหนในบริษัทรับจ้างพัฒนาที่ควรถูก grill ก่อนเสมอ

มีคำถามหนึ่งที่ผมแทบไม่ได้ยินในทีมอีกแล้วตั้งแต่ใช้ agent ทุกวันครับ คือ "อันนี้หมายความว่ายังไงครับพี่"
เมื่อก่อนน้อง junior ที่ได้รับงานจากผมจะเดินมาถามอย่างน้อยหนึ่งรอบ บางทีถามจนผมรำคาญ "export ทั้งหมดคือทั้งหมดจริง ๆ ไหม" "ถ้าลูกค้าไม่มีอีเมลจะส่งยังไง" "ปุ่มนี้ใครกดได้บ้าง" แต่ตอนนี้งานเดียวกันถูกส่งตรงเข้าแชตของ agent ห้านาทีต่อมาก็ได้ PR ที่รันได้ test เขียวครบ คำถามพวกนั้นไม่ได้หายไปนะครับ มันแค่ถูกตอบไปแล้ว โดย agent ที่ไม่ได้บอกใครว่ามันเลือกอะไร
ความเร็วของ agent ทำให้การถามรู้สึกเหมือนการเสียเวลา ทำไมต้องนั่งคุยสิบนาทีในเมื่อสั่งทำแล้วดูผลเลยได้ ผิดก็สั่งแก้ ฟังมีเหตุผลมาก จนกระทั่งเราพบว่าคำตอบที่ agent เลือกให้ ถูกล็อกไว้ใน test สามสิบตัว migration หนึ่งไฟล์ และหน้าจอที่ลูกค้าเห็นไปแล้วตอน demo
ผมเป็นทั้ง developer, PM และ PO ที่ Mulberrysoft ดูแลทีม junior ทำงานกับลูกค้าที่ requirement แทบไม่เคยครบ ซีรีส์นี้เริ่มจากการให้ agent ทำงานแทนโดยไม่ให้มันคิดแทน ต่อด้วยวันที่คำตอบของ agent กลายเป็นความเห็นของเรา หนี้ความเข้าใจที่ไม่ขึ้นบน dashboard เจตนาที่ agent จ่ายแทนไม่ได้ สีเขียวที่ไม่ได้แปลว่าถูก และล่าสุดการล็อกสเปกก่อนโค้ดด้วย OpenSpec
โพสต์ OpenSpec ตอบว่าข้อตกลงควร "อยู่ที่ไหน" คือในไฟล์ที่อ่านได้และ review ได้ แต่ยังมีคำถามก่อนหน้านั้นที่ผมค้างไว้ คือข้อตกลงนั้น "เกิดขึ้นได้ยังไง" ในเมื่อ requirement ที่เราได้จากลูกค้าส่วนใหญ่เป็นข้อความบรรทัดเดียวใน LINE
จุดยืนของโพสต์นี้คือ ให้ตัวเองถูก grill จนชัดก่อนลงมือ ไม่ใช่เราซัก agent แต่ให้ agent ซักเรา ทีละคำถาม จนทุกการตัดสินใจที่สำคัญมีเจ้าของ แล้วค่อยเขียนโค้ด
จุดเริ่มต้นจากโพสต์สรุป talk บน X
ผมเห็น โพสต์ของ Antonio Cappiello บน X ที่สรุป talk ของ Franz Nkemaka เรื่องทำไม senior engineer ถึงพลาดกับ agentic coding ในโพสต์นั้นมีนิสัยหลายข้อ และข้อแรกที่เขาวางไว้คือ spec before code โดยยกตัวอย่าง "Grill Me" ของ @mani_tweeter เป็นวิธีปฏิบัติ
ที่สะดุดใจผมคือคำว่า senior ครับ เราน่าจะคิดว่าคนที่พลาดกับ agent คือมือใหม่ที่เชื่อทุกอย่าง แต่ผมว่ามันสมเหตุสมผลมาก คนที่มีประสบการณ์มักมั่นใจว่ารู้แล้วว่าต้องการอะไร เลยพิมพ์ prompt สั้น ๆ แล้วปล่อยให้ agent เติมส่วนที่เหลือ ความรู้ที่อยู่ในหัวเราไม่ได้ถูกส่งต่อ แต่ความมั่นใจถูกส่งต่อไปเต็ม ๆ
ผมเจอตัวเองในประโยคนั้นเลย หลายครั้งที่ผมเป็นคนพิมพ์ prompt สองบรรทัดเอง แล้วไปโทษ agent ว่าเข้าใจผิด ทั้งที่ผมไม่เคยบอกมันว่าเข้าใจถูกหน้าตาเป็นยังไง
Grill Me คืออะไรจริง ๆ
Grill Me ไม่ใช่เครื่องมือที่ต้องติดตั้งครับ มันคือรูปแบบการทำงานที่ถูกแพ็กเป็น skill หรือ slash command ในหลายที่ เช่น /grill-me ใน agentic coding skill ที่ผมเห็นคนแชร์กัน หลักการรวม ๆ คือ ก่อน agent จะเริ่มทำงาน มันต้อง สัมภาษณ์เรา เกี่ยวกับงานนั้นก่อน
ฟังดูธรรมดา แต่รายละเอียดของมันคือสิ่งที่ทำให้ต่างจากการพิมพ์ "มีคำถามอะไรไหม" ท้าย prompt ผมสรุปพฤติกรรมหลักไว้แบบนี้
1. ถามทีละคำถาม ไม่ใช่โยนลิสต์คำถามสิบห้าข้อมาให้ตอบทีเดียว ข้อนี้สำคัญกว่าที่คิดครับ เพราะเวลาเจอลิสต์ยาว เรามักตอบแค่ข้อที่ง่าย แล้วข้ามข้อที่ต้องคิด ส่วนข้อที่ข้ามไป agent ก็จะเดาเองอยู่ดี
2. เสนอคำตอบที่แนะนำมาด้วยทุกข้อ และเรียบเรียงคำถามให้การตอบว่า "ใช่" คือการยอมรับคำแนะนำนั้น เช่น "ไฟล์ export ควรใช้ timezone ของบริษัท (Asia/Bangkok) ไม่ใช่ของ browser ใช่ไหมครับ" แบบนี้เราไม่ต้องคิดจากศูนย์ทุกข้อ แต่ยังต้องตัดสินใจ และเห็นชัดว่ากำลังยอมรับอะไร
3. ไปหาคำตอบจาก codebase เองถ้าโค้ดตอบได้ ไม่ถามว่า "ระบบมี role อะไรบ้าง" ถ้ามันเปิด enum ดูเองได้ คำถามที่เหลือมาถึงเราจึงเป็นคำถามที่มีแต่คนตอบได้ คือเรื่องธุรกิจ เรื่องลูกค้า เรื่องที่ยังไม่มีใครตัดสิน
4. เดินตามกิ่งของต้นไม้การตัดสินใจ คำตอบข้อหนึ่งเปิดหรือปิดคำถามข้อถัดไป ถ้าตอบว่า export ได้เฉพาะ admin คำถามเรื่อง "ข้อมูลของสาขาอื่นควรเห็นไหม" อาจหายไปเลย แต่ถ้าตอบว่าหัวหน้าสาขาก็ export ได้ คำถามนั้นต้องถูกตอบก่อนไปต่อ มันแก้ dependency ทีละข้อ ไม่กระโดด
5. ไม่ลงมือจนกว่าจะยืนยันว่าเข้าใจตรงกัน อันนี้คือหัวใจครับ agent ต้องสรุปกลับมาว่าเข้าใจอะไร และรอให้เราบอกว่าใช่ ก่อนจะแตะไฟล์แม้แต่ไฟล์เดียว
และถ้าใช้คู่กับโหมด plan ก็ต่อได้อีกขั้น คือ grill จนชัด แล้วให้ agent เขียนแผนออกมาให้เรา review ก่อนเขียนโค้ด ซึ่งผมจะกลับมาพูดถึงตอนเชื่อมกับ OpenSpec
สิ่งที่ผมชอบที่สุดคือมันกลับทิศของบทสนทนาครับ ปกติเราเป็นฝ่ายสั่ง agent เป็นฝ่ายรับ ใน Grill Me agent เป็นฝ่ายถาม และเราเป็นฝ่ายที่ต้องรับผิดชอบคำตอบ
เรื่องจริงจากหน้า export รายงาน
ขอเล่าตัวอย่างที่เกิดขึ้นจริงในทีมครับ ลูกค้าเจ้าหนึ่งพิมพ์มาใน LINE ประมาณว่า "ขอปุ่ม export รายงานยอดขายเป็น Excel หน่อยครับ ฝ่ายบัญชีจะใช้"
น้องในทีมเอาข้อความนี้ไปให้ agent พร้อมบอกว่าหน้ารายงานอยู่ไฟล์ไหน ได้ PR กลับมาในยี่สิบนาที ปุ่มสวย ไฟล์ออกมาถูก format test ผ่านหมด น้องส่งมาให้ผมรีวิว
ผมเปิด diff แล้วต้องไล่หาว่า agent ตัดสินใจอะไรไปบ้าง ปรากฏว่ามันเลือกให้ทุก role ที่เห็นหน้ารายงานกด export ได้ เลือกใช้ช่วงวันที่ตาม filter บนหน้าจอ เลือกตัดยอดตามเวลา UTC เพราะ database เก็บแบบนั้น และเลือกไม่รวมรายการที่ถูก void เพราะหน้าจอไม่แสดง ทุกข้อมีเหตุผลรองรับ ทุกข้อมี test ยืนยัน และอย่างน้อยสองข้อผิดสำหรับฝ่ายบัญชี
ปัญหาไม่ใช่ว่า agent โง่ครับ ปัญหาคือมันไม่มีทางรู้ และไม่มีใครถาม
ผมลองย้อนทำงานเดียวกันใหม่โดยให้ agent grill ผมก่อน คำถามที่ได้ประมาณนี้
- "จากโค้ดมี role อยู่สี่แบบ แนะนำให้ export ได้เฉพาะ admin กับ accounting เพราะข้อมูลมียอดเงินรวม ใช่ไหมครับ"
- "รอบตัดยอดควรเป็นเที่ยงคืนเวลาไทย ไม่ใช่ UTC ตามที่ database เก็บ ใช่ไหมครับ"
- "รายการที่ void ฝ่ายบัญชีน่าจะต้องเห็นเพื่อกระทบยอด แนะนำให้รวมไว้พร้อมคอลัมน์สถานะ ใช่ไหมครับ"
ข้อแรกกับข้อสองผมตอบได้ทันที ข้อสามผมไม่รู้ครับ และนั่นแหละคือจุดที่มีค่าที่สุดของรอบนี้ เพราะมันกลายเป็นคำถามที่ผมส่งกลับไปถามลูกค้า แทนที่จะเป็นคำตอบที่ agent ฝังไว้ในโค้ดเงียบ ๆ
ทั้งหมดใช้เวลาไม่ถึงสิบห้านาที น้อยกว่าเวลาที่ผมใช้ไล่อ่าน diff รอบแรกเสียอีก
ทำไม PM และ PO ควรเป็นคนถูกซัก
ตรงนี้คือมุมที่ผมคิดว่าคนมองข้ามบ่อยครับ Grill Me มักถูกเล่าเป็นเทคนิคของ developer แต่คำถามส่วนใหญ่ที่ agent ถามหลังจากหาคำตอบจาก codebase เองแล้ว ไม่ใช่คำถามทางเทคนิค
"ใครกดได้" "ตัดยอดตอนไหน" "ลูกค้าเห็นข้อความ error ว่าอะไร" "ถ้าข้อมูลไม่ครบให้ทำยังไง" พวกนี้คือการตัดสินใจทางธุรกิจทั้งนั้น ถ้าคนที่ถูก grill คือน้อง junior คนเดียว สิ่งที่เกิดขึ้นคือน้องจะตอบ "ใช่" ไปตามคำแนะนำของ agent เพราะไม่รู้จะตอบอะไร หรือเกรงใจที่จะต้องมาถามพี่ทุกข้อ ผลลัพธ์ก็คือคำเดาของ agent เหมือนเดิม แค่มีลายเซ็นของน้องแปะอยู่
ผมเลยคิดว่าการ grill ที่ได้ผลจริงต้องมีคนที่มีอำนาจตัดสินเรื่องธุรกิจอยู่ด้วยครับ อาจเป็น PO อาจเป็น PM หรืออย่างน้อยต้องมีวิธีพักคำถามประเภทนั้นไว้แล้วส่งต่อให้คนที่ตอบได้
อีกเรื่องที่ผมได้จากการถูก grill เองคือมันเปิดโปงว่าผมรู้น้อยกว่าที่คิดครับ ตอนอ่าน requirement ของลูกค้า ผมรู้สึกว่าเข้าใจแล้ว แต่พอถูกถามทีละข้อด้วยคำถามที่เจาะจงมาก ผมพบว่าครึ่งหนึ่งผมตอบจากความเคยชิน ไม่ใช่จากสิ่งที่ลูกค้าบอก ความรู้สึกอึดอัดตอนถูกซักแบบนี้ไม่สบายใจเลยครับ แต่มันถูกกว่าความรู้สึกตอนลูกค้าถามใน UAT ว่า "ทำไมยอดไม่ตรงกับที่บัญชีปิด" มาก
ต่อจาก Intent Debt, Verify และ OpenSpec
ถ้ามองย้อนไปทั้งซีรีส์ ผมเห็น Grill Me เป็นชิ้นที่ขาดไประหว่างโพสต์ก่อน ๆ ครับ
ในโพสต์ Intent Debt ผมบอกว่าช่องว่างใน prompt จะถูกเติมเสมอ คำถามคือใครเติมและรู้ตัวไหม Grill Me คือการบังคับให้ช่องว่างพวกนั้นโผล่ออกมาเป็นคำถามก่อนที่ agent จะเติมเอง มันดึงเจตนาที่อยู่ในหัวเราออกมาเป็นคำพูด ตอนที่ยังเปลี่ยนได้ราคาถูก ส่วนเรื่องที่ไม่มีใครรู้ ก็ถูกเขียนเป็น "ยังไม่รู้" ที่มีเจ้าของ แทนที่จะเป็นคำเดาที่ไม่มีใครรับผิดชอบ
ในโพสต์ Verify ผมบอกว่าต้องนิยามคำว่า verified ไว้ก่อนเห็นผล เพราะหลังจากเห็นสีเขียวแล้ว เราจะหาเหตุผลให้มันถูกเสมอ Grill Me คือจังหวะที่นิยามนั้นเกิดขึ้นครับ ก่อนจะมี test สักตัว เราตกลงกันแล้วว่าไฟล์ export ต้องตัดยอดตามเวลาไทยและต้องมีรายการ void พอ agent เขียน test ออกมา มันมีอะไรให้เทียบ ไม่ใช่ test ที่ยืนยันคำเดาของตัวเอง
ส่วนโพสต์ OpenSpec ผมคิดว่าสองอย่างนี้เติมกันพอดีครับ Grill Me คือ นิสัยเชิงบทสนทนา เป็นวิธีที่ทำให้เราไปถึงความเข้าใจที่ตรงกัน ส่วน OpenSpec คือ artifact ที่ล็อกความเข้าใจนั้นไว้ เป็นไฟล์ใน repo ที่ review ได้และ agent ตัวถัดไปอ่านได้
ถ้า grill อย่างเดียวโดยไม่เขียนลงที่ไหน ข้อตกลงก็อยู่ในแชตแล้วหายไปพร้อม session ถ้าใช้ OpenSpec โดยไม่ grill ก่อน proposal.md กับ specs/ ก็อาจเป็นแค่คำเดาของ agent ในรูปแบบที่ดูเป็นทางการขึ้น ลำดับที่ผมกำลังลองคือ grill จนชัด แล้วให้ผลของการ grill กลายเป็น proposal กับ specs ใน OpenSpec จากนั้นค่อย review แล้ว apply
ต้องย้ำเหมือนทุกโพสต์ครับว่า Grill Me ไม่ได้กันเราจากการยอมจำนนทางความคิด ได้อัตโนมัติ คำถามที่มาพร้อมคำตอบแนะนำทำให้ตอบ "ใช่" ได้ง่ายมาก ถ้าเราตอบใช่ทุกข้อโดยไม่คิด สิ่งที่ได้คือคำเดาของ agent ที่ผ่านพิธีกรรมยืนยันแล้ว ซึ่งแย่กว่าเดิมเพราะมันดูเหมือนเราตัดสินใจเอง การออกแบบให้ "ใช่" คือการยอมรับเป็นเรื่องดี แต่มันมีไว้เพื่อลดภาระ ไม่ใช่เพื่อให้เราเลิกอ่าน
งานแบบไหนที่ผมจะให้ agent grill ก่อน
ไม่ใช่ทุกงานต้องถูกซักครับ ถ้าผมจะแก้ typo ในหน้า About แล้ว agent ถามกลับมาห้าข้อ ผมคงปิดแชตทิ้ง เกณฑ์นี้ผมเรียบเรียงเองจากงานแบบ Mulberrysoft
ควร grill ก่อนเสมอ เมื่อ
- requirement มาเป็นประโยคเดียวจากแชต LINE หรือ Slack บรรทัดเดียวคือสัญญาณว่ามีการตัดสินใจซ่อนอยู่หลายสิบข้อ และลูกค้าเองก็อาจยังไม่ได้คิด
- งานแตะเงิน สิทธิ์ หรือข้อมูลลูกค้า ยอดเงิน ส่วนลด role การ export ข้อมูลส่วนบุคคล หมวดนี้คำเดาผิดแพงที่สุด และ test จะไม่ล้มเพราะมัน
- ลูกค้าจะเห็นผลโดยตรง หน้าจอ อีเมล ข้อความแจ้งเตือน ทุกคำที่ลูกค้าอ่านควรมาจากการตัดสินใจของคน ไม่ใช่ default ของ agent
- คนสั่ง agent ไม่ใช่คนตัดสินธุรกิจ เช่น น้อง junior รับงานจากผมอีกต่อหนึ่ง ตรงนี้ผมอยากให้ grill โดยมีผมหรือ PO อยู่ด้วย
- งานที่จะต่อด้วย OpenSpec ถ้าจะล็อกสเปกอยู่แล้ว การ grill ก่อนทำให้ proposal ที่ออกมามีเนื้อจริง ไม่ใช่โครงที่รอให้คนมาแก้
ไม่จำเป็น เมื่อ
- งานเล็ก ย้อนกลับง่าย และไม่มีการตัดสินใจทางธุรกิจ เช่น แก้ข้อความ ปรับ spacing
- บั๊กที่สาเหตุชัดและการแก้ไม่เปลี่ยนพฤติกรรมที่ตกลงไว้
- prototype ทิ้งเพื่อให้ลูกค้าเห็นภาพ ตรงนี้ผมยอมให้ agent เดาได้ เพราะผลลัพธ์มีไว้เพื่อเกิดคำถาม ไม่ได้มีไว้ส่งมอบ
คำถามเช็กของผมยังเหมือนโพสต์ก่อนครับ ถ้า agent เดาผิดในงานนี้ ใครจะเป็นคนเจอ และเจอเมื่อไร ถ้าคำตอบคือลูกค้าตอน UAT ก็ให้มันซักเราก่อน
นิสัยที่ผมจะลองใช้
ทีละคำถาม ไม่รับลิสต์ ถ้า agent โยนคำถามมาสิบข้อ ผมจะบอกให้มันเลือกข้อที่สำคัญที่สุดมาก่อนข้อเดียว คำถามที่ตอบทีละข้อได้รับความคิดเต็ม ๆ คำถามในลิสต์ยาวได้รับแค่การกวาดตา
ไม่ตอบสิ่งที่โค้ดตอบได้ ถ้า agent ถามว่า "ตาราง orders มีคอลัมน์สถานะไหม" ผมจะให้มันไปเปิดดูเอง เวลาของคนควรถูกใช้กับคำถามที่มีแต่คนตอบได้ และการบังคับแบบนี้ทำให้คำถามที่เหลือคมขึ้นมาก
อ่านคำตอบที่แนะนำทุกข้อก่อนพิมพ์ "ใช่" ผมจะถามตัวเองสั้น ๆ ว่าข้อนี้ผมรู้จริง เดาเอง หรือแค่ยอมตาม ถ้าเป็นอย่างหลัง ข้อนั้นยังไม่ถูกตัดสิน
เขียน "ยังไม่รู้" เป็นสมมติฐานที่มีเจ้าของ เรื่องที่ต้องรอลูกค้า ผมจะไม่ปล่อยให้ agent เลือกให้ แต่จะให้มันบันทึกไว้ว่า "สมมติให้รวมรายการ void ไว้ก่อน รอฝ่ายบัญชียืนยัน ผู้รับผิดชอบคือ Earth" สมมติฐานที่มีชื่อคนกำกับจะถูกตามต่อ สมมติฐานที่ไม่มีจะกลายเป็นข้อเท็จจริงในสามวัน
ให้น้อง grill โดยมี PO อยู่ด้วยสำหรับงานธุรกิจ ไม่จำเป็นต้องนั่งด้วยกันตลอด แต่น้องควรรู้ว่าคำถามแบบไหนต้องส่งต่อ และควรรู้สึกว่าการพักคำถามไว้แล้วมาถามพี่เป็นเรื่องปกติ ไม่ใช่ความล้มเหลว ผมคิดว่านี่คือการคืนคำถาม "อันนี้หมายความว่ายังไงครับพี่" ให้กลับมาในทีม ผ่านปากของ agent
หยุดเมื่อตรงกันแล้ว Grill Me ไม่ใช่การสัมภาษณ์ที่ต้องถามจนครบทุกความเป็นไปได้ พอ agent สรุปกลับมาแล้วผมอ่านแล้วตรงกับที่ต้องการ ก็พอ ต่อจากนั้นคือเลือกว่าจะให้ลงมือเลย หรือให้เขียนเป็น OpenSpec proposal ก่อน ขึ้นกับเกณฑ์ในหัวข้อก่อนหน้า
เก็บผลการ grill ไว้นอกแชต อย่างน้อยที่สุดคือสรุปการตัดสินใจไว้ใน PR description หรือ ticket ถ้างานเข้าเกณฑ์ก็ให้มันกลายเป็น proposal.md กับ specs/ เพราะการตัดสินใจที่อยู่แค่ในประวัติแชตคือหนี้เจตนาก้อนใหม่ที่รอวันถูกลืม
ท้ายที่สุด
ผมคิดว่า Grill Me เป็นชื่อที่ดีมากครับ เพราะมันบอกตรง ๆ ว่ากระบวนการนี้ไม่สบาย การถูกถามว่า "ตัดยอดตอนไหน" แล้วตอบไม่ได้ เป็นความรู้สึกที่ไม่มีใครชอบ โดยเฉพาะคนที่คิดว่าตัวเองเข้าใจงานดีแล้ว
แต่ความอึดอัดนั้นต้องเกิดที่ไหนสักที่อยู่ดีครับ ถ้าไม่เกิดตอนที่ agent ซักเราในแชต ก็จะเกิดตอนรีวิว diff ห้าร้อยบรรทัด หรือแย่กว่านั้นคือตอนที่ลูกค้าเปิดไฟล์ export แล้วยอดไม่ตรงกับที่บัญชีปิดไว้ คำถามมีราคาเท่าเดิมเสมอ สิ่งที่เปลี่ยนคือราคาของคำตอบที่ผิด ซึ่งแพงขึ้นทุกชั่วโมงที่มันถูกฝังลึกลงไปในโค้ด
Agent ทำให้การเขียนโค้ดถูกลงมาก มากจนเราลืมไปว่าการถามยังถูกกว่าอยู่ดี
ดังนั้นครั้งถัดไปที่ได้ requirement บรรทัดเดียวจากลูกค้า ผมจะไม่โยนมันเข้า agent แล้วรอดูผล ผมจะพิมพ์ว่า grill me แล้วตอบคำถามทีละข้อ จนกว่าผมจะพูดได้เต็มปากว่า "เสร็จ" ในงานนี้หมายความว่าอะไร
ถูกซักให้ชัดก่อนครับ แล้วค่อยให้ agent ลงมือ