ข้าม​ไป​ยัง​เนื้อหา

เริ่ม​ด้วย eval set เล็กๆ

บท​ที่​แล้ว​เรา​ได้​เครื่องมือ​ตัดสิน​มาสอง​แบบ — ตัว​เช็ค​แบบ deterministic กับ LLM-as-judge ที่​ต้อง calibrate ก่อน​ถึง​จะ​เชื่อถือ​ได้ แต่​เครื่องมือ​ตัดสิน​ไม่มี​ค่า​อะไร​เลย​ถ้า​ไม่มี​เคส​ให้​ตัดสิน คำถาม​ของ​บท​นี้​คือ: จะ​เริ่ม​สร้าง​ชุด​เคส​วัดผล​จาก​ตรง​ไหน สัญชาตญาณ​แรก​ของ​ทีม​ส่วน​ใหญ่​คือ “ขอ​รวบรวม​ให้​ครบ​เป็น​ร้อย​เคส​ก่อน​ค่อย​เริ่ม eval” — ซึ่ง​เป็น​กับดัก​ที่​ทำให้​ไม่​ได้​เริ่ม​สัก​ที ข้อ​เสนอ​ของ​บท​นี้​ตรง​ข้าม: เริ่ม​เล็ก เริ่ม​จาก​ของ​จริง เริ่ม​วัน​นี้

📦 code ตัวอย่าง (กำลัง​จัด​ทำ)

บท​นี้​เดิน​เรื่อง​ด้วย ops-copilot agent ที่​คืน​เงิน​ออเดอร์​ใน domain Order จาก repo kaen-food-ordering (กำลัง​จัด​ทำ) — เป็น​บท​เชิง​วิธีการ สเก็ตช์ dataset ที่​เห็น​เป็น​ภาพร่าง​ของ​โครง​เคส​วัดผล เพื่อ​สื่อ​ไอเดีย ไม่ใช่ eval harness ที่​รัน​ได้​ทันที

20–50 เคส​จาก​ความ​ล้มเหลว​จริง คือ​จุด​เริ่ม​ที่​ดี

หัวข้อ​ที่​มีชื่อ​ว่า “20–50 เคส​จาก​ความ​ล้มเหลว​จริง คือ​จุด​เริ่ม​ที่​ดี”

Anthropic พูดตรงๆ ว่า “20-50 simple tasks drawn from real failures is a great start” — เคสง่ายๆ 20–50 เคส​ที่​ดึง​มา​จาก​ความ​ล้มเหลว​จริง​คือ​จุด​เริ่ม​ที่​ดี​มาก (ดู Anthropic, “Demystifying evals for AI agents”) ชุด​เคส​เริ่ม​ต้นแบบ​นี้​แหละ​คือ​สิ่ง​ที่​เรา​จะ​เรียก​ว่า Golden DatasetGolden Datasetชุด input พร้อม​คำ​ตอบ/พฤติกรรม​ที่​ถูกต้อง (Ground Truth) ซึ่ง​มนุษย์​ตรวจ​แล้ว ใช้​เป็น​หลัก​อ้างอิง​ตายตัว​สำหรับ​รัน eval ซ้ำ​ก่อน​ปล่อย​แต่ละ version — เริ่ม​จาก​เคส​จริง​หลัก​สิบ​เคส​ที่​เคย​พัง​มา​ก่อน​ก็​พอ ไม่​ต้อง​รอ​ให้​มี​เป็น​ร้อย​เคส​ก่อน​เริ่ม eval แต่​ต้อง​มา​จาก​ความ​ล้มเหลว​จริง ไม่ใช่​เคส​ที่​จินตนาการ​ขึ้น​เองProcess: ชุด input พร้อม​พฤติกรรม​ที่​ถูกต้อง​ซึ่ง​มนุษย์​ตรวจ​แล้ว ใช้​เป็น​หลัก​อ้างอิง​ตายตัว​สำหรับ​รัน eval ซ้ำ​ก่อน​ปล่อย​แต่ละ version — และ​มัน​ไม่​จำเป็น​ต้อง​ใหญ่​ตั้งแต่​วัน​แรก

นี่​ไม่ใช่​แค่​คำ​แนะนำลอยๆ ทีม​ที่​สร้าง multi-agent research system ของ Anthropic เล่า​ว่า​พวก​เขา “started evaluating immediately” ด้วย “about 20 queries representing real usage patterns” — เริ่ม​วัดผล​ทันที​ด้วย​ราว 20 คำถาม​ที่​สะท้อน​รูปแบบ​การ​ใช้งาน​จริง แทนที่​จะ​รอ​ให้​มี​ชุด​เป็น​ร้อย​เคส​ก่อน (ดู Anthropic, “How we built our multi-agent research system” — อ้าง​เพื่อ วิธีการ เริ่ม​เล็ก ไม่ใช่​เพื่อ​ตัวเลข​ประสิทธิภาพ​ใน post นั้น)

เหตุผล​ที่​ชุด​เล็ก​ใช้ได้​ผล​ตอน​เริ่ม​ไม่ใช่​เพราะ​เรา​มักง่าย แต่​เพราะ ตอน​แรก​ความ​เปลี่ยนแปลง​มัน​ตัว​โต ระบบ​ที่​เพิ่ง​เริ่ม​มัก​มี bug ก้อน​ใหญ่​ที่พังชัดๆ การ​แก้ prompt หนึ่ง​ครั้ง​อาจ​ดัน​อัตรา​สำเร็จ​จาก 30% ขึ้น​เป็น 80% ได้ — ส่วน​ต่าง​ขนาด​นั้น (นี่​เป็น​ตัวเลข ตัวอย่าง​เชิง​ประกอบ เพื่อ​ให้​เห็น​ภาพ ไม่ใช่​ผล​วัด​จาก​ระบบ​จริง) เห็น​ได้​ชัด​ตั้งแต่​เคส​ไม่​กี่​สิบ​เคส ไม่​ต้อง​ใช้​เป็น​พัน​เคสมา​ยืนยัน

พูด​อีก​แบบ: จำนวน​เคส​ที่​ต้อง​ใช้​ขึ้น​กับ​ขนาด​ของ​สิ่ง​ที่​อยาก​ตรวจ​จับ ถ้า​อยาก​รู้​ว่าการ​เปลี่ยนครั้งใหญ่ทำให้ดีขึ้นชัดๆ หรือ​เปล่า เคส​หลัก​สิบ​ก็​ตอบ​ได้ แต่​พอ​ระบบ​นิ่ง​ขึ้น​แล้ว​เรา​ไป​ไล่​จับ​ส่วน​ต่าง​เล็กๆ (เช่น​ดี​ขึ้น​อีก 2%) ตอน​นั้น​แหละ​ถึง​ต้องการ​เคส​มาก​ขึ้น​เพื่อ​ให้​มั่นใจ​ว่า​ไม่ใช่​ความ​บังเอิญ นั่น​คือ​เหตุผล​ว่า​ทำไม 20–50 ถึง “พอ” เฉพาะ​ช่วง​เริ่ม ไม่ใช่​ตลอด​ไป

เคส​ควร​มา​จาก​ไหน — สอง​แหล่ง​ของ​ความ​ล้มเหลว​จริง

หัวข้อ​ที่​มีชื่อ​ว่า “เคส​ควร​มา​จาก​ไหน — สอง​แหล่ง​ของ​ความ​ล้มเหลว​จริง”

หัวใจ​อยู่​ที่​คำ​ว่า real failures เคส​ใน​ชุด​เริ่มต้น​ต้อง​มา​จาก​ความ​ล้มเหลว​จริง ไม่ใช่​เคส​ที่​เรา​นั่ง​จินตนาการ​ขึ้น​เอง แล้ว​ความ​ล้มเหลว​จริง​หา​ได้​จาก​ไหน มี​สอง​แหล่ง​หลัก​ตาม​ช่วง​ชีวิต​ของ​ระบบ:

  1. ก่อน​ปล่อย — จาก​สิ่ง​ที่​คุณ​ทดสอบ​ด้วย​มือ​อยู่​แล้ว ก่อน​ปล่อย​ทุก version เรา​มัก​ลอง​สั่ง agent ด้วย​มือ​แล้ว​ดู​ว่า​มัน​พัง​ตรง​ไหน เคส​ที่​คุณ​ลอง​ด้วย​มือ​ซ้ำๆ ก่อน​กด​ปล่อย​นั่น​คือ​คือ​เคส eval ชุด​แรก — แค่​จด​มัน​ลง​เป็น​ชุด​ที่​รัน​ซ้ำ​ได้ แทนที่​จะ​ลอง​แล้ว​ลืม
  2. หลัง​ปล่อย — จาก bug tracker กับ​คิว support พอ​ขึ้น​โปร​ดัก​ชัน ทุก bug ที่​ผู้​ใช้​แจ้ง​เข้า​มา​และ​ทุก​ตั๋ว​ใน​คิว support คือ​เคส​จริง​ที่​ราคา​แพง​เพราะ​มี​คน​เจอ​ไป​แล้ว ดึง​มัน​กลับ​มา​เป็น​เคส​ใน Golden Dataset เพื่อ​กัน​ไม่​ให้​ความ​พัง​แบบ​เดิม​หลุด​ซ้ำ

สำหรับ ops-copilot คืน​เงิน​ของ​เรา เคส​จริง​หน้าตา​แบบ​นี้: “คืน​เงิน ฿100 ทั้ง​ที่​ควร​เป็น ฿120”, “คืน​เงิน​ผิด​ออเดอร์”, “บอกว่า​คืน​เงิน​แล้ว​แต่​ฐาน​ข้อมูล​ไม่​ขยับ” — แต่ละ​อัน​เคย​เกิด​จริง​และ​มี​คน​เจอ​จริง

จุด​ที่​ต้อง​ย้ำ: เกณฑ์​ผ่าน​ของ​แต่ละ​เคส​ต้อง​เป็น outcome ที่​ตรวจสอบ​ได้ ไม่ใช่​คำ​บอก​เล่า​ของ agent เอง สำหรับ​เคส​คืน​เงิน​ออเดอร์ #123 เกณฑ์​ผ่าน​คือ “มี​แถว​คืน​เงิน​ของออเดอร์ #123 ใน​ฐาน​ข้อมูล​จริง จำนวน ฿120” ไม่ใช่ “agent พิมพ์​ว่า ‘คืน​เงิน​เรียบร้อย’” — ถ้า​เกณฑ์​ผูก​กับ​คำ​พูด​ของ agent เคส​ทั้ง​ชุด​ก็​ผ่าน​ลวงตา​ได้​หมด

# สเก็ตช์ golden dataset เพื่อสื่อไอเดีย ไม่ใช่ file ที่รันได้จริง
# แต่ละเคส "มาจากของจริง" และมี outcome ที่ตรวจสอบได้ ไม่อิงคำพูด agent
- id: refund-wrong-amount
source: bug-tracker#412 # เคยพังจริง ผู้ใช้แจ้งเข้ามา
input: "คืนเงินออเดอร์ 123"
expect_db: # เช็คสถานะจริงของฐานข้อมูล ไม่ใช่ agentReply
refunds: { orderId: 123, amount: 120 }
- id: refund-wrong-order
source: support-queue#88
input: "คืนเงินออเดอร์ล่าสุดของลูกค้าคนนี้"
expect_db:
refunds: { orderId: 501, amount: 90 } # ต้องเป็น 501 ไม่ใช่ออเดอร์อื่น
- id: refund-says-done-but-noop
source: manual-test # เจอตอนลองด้วยมือก่อนปล่อย
input: "คืนเงินออเดอร์ 777"
expect_db:
refunds: { orderId: 777, amount: 250 } # ต้องมีแถวจริง ไม่ใช่แค่ข้อความ

ต้อง​เห็น​ภาพ​ให้​ชัด​ว่า “20 เคส​ก็​พอ” เป็น จุด​เริ่มต้น ไม่ใช่​ปลายทาง ชุด 20–50 เคสมี​ไว้​จับ bug ก้อน​ใหญ่​ที่ effect size โต​พอ​จะ​เห็น​ได้​เร็ว มัน​ไม่ใช่​ชุด​ที่​พอ​ไป​ตลอด พอ​ผ่าน​ช่วง​แรก วินัย eval ชุด​เดียวกัน​นี้​จะ​เรียกร้อง​ให้​เรา​ขยับ​ไป​อ่าน trace จริง​เป็น​ร้อยๆ เคส​ใน​ทุกรอบ​ของ error analysis (บท​ที่ 6) — ที่​นั่น Golden Dataset จะ​โต​ขึ้น​เรื่อยๆ จาก​เคส​พัง​จริง​ที่​อ่าน​เจอ ไม่ใช่​หยุด​ที่ 20

กลไก​ที่​ทำให้​มัน​โต​คือ​วง​ป้อน​กลับ: ทุก​ความ​ล้มเหลว​ใหม่​ที่​เจอ — ไม่​ว่า​จาก support, จาก​การ​อ่าน trace, หรือ​จาก version ใหม่​ที่​ทำ​เคส​เก่า​พัง — ถูก​ดึง​กลับ​มา​เป็น​เคส​ใหม่​ใน​ชุด ชุด​จึง​ค่อยๆ ครอบคลุม​ความ​จริง​มาก​ขึ้น​ตาม​อายุ​ของ​ระบบ

flowchart LR
  F["failure จริง<br/>manual test ก่อนปล่อย<br/>+ bug tracker + คิว support"]
  F --> G["golden set เล็ก<br/>20-50 เคส<br/>แต่ละเคสมี outcome ที่ตรวจได้"]
  G --> E["รัน eval แล้วแก้ prompt หรือ model<br/>effect size ใหญ่ จับ bug ก้อนโตได้เร็ว"]
  E --> B6["บทที่ 6 error analysis<br/>อ่าน trace จริง 100+ เคส"]
  B6 -->|เคสพังใหม่ป้อนกลับเข้าชุด| G
  classDef start fill:#16a34a,stroke:#065f46,color:#f8fafc;
  classDef grow fill:#2563eb,stroke:#1e3a8a,color:#f8fafc;
  class F start;
  class B6 grow;

คำ​บรรยาย​ภาพ: สาย​ธาร​ของ eval set เริ่ม​จาก​ความ​ล้มเหลว​จริง (เขียว) — จาก manual test ก่อน​ปล่อย​และ​จาก​คิว bug/support — กลั่น​เป็น golden set เล็กๆ 20–50 เคส​ที่​แต่ละ​เคสมี outcome ตรวจ​ได้ ใช้​ชุด​นี้​รัน eval แล้ว​แก้ prompt/model จับ bug ก้อน​ใหญ่​ได้​เร็ว​เพราะ effect size ยัง​โต จาก​นั้น (น้ำเงิน) บท​ที่ 6 พา​ไป​อ่าน trace จริง​เป็น​ร้อย​เคส และ​เคส​พัง​ใหม่​ที่​เจอ​ถูก​ป้อน​กลับ​เข้า​ชุด ทำให้ Golden Dataset โต​ขึ้น​เรื่อยๆ ไม่ใช่​หยุด​นิ่ง​ที่ 20

เริ่ม​ด้วย eval set เล็กๆ 20–50 เคส เพราะ​ตอน​แรก effect size ยัง​ใหญ่ ชุด​หลัก​สิบ​เคส​ก็​จับ bug ก้อน​โต​ได้ ไม่​ต้อง​รอ​สร้าง​ชุด​สมบูรณ์​ก่อน​จึง​เริ่ม เคส​ต้อง​มา​จาก​ความ​ล้มเหลว​จริง — สิ่ง​ที่​คุณ​ทดสอบ​ด้วย​มือ​ก่อน​ปล่อย และ​ตั๋ว​ใน bug tracker/คิว support — ไม่ใช่​เคส​ที่​จินตนาการ​เอา และ​แต่ละ​เคส​ต้อง​ผูก​กับ outcome ที่​ตรวจสอบ​ได้​จริง เช่น​แถว​คืน​เงิน​ใน​ฐาน​ข้อมูล ไม่ใช่​คำ​พูด​ของ agent สุดท้าย 20 เคส​คือ​จุด​เริ่ม ไม่ใช่​จุดจบ บท​ที่ 6 จะ​พา​ชุด​นี้​โต​ขึ้น​ด้วย error analysis บน trace จริง​เป็น​ร้อย​เคส


🔗 อ้างอิง​ต้นทาง​ของ​บท​นี้

บท​นี้​สังเคราะห์​จาก​สอง​แหล่ง​หลัก อ่าน​ต่อ​ได้ที่​ต้นทาง​โดยตรง:

  • Anthropic, “Demystifying evals for AI agents” — “20-50 simple tasks drawn from real failures is a great start” และ​ที่มา​ของ​เคส​จาก manual test ก่อน​ปล่อย​กับ bug tracker/คิว support
  • Anthropic, “How we built our multi-agent research system” — ทีม​จริง “started evaluating immediately” ด้วย “about 20 queries representing real usage patterns” (อ้าง​เพื่อ​วิธีการ​เริ่ม​เล็ก ไม่ใช่​ตัวเลข​ประสิทธิภาพ)

เช็กความเข้าใจ — บทที่ 5

ข้อ 1 / 3

ทำไมชุดแค่ 20–50 เคสถึง 'พอ' ตอนเริ่มต้น?