Failure taxonomy — ตั้งชื่อความพลาดก่อนวัด
บทที่แล้วจบด้วยข้อสรุปว่า agent ต้องวัดกันที่ผลลัพธ์และวัดข้ามหลายรอบ แต่พอ eval บอกว่า “ไม่ผ่าน” คำเดียว มันยังไม่บอกอะไรเลยว่าจะไปแก้ตรงไหน ก่อนจะลงมือวัดให้ละเอียด เราต้องมีภาษากลางไว้เรียกความพลาดแต่ละแบบก่อน เพราะความล้มเหลวคนละแบบแก้กันคนละจุด — จับมันไปกองรวมกันเป็น “agent มันพัง” ก้อนเดียวเมื่อไร ก็เท่ากับปิดตาตัวเองไม่ให้เห็นว่าต้องขยับอะไร
บทนี้สร้าง Failure TaxonomyFailure Taxonomyหมวดหมู่ความผิดพลาดที่ได้จากการทำ Open Coding ซ้ำหลายรอบจนเห็นแพทเทิร์นซ้ำ ๆ เช่น วางแผนผิด (Planning Failure), เรียก tool ถูกตัวแต่ได้ผลลัพธ์ผิดเอง (tool-execution failure), หรือแผนถูกแต่ใช้ขั้นตอน/เวลา/ต้นทุนเกินจำเป็น (efficiency failure) — ใช้จัดลำดับว่าจะแก้ปัญหาไหนก่อนเพราะกระทบมากที่สุดProcess — ชุดหมวดหมู่ที่ตั้งชื่อไว้ชัดเจนสำหรับเรียกความล้มเหลวของ agent Chip Huyen จัดความพลาดออกเป็นสามชั้นหลัก: planning failure (วางแผน/ให้เหตุผลผิด), tool-execution failure (เรียก tool ถูกตัวแต่ tool คืนผลผิดเอง), และ efficiency failure (แผนถูกแต่เปลืองขั้น/เวลา/ต้นทุนเกินจำเป็น) (ดู Chip Huyen, “Agents”) ทั้งบทนี้จะเดินเรื่องด้วย ops-copilot ตัวเดิม — agent ที่รับคำสั่งดูแลออเดอร์อาหาร คืนเงิน และยกเลิกออเดอร์
code ตัวอย่างของคอร์สนี้อยู่ที่ repo kaen-food-ordering (กำลังจัดทำ) — ops-copilot agent ทำงานบน domain Order เดิม บทนี้เป็นบทวางกรอบความคิด สเก็ตช์ที่เห็น (type ของหมวดความล้มเหลว, คลัง tool) เป็นภาพร่างเพื่อสื่อไอเดียว่าจะ “ป้ายหมวด” ความพลาดอย่างไร ไม่ใช่ eval harness ที่รันได้ทันที
planning failure — วางแผนผิดตั้งแต่ยังไม่ทันลงมือ
หัวข้อที่มีชื่อว่า “planning failure — วางแผนผิดตั้งแต่ยังไม่ทันลงมือ”Planning FailurePlanning Failureความผิดพลาดหมวดหลักที่เกิดตอน agent วางแผนผิดตั้งแต่ต้น เช่น เลือกเรียก tool ที่ไม่มีอยู่จริง เรียก tool ถูกตัวแต่ใส่ parameter ผิดชนิด/ผิดค่า (เช่น คืนเงิน ฿100 ทั้งที่ควรเป็น ฿120) หรือบรรลุเป้าหมายผิดไปเลย — ต่างจาก tool ที่ทำงานถูกคำสั่งแต่คืนผลลัพธ์ผิดเอง ต้องแก้กันคนละจุดProcess คือความพลาดที่เกิดในหัวของ agent ตอนมันแปลงคำสั่งเป็นแผน — เลือก tool ผิด กำหนดค่าให้ tool ผิด หรือเข้าใจเป้าหมายผิด ทั้งหมดนี้เป็นความผิดพลาดเชิงการให้เหตุผล ไม่ใช่ความผิดของ tool Huyen แยกซับไทป์ของมันไว้ชัด และแต่ละอัน map เข้ากับ ops-copilot ได้ตรงๆ:
- invalid tool — วางแผนเรียก tool ที่ไม่มีอยู่ในคลัง Huyen ยกตัวอย่างว่า “it generates a plan that contains
bing_search, which isn’t in the tool inventory” กับ ops-copilot ก็เช่น วางแผนเรียกbing_searchเพื่อหาที่อยู่ลูกค้า ทั้งที่ระบบมีแค่getOrder,issueRefund,cancelOrder,notifyCustomer - valid tool + parameter ผิดชนิด/จำนวน — เรียก tool ที่มีจริง แต่ใส่ argument ผิดโครงสร้าง Huyen ยกว่า “it calls
lbs_to_kgwith two parameters, but this function requires only one” - valid tool + ค่า parameter ผิด — เรียกถูกตัว โครงสร้างถูก แต่ “ค่า” ที่ใส่ผิด Huyen เขียนไว้ตรงๆ ว่า “uses the value 100 for lbs when it should be 120” — ซึ่งเป็นภาพเดียวกับ ops-copilot เป๊ะ: สั่งคืนเงินออเดอร์ #123 เป็น ฿100 ทั้งที่ยอดจริงคือ ฿120 tool
issueRefundทำงานถูกทุกอย่าง มันแค่ถูกป้อนตัวเลขผิดมา - goal failure — บรรลุเป้าหมายผิดไปเลย หรือทำสำเร็จแต่ละเมิดเงื่อนไข (Huyen ยกตัวอย่างทริปที่จองสำเร็จแต่เกินงบ) กับ ops-copilot คือ คืนเงินสำเร็จ ยอดถูก แต่ คืนผิดออเดอร์ — ไปคืนออเดอร์ #124 แทน #123
จุดที่ต้องเน้น: ทั้งสี่ซับไทป์นี้อยู่หมวดเดียวกันหมด เพราะรากของมันคือ “การวางแผนผิด” invalid tool กับ ค่า parameter ผิด แม้ดูคนละเรื่อง แต่ทั้งคู่คือ agent คิดแผนมาผิด ไม่ใช่ tool ทำงานเพี้ยน — และนั่นชี้ว่าจะไปแก้ที่ prompt กับคำอธิบาย tool ไม่ใช่ไปแก้ตัว tool
tool-execution failure — tool ถูกตัว แต่ผลที่ได้ผิด
หัวข้อที่มีชื่อว่า “tool-execution failure — tool ถูกตัว แต่ผลที่ได้ผิด”หมวดที่สองต่างกันคนละขั้ว: agent วางแผนถูก เลือก tool ถูก ใส่ค่าถูกครบ แต่ตัว tool เองคืนผลลัพธ์ผิด — Huyen ยกตัวอย่างเช่น image caption ที่บรรยายผิด หรือ SQL ที่ generate มาแล้ว malformed กับ ops-copilot คือ agent สั่ง issueRefund(orderId: 123, amount: 120) มาถูกทุกตัวอักษร แต่ตัว tool ต่อฐานข้อมูลแล้วสร้าง query ผิดรูป จนแถวคืนเงินไม่ได้ถูกบันทึกจริง
ความพลาดแบบนี้ ไม่มีทางแก้ได้ด้วยการปรับ prompt เพราะ agent ทำหน้าที่ของมันครบแล้ว ปัญหาอยู่ที่ code ของ tool หรือ integration ปลายทาง นี่คือเหตุผลว่าทำไมต้องแยก planning ออกจาก execution ให้ขาด: อาการปลายทางอาจดูเหมือนกัน (“คืนเงินไม่สำเร็จ”) แต่ต้นตอและวิธีแก้อยู่คนละโลก
efficiency failure — แผนถูก ผลถูก แต่เปลือง
หัวข้อที่มีชื่อว่า “efficiency failure — แผนถูก ผลถูก แต่เปลือง”หมวดที่สามคือกรณีที่ agent ทำงานสำเร็จ ผลลัพธ์ถูกต้อง แต่ใช้ทรัพยากรเกินจำเป็น Huyen บอกให้ติดตามสามตัว: “how many steps… on average,” “how much does the agent cost, on average,” และ “how long does each action typically take” — นั่นคือ จำนวนขั้น, ต้นทุน, และเวลา (latency)
ตัวอย่างชัดๆ ใน ops-copilot: มันยกเลิกออเดอร์เดียวได้สำเร็จ แต่ใช้การเรียก tool ถึง 8 ครั้ง — ดึงออเดอร์ซ้ำไปมา ถามสถานะซ้ำ กว่าจะยิง cancelOrder ทั้งที่งานนี้ทำจบได้ในไม่กี่ขั้น ผลลัพธ์สุดท้ายถูก แต่ถ้าปล่อยไว้ ต้นทุนต่อคำสั่งกับเวลารอของลูกค้าจะบานเมื่อสเกลขึ้น
จำนวนขั้นไม่ได้แพงแค่เรื่องเงินและเวลา — บทที่ 1 ชี้ไว้แล้วว่ายิ่งขั้นเยอะ ความผิดพลาดต่อขั้นยิ่งมีที่สะสม (ตัวเลข 95% ต่อขั้น → ~60% ที่ 10 ขั้นในบทนั้นเป็นการคำนวณเชิงสมมติว่าความผิดพลาดเป็นอิสระต่อกัน ไว้สร้างสัญชาตญาณ ไม่ใช่อัตราพังที่วัดจริง) efficiency failure จึงเป็นทั้งเรื่องต้นทุนและเรื่องความเสี่ยงที่เพิ่มตามความยาวของ agentic loop
ต้นไม้หมวดหมู่ทั้งหมด
หัวข้อที่มีชื่อว่า “ต้นไม้หมวดหมู่ทั้งหมด”flowchart TD ROOT["ความล้มเหลวของ agent<br/>Failure Taxonomy"] ROOT --> P["planning failure<br/>วางแผน/ให้เหตุผลผิด"] ROOT --> T["tool-execution failure<br/>เรียก tool ถูกตัว แต่ tool คืนผลผิดเอง"] ROOT --> E["efficiency failure<br/>แผนถูก ผลถูก แต่เปลืองเกินจำเป็น"] P --> P1["invalid tool<br/>เรียก tool ที่ไม่มีในคลัง เช่น bing_search"] P --> P2["valid tool + parameter ผิดชนิด/จำนวน"] P --> P3["valid tool + ค่า parameter ผิด<br/>คืนเงิน 100 บาท ทั้งที่ควรเป็น 120 บาท"] P --> P4["goal failure<br/>บรรลุเป้าผิด/ละเมิดเงื่อนไข เช่น คืนผิดออเดอร์"] E --> E1["steps — เรียก tool 8 ครั้งเพื่อยกเลิก 1 ออเดอร์"] E --> E2["cost — ต้นทุนต่อคำสั่งสูงเกิน"] E --> E3["latency — ใช้เวลาต่อขั้นนานเกิน"] classDef plan fill:#dc2626,stroke:#7f1d1d,color:#f8fafc; classDef exec fill:#d97706,stroke:#78350f,color:#f8fafc; classDef eff fill:#2563eb,stroke:#1e3a8a,color:#f8fafc; class P,P1,P2,P3,P4 plan; class T exec; class E,E1,E2,E3 eff;
คำบรรยายภาพ: หมวดความล้มเหลวสามชั้นหลัก — planning (แดง), tool-execution (ส้ม), efficiency (น้ำเงิน) โดย planning failure แตกเป็นสี่ซับไทป์ที่รากเดียวกันคือ “วางแผน/ให้เหตุผลผิด” (invalid tool, parameter ผิดชนิด, ค่าผิด, และ goal failure) ส่วน efficiency แตกเป็นสามมิติที่วัดได้ (ขั้น/ต้นทุน/เวลา) สังเกตว่า “คืนเงิน 100 บาทแทน 120” อยู่ใต้ planning ไม่ใช่ tool-execution เพราะ tool ทำงานถูก แค่ถูกป้อนค่าผิด
ทำไมต้องตั้งชื่อให้ถูกหมวด — เพราะแต่ละหมวดแก้คนละจุด
หัวข้อที่มีชื่อว่า “ทำไมต้องตั้งชื่อให้ถูกหมวด — เพราะแต่ละหมวดแก้คนละจุด”คุณค่าของ taxonomy ไม่ได้อยู่ที่การจัดกล่องให้สวย แต่อยู่ที่มันชี้ จุดที่ต้องลงมือแก้ ให้ต่างกัน อาการปลายทางของ ops-copilot อาจเหมือนกันหมด (“ลูกค้าไม่ได้เงินคืน”) แต่ต้นตอกับวิธีแก้อยู่คนละที่:
| หมวดความล้มเหลว | ตัวอย่างจาก ops-copilot | จุดที่ลงมือแก้ |
|---|---|---|
| planning — invalid tool | วางแผนเรียก bing_search ที่ไม่ได้ต่อไว้ | คลัง tool + คำอธิบาย tool ใน prompt |
| planning — ค่า parameter ผิด | คืนเงิน ฿100 แทน ฿120 | prompt / การให้เหตุผล / guard ตรวจค่าก่อนยิง tool |
| planning — goal | คืนเงินผิดออเดอร์ (#124 แทน #123) | prompt / นิยามเป้าหมาย / ยืนยันก่อนลงมือ |
| tool-execution | issueRefund ถูกเรียกถูก แต่คืน SQL ผิดรูป | ตัว tool หรือ integration เอง — ไม่ใช่ prompt |
| efficiency | เรียก tool 8 ครั้งเพื่อยกเลิก 1 ออเดอร์ | ออกแบบ tool ใหม่/รวมขั้น ลดรอบใน loop |
ถ้าเจอ “คืนเงิน ฿100 แทน ฿120” แล้วเผลอไปนับเป็น tool-execution failure เราจะเสียเวลาไล่แก้ code issueRefund ทั้งที่ tool ไม่ได้ผิดอะไรเลย — ปัญหาอยู่ที่ agent ป้อนค่าผิดตั้งแต่ตอนวางแผน การป้ายผิดหมวดจึงพาไปแก้ผิดจุด นี่คือเหตุผลที่ต้องตั้งชื่อความพลาดให้ถูกก่อนจะลงมือแก้
แต่ก่อนจะป้ายหมวดได้ ต้อง เห็นความพลาดจริงๆ ก่อน — และนี่คือจุดเชื่อมกลับไปที่บทที่ 1: เราจะเห็นว่า agent คืน ฿100 แทน ฿120 ก็ต่อเมื่อเราไปดู สถานะจริงของฐานข้อมูล ไม่ใช่เชื่อคำที่ agent พิมพ์ว่า “คืนเงินเรียบร้อย” ถ้า eval เช็คแค่ว่า agent พูดว่า done หรือยัง ความพลาด wrong-value ทั้งหมวดจะล่องหน คำถามที่ eval ต้องถามคือ “มีแถวคืนเงินของออเดอร์ #123 ในฐานข้อมูลจริง จำนวน ฿120 หรือยัง” — outcome ที่ตรวจสอบได้แบบนี้เท่านั้นที่เผยหมวดความล้มเหลวออกมาให้เราจัดกลุ่มได้
สามหมวดของ Huyen เป็นกรอบตั้งต้นที่ดี แต่ taxonomy ของระบบจริงไม่ได้หล่นมาจากตำรา — มันโตขึ้นจากการนั่งอ่าน trace ที่ agent ทำงานจริงทีละเคส แล้วค่อยๆ จัดกลุ่มความพลาดที่เจอซ้ำๆ เป็นหมวดของตัวเอง (กระบวนการนี้คือ error analysis กับ open coding ที่บทที่ 6 จะเจาะเต็มๆ) หมวดสามชั้นในบทนี้จึงเป็นโครงเริ่ม ไม่ใช่รายการปิดตายที่ห้ามเพิ่ม
สิ่งที่จะทำต่อ
หัวข้อที่มีชื่อว่า “สิ่งที่จะทำต่อ”บทนี้ให้ภาษากลางไว้เรียกความพลาด — planning / tool-execution / efficiency พร้อมซับไทป์ — และย้ำว่าแต่ละหมวดแก้กันคนละจุด บทต่อไปกลับไปที่คำถาม “แล้ววัดยังไงให้เห็นหมวดพวกนี้”:
- ตัดสินจากผลลัพธ์ ไม่ใช่เส้นทาง (บทที่ 3) — ทำไม outcome เป็นเกณฑ์หลัก และการไล่เช็ค trajectory ทีละก้าวเข้ามาช่วยตรงไหน
- Human-in-the-loop กับ error analysis (บทที่ 6) — วิธีสร้าง taxonomy ของคุณเองจากการอ่าน trace จริง แทนการยืมหมวดสำเร็จรูปมาทั้งดุ้น
ทุกบทยังเดินเรื่องด้วย ops-copilot ตัวเดิม คำถามปลายทางไม่เปลี่ยน — มีแถวคืนเงินของออเดอร์ #123 จำนวน ฿120 ในฐานข้อมูลจริงหรือยัง
หมวดหมู่ความล้มเหลวในบทนี้อ้างอิงจากแหล่งหลักแหล่งเดียว อ่านต่อได้ที่ต้นทางโดยตรง:
- Chip Huyen, “Agents” — ต้นทางของ taxonomy สามชั้น (planning / tool-execution / efficiency) รวมถึงตัวอย่าง invalid tool (
bing_search), parameter ผิด (lbs_to_kg), ค่าผิด (100 แทน 120) และสามมิติของ efficiency (ขั้น/ต้นทุน/เวลา) - คอร์สนี้ บทที่ 1 — ที่มาของการวัดที่ outcome จริง ซึ่งเป็นเงื่อนไขที่ทำให้เราเห็นความพลาดแต่ละหมวดได้ตั้งแต่แรก
เช็กความเข้าใจ — บทที่ 2
ข้อ 1 / 3การวางแผนเรียก tool ที่ไม่มีอยู่จริง (invalid tool) กับการใส่ค่า parameter ผิด (คืนเงิน ฿100 แทน ฿120) — สองอย่างนี้จัดอยู่ในหมวดความล้มเหลวใด?