แยก access failure ออกจากผลว่างที่ถูกต้อง
แนวคิด
มีสองสถานการณ์ที่หน้าตาคล้ายกันแต่ความหมายต่างกันสิ้นเชิง หนึ่งคือ access failure เช่น tool time out หรือบริการล่ม แปลว่า "เข้าถึงข้อมูลไม่ได้" สองคือ valid empty result เช่น ค้นออร์เดอร์ของลูกค้าแล้วไม่พบเลยจริง ๆ แปลว่า "ค้นสำเร็จ แต่ไม่มีอะไรตรง" สองอย่างนี้ต้องรายงานให้ต่างกัน เพราะการตัดสินใจถัดไปต่างกัน
ถ้า tool คืนอาเรย์ว่างเหมือนกันทั้งสองกรณี coordinator จะแยกไม่ออก access failure ควรนำไปสู่การตัดสินใจว่าจะลองใหม่ เปลี่ยนวิธี หรือ escalate แต่ valid empty result เป็นคำตอบที่สมบูรณ์ในตัวมันเอง เช่น "ลูกค้ารายนี้ไม่มีออร์เดอร์ค้าง" ซึ่งอาจเป็นข้อมูลที่ถูกต้องและ agent ควรตอบไปตามนั้น ไม่ใช่พยายาม retry
มี anti-pattern สองอย่างที่ต้องเลี่ยง หนึ่งคือกลืน error เงียบ ๆ แล้วคืนผลว่างที่ทำเครื่องหมายว่าสำเร็จ ทำให้ access failure ปลอมตัวเป็น empty result สองคือจบทั้ง workflow เพราะความล้มเหลวจุดเดียว ทั้งที่ subagent ตัวอื่นยังทำงานได้และกลยุทธ์กู้คืนยังมีทาง
ทำไมสำคัญ
เอกสาร handle tool calls แยกชนิดของ error ไว้ชัด และแนะนำให้ใช้ is_error เป็น true เฉพาะกับความล้มเหลวในการทำงานของ tool เช่น network error พร้อมข้อความที่บอกสาเหตุ ส่วนผลลัพธ์ที่สำเร็จแต่ว่างเปล่าไม่ใช่ error มันคือ tool_result ปกติที่บังเอิญไม่มีข้อมูลตรง การใช้ธงให้ถูกจึงเป็นการบอก coordinator ตั้งแต่ต้นว่านี่คือความล้มเหลวหรือคำตอบที่สมบูรณ์
เอกสาร tool use overview อธิบายกลไกว่า client tool คืน tool_result กลับให้แอปจัดการ ซึ่งหมายความว่าเรามีอิสระเต็มที่ในการออกแบบว่า result จะมีหน้าตาอย่างไร เราจึงควรใส่ความหมายลงไปให้ชัด แทนที่จะคืนอาเรย์ว่างลอย ๆ ให้คืนโครงสร้างที่บอกว่า "ค้นสำเร็จ พบ 0 รายการ" ต่างจาก "ค้นไม่สำเร็จเพราะ timeout" เพียงเท่านี้ coordinator ก็ตัดสินใจถูก
สิ่งที่ต้องเข้าใจให้ลึกคือ ความคลุมเครือระหว่างสองสถานการณ์นี้เป็นบ่อเกิดของบั๊กที่ตามยาก ถ้า access failure ถูกกลืนเป็น empty result ระบบจะรายงานว่า "ไม่มีข้อมูล" ทั้งที่จริง ๆ แค่เข้าถึงไม่ได้ ซึ่งอาจนำไปสู่รายงานที่ผิดหรือการตัดสินใจที่พลาด การแยกให้ชัดตั้งแต่ชั้น tool จึงป้องกันความผิดพลาดที่ลามไปทั้งระบบ และช่วยให้ subagent กู้คืน transient failure ในระดับตัวเองได้อย่างถูกต้องก่อน propagate ขึ้นไป
ตัวอย่าง
// access failure — เข้าถึงไม่ได้ ควรพิจารณา retry/escalate
{ "is_error": true,
"status": "timeout",
"detail": "order service ไม่ตอบใน 5 วินาที" }
// valid empty result — ค้นสำเร็จ ไม่มีข้อมูลตรง เป็นคำตอบที่สมบูรณ์
{ "is_error": false,
"status": "ok",
"matches": [],
"note": "ลูกค้ารายนี้ไม่มีออร์เดอร์ค้าง" }
เช็คความเข้าใจ
access failure ต่างจาก valid empty result อย่างไร และทำไมต้องรายงานให้ต่างกัน
anti-pattern สองอย่างในการจัดการความล้มเหลวคืออะไร