self-correction: calculated_total, conflict_detected และ detected_pattern
แนวคิด
แทนที่จะรอให้ validation ภายนอกจับ semantic error แล้วค่อย retry เราออกแบบ schema ให้โมเดลตรวจตัวเองได้ตั้งแต่รอบแรก หลักคือให้ดึงข้อมูลที่เพียงพอต่อการเทียบความสอดคล้องออกมาพร้อมกัน แล้วปล่อยให้เกิดสัญญาณเตือนในตัว output เอง
ทบทวนก่อนว่า semantic error ต่างจาก syntax error อย่างไร syntax error คือ JSON พัง ซึ่ง tool use กำจัดไปแล้ว ส่วน semantic error คือค่าที่ valid ตาม schema แต่ผิดความหมาย เช่น ยอดไม่ตรงหรือค่าอยู่ผิด field การ self-correction คือการทำให้ schema ช่วยเปิดโปง semantic error ประเภทนี้
ทำไมสำคัญ
เทคนิคที่ตรงที่สุดคือดึง calculated_total คู่กับ stated_total ให้โมเดลทั้งอ่านยอดที่เอกสารระบุ และคำนวณยอดจาก line item เองแล้วใส่แยกเป็นสอง field เมื่อได้ทั้งสองค่าออกมา ระบบปลายทางเทียบได้ทันทีว่าตรงกันไหม ถ้าไม่ตรงแปลว่ามี semantic error ที่ต้องสนใจ การให้โมเดล "แสดงงาน" ด้วยการคำนวณแยก ทำให้ความไม่สอดคล้องปรากฏออกมาเป็นข้อมูล ไม่ใช่ซ่อนอยู่ในค่าเดียว
ต่อยอดได้ด้วย field แบบ boolean อย่าง conflict_detected สำหรับกรณีที่เอกสารต้นทางขัดแย้งในตัวเอง เช่น หัวตารางบอกยอดหนึ่งแต่ท้ายเอกสารบอกอีกยอด แทนที่จะให้โมเดลเลือกข้างเงียบ ๆ ให้มันตั้ง conflict_detected เป็น true แล้วรายงานว่าเจอความขัดแย้ง ส่งต่อให้คนหรือระบบตัดสิน นี่รักษาความจริงของเอกสารไว้ ไม่บิดให้ดูสอดคล้องปลอม ๆ
อีก field ที่มีค่าในเชิงวิเคราะห์ระยะยาวคือ detected_pattern การให้โมเดลบันทึกว่า construct หรือ pattern แบบใดในโค้ดที่กระตุ้นให้เกิด finding ช่วยให้ทีมวิเคราะห์ได้ทีหลังว่า finding ประเภทไหนถูก developer ปัดตกบ่อย เมื่อรู้ว่า pattern ใดสร้าง false positive ซ้ำ ๆ ก็ปรับ prompt ของหมวดนั้นได้ตรงจุด เชื่อมกลับไปยังบทเรื่องการกู้ trust ด้วยการปิดหมวดที่ false positive สูงชั่วคราว detected_pattern คือข้อมูลที่ทำให้การปรับปรุงนั้นมีหลักฐาน ไม่ใช่เดา
ทั้งสาม field นี้มีจิตวิญญาณเดียวกัน คือออกแบบ output ให้เปิดเผยปัญหาเชิงความหมายออกมาเอง แทนการหวังว่าค่าที่ได้จะถูกโดยบังเอิญ
ตัวอย่าง
{
"stated_total": { "type": "number" },
"calculated_total": { "type": "number" },
"conflict_detected":{ "type": "boolean" },
"detected_pattern": { "type": ["string", "null"] }
}
// ตัวอย่างผล:
// stated_total 200, calculated_total 250 → ไม่ตรง = semantic error โผล่เอง
// conflict_detected true → เอกสารขัดแย้งในตัว ส่งให้คนตัดสิน
// detected_pattern "nested ternary" → เก็บไว้วิเคราะห์ false positive ทีหลัง
เช็คความเข้าใจ
การดึง calculated_total คู่กับ stated_total ช่วยจับ semantic error อย่างไร
field detected_pattern มีประโยชน์อย่างไรต่อการปรับปรุงระบบระยะยาว