04 ตรวจสอบโดยมนุษย์
บันทึกผู้สอนสำหรับการสืบสวนโดยมนุษย์ที่ยึดหลักฐานเป็นหลัก และการส่งต่อแหล่งที่มาจากระบบจริง
คู่มือประกอบสำหรับวิทยากร 04 ตรวจสอบโดยมนุษย์
เวลา
รวม ~20 นาที
- 3 นาที — กรองความคิดเห็นเชิงลบและยืนยัน Chat root ที่เป็นข้อมูลอ้างอิงหลัก
- 4 นาที — สร้าง score config ทั้งสามรายการ จากนั้นจึงสร้างคิวพร้อมไฟล์แนบที่ตายตัว
- 4 นาที — เปิดโค้ดพฤติกรรมที่สังเกตได้ก่อนพูดคุยเรื่องการวินิจฉัย
- 5 นาที — ตรวจสอบหลักฐานในเทรซและรัน SQL ของ
policy-v1/policy-v2เทียบกัน - 4 นาที — กรอกการแก้ไข อนุมัติ ทำงานให้เสร็จสิ้น และบันทึกแหล่งที่มา
การเตรียมล่วงหน้าของผู้สอน
ก่อนที่ผู้เรียนจะมาถึง ให้ยืนยันว่าโมดูล 03 สร้าง chat_turn
ที่เป็นข้อมูลอ้างอิงหลักเพียงหนึ่งรายการ พร้อม Boolean user-thumbs=false และ
sql-execution-success=true เก็บ trace ID ไว้เป็นความลับ และยืนยันว่าเอาต์พุตของ root
มีคำถาม, SQL ที่สร้างขึ้น, แถวข้อมูลที่ส่งคืน และผลลัพธ์ครบถ้วน
สร้าง score config ทั้งสามรายการในโปรเจกต์ทดสอบแบบใช้แล้วทิ้งได้ หากต้องการฝึกซ้อมก่อน แต่อย่าสร้างคิวจริงของผู้เรียนไว้ล่วงหน้า ชุด score-config ID ที่แนบกับคิวจะถูกกำหนดตายตัว ตั้งแต่ตอนสร้างคิว ดังนั้นห้องเรียนควรสร้าง config ทั้งหมดก่อน แล้วแนบให้ครบทั้ง สามรายการ:
| ชื่อ | ชนิด | ค่า |
|---|---|---|
observed-issue | TEXT | หลักฐานแบบข้อความอิสระ |
failure-category | CATEGORICAL | stale-business-policy, incorrect-sql, ambiguous-request, not-actionable |
approved-for-golden | BOOLEAN | true / false |
แบบฝึกหัดการทำ annotation นี้ทำผ่าน UI เท่านั้น สคริปต์ที่รันแบบ runtime ตรวจสอบ score ของเทรซและส่งเสริม (promote) ผลการตรวจทานที่ export ออกมาในภายหลังได้ แต่ไม่สามารถ สร้างคิว บันทึกการตัดสินของมนุษย์ หรือทำงาน annotation ให้เสร็จสิ้นแทนได้
แนวทางการบรรยาย
-
กรอง Tracing ด้วย
user-thumbs = falseและจับคู่กับ trace ID จาก worksheet ของโมดูล 03 พูดว่า: “feedback เป็นตัวกำหนดว่าเราจะสืบสวนอะไรต่อ ไม่ใช่ตัวสรุปว่า ข้อสรุปคืออะไร” -
ใช้ Settings → Scores → Create สร้าง score config แต่ละรายการ จากนั้นใช้ Annotations → Queues → Create ตั้งชื่อคิวว่า
production-investigation-<session>โดยมีส่วนต่อท้ายเฉพาะของเซสชัน และแนบ config ทั้งสามรายการเข้าไป -
เลือก root observation
chat_turnเปิดเมนู Annotate แล้วเลือก คิวที่สร้างใหม่ ให้ดูllm_callซึ่งเป็น child ด้วย แต่อธิบายว่าเหตุใดจึงเป็นเป้าหมายที่ผิด: เพราะมันขาดผลลัพธ์การทำงานแบบมีโครงสร้างตั้งแต่ต้นจนจบ และไม่ใช่จุดเกิดเหตุ (incident) ของ feedback ในเชิงตรรกะ -
เตือนผู้เรียนว่าโมดูล 03 ได้เปิดเผยการตั้งค่าที่จำลองไว้แล้ว จากนั้นขอให้พวกเขาพักความรู้ นั้นไว้ก่อนชั่วคราว และฝึกทำ open-coding โดยสังเกตพฤติกรรมจริง บันทึกแรกที่ดีตัวอย่างคือ:
The SQL executed and returned a count. The observed count differs from the second reference count. The query uses a 90-day customer signup window, and the trace metadata reports policy-v1. -
เมื่อห้องเรียนบันทึกข้อสังเกตนั้นแล้วเท่านั้น จึงเปิดเผยหลักฐานทั้งหมด: metadata ที่ปล่อยออกมา คือ
policyversion=policy-v1, SQL/ผลลัพธ์ที่อิงตามการลงทะเบียนใช้งาน (signup) และ score ทั้งสองตัว ฟิลด์ต้นทางคือpolicy_versionส่วน OpenTelemetry adapter จะปล่อย key ที่ผ่านการ sanitize ของ Langfuse ออกมาเป็นpolicyversion -
รันนิยามของนโยบายทั้งสองเวอร์ชันเทียบกัน ข้อมูลอ้างอิงของ
policy-v1คือ:SELECT count() FROM v_customers WHERE signup_date >= today() - INTERVAL 90 DAYข้อมูลอ้างอิงของนโยบายปัจจุบัน
policy-v2คือ:SELECT uniqExact(customer_id) FROM v_orders WHERE order_ts >= now() - INTERVAL 30 DAY AND status NOT IN ('cancelled', 'returned') -
เมื่อเปรียบเทียบเสร็จแล้วเท่านั้น จึงให้ลงข้อวินิจฉัย: บันทึก
failure-category=stale-business-policyสลับ Corrected Output ไปเป็น plain-text mode แล้ววาง query ปัจจุบันแบบดิบลงไป Langfuse ไม่รัน SQL ให้ ดังนั้นต้องตรวจสอบข้อความเดียวกันเป๊ะ ๆ ผ่าน read-only client ของขั้นตอนที่ 6 ก่อนตั้งค่าapproved-for-golden=trueและทำงานให้เสร็จสิ้น -
เก็บรักษา
source_trace_id,failure_category,source_policy_version, ค่าที่แก้ไข และ annotation task ID (ถ้ามี) ไว้สำหรับโมดูล 05
สามข้อวินิจฉัยที่ดูน่าเชื่อแต่ผิด
- “โมเดลไม่ทำตามพรอมป์” SQL ในเทรซเป็นไปตามบริบท
policy-v1ที่ระบุไว้อย่างชัดเจน ความล้มเหลวอยู่ที่นโยบายที่ deploy ไว้ล้าสมัย ไม่ใช่การไม่ทำตาม คำสั่งที่ให้มา - “
sql-execution-successเสีย” SQL รันสำเร็จจริง ดังนั้น evaluator ด้านการทำงานจึงคืนค่าtrueได้อย่างถูกต้อง การออกแบบของมันไม่ได้ทดสอบความถูกต้องเชิง ความหมายทางธุรกิจที่อยู่ภายใต้การกำกับ (governed) - “thumbs-down พิสูจน์ว่า SQL ผิด” feedback บอกแค่ว่าเทรซนี้ควรค่าแก่การตรวจทาน มันไม่ได้ชี้ชัดเจตนาของผู้ใช้หรือให้ query ที่แก้ไขแล้วผ่านการยืนยัน; การเทียบนโยบาย เคียงข้างกันและการตรวจสอบโดยมนุษย์ต่างหากที่ทำหน้าที่นั้น
เก็บทางเลือกเหล่านี้ให้ผู้เรียนเห็นไว้จนกว่าพวกเขาจะได้ open-code เทรซด้วยตนเอง แม้ ผู้สอนจะรู้คำตอบที่จำลองไว้อยู่แล้ว แต่การสืบสวนก็ควรยังคงจำลองกระบวนการตรวจทานที่ ยึดหลักฐานเป็นหลักแบบที่ใช้งานจริง
การเลือก root observation ให้ถูกต้อง
มี observation ที่เกี่ยวข้องอยู่สองรายการในเทรซ:
| รายการสังเกต (observation) | เนื้อหาที่มี | ใช้ทำ annotation หรือไม่ |
|---|---|---|
รายการราก chat_turn | คำถาม พร้อม SQL/ผลลัพธ์/เอาต์พุตแบบมีโครงสร้าง | ใช่ |
รายการลูก llm_call | บทสนทนาของโมเดล, SQL ที่สร้างขึ้น, การใช้โทเค็น | ไม่ใช่ |
หากผู้เรียนเผลอเพิ่ม child เข้าคิวโดยไม่ได้ตั้งใจ อย่าทำงานนั้นให้เสร็จเสมือนเป็นการสืบสวน
production ที่ถูกต้อง ให้เพิ่ม root chat_turn เข้าคิวที่ถูกต้อง และเก็บ/ลบ task
ที่ผิดพลาดตามนโยบายการเก็บรักษาข้อมูลของโปรเจกต์ ให้เก็บ trace ID ไว้
ไม่ใช่ ID ของ child observation ในฟิลด์ source_trace_id
ไฟล์แนบของคิวที่ตายตัว และการตั้งชื่อให้ปลอดภัยสำหรับการรีเซ็ต
Langfuse จะกำหนดชุด score-config ID ที่แนบกับคิวให้ตายตัวตอนที่คิวถูก สร้าง คิวไม่สามารถแนบ config ที่ตกหล่นไปเพิ่มในภายหลังได้ ดังนั้นการสร้าง config ทั้งหมดก่อนจึงเป็นแนวทางที่ปลอดภัยที่สุด ตัว score config เองสามารถแก้ไขได้: การแก้ไข name, schema หรือค่าของ categorical ที่รองรับต้องผ่านการอัปเดต score config แบบมี audit และการอัปเดตนั้นจะไม่เขียนทับ score ที่มีอยู่แล้ว
ใช้ suffix ที่ปลอดภัยสำหรับการรีเซ็ต เช่น:
production-investigation-<session>-retry-1หากคิวตกหล่น config บางรายการ หรือแนบ config ID ผิด ให้สร้างคิวใหม่ที่มี suffix ต่างออกไปโดยแนบ ID ที่ถูกต้องครบทั้งสามรายการ เพิ่ม root ที่เป็นข้อมูลอ้างอิงหลักเข้าไปอีกครั้ง และทำเครื่องหมายคิวเก่าให้เห็นชัดว่าถูกแทนที่แล้ว (หรือลบออกได้เฉพาะเมื่อนโยบายของโปรเจกต์อนุญาต) ส่วนการแก้ไขที่รองรับกับ config ที่แนบอยู่แล้ว ให้ใช้การอัปเดต score config แบบมี audit แทนการสร้างคิวใหม่ อย่านำชื่อคิวที่เสร็จสมบูรณ์แล้วมาใช้ซ้ำในทางที่ทำให้ สับสนว่า task ใดเป็นตัวที่ให้ผลการตัดสินใจจริง
ความน่าเชื่อถือของ corrected output
ค่าที่แก้ไขจะกลายเป็น golden ground truth ในอนาคต ดังนั้นทั้งไวยากรณ์และความถูกต้อง ตามนโยบายจึงสำคัญทั้งคู่ สลับ Corrected Output ไปเป็น plain-text mode ก่อนวาง raw SQL Langfuse จะเก็บข้อความไว้แต่ไม่รันมัน ก่อนอนุมัติ ให้รัน ข้อความที่ตรงกันเป๊ะ ๆ ผ่าน read-only ClickHouse client ของขั้นตอนที่ 6 query ที่ดู ถูกต้องแต่มีรูปแบบผิดพลาด อ้างอิงตาราง raw ตรง ๆ มีหลายคำสั่งรวมกัน หรือรันไม่ผ่านใน ClickHouse ต้องไม่ได้รับการอนุมัติ
สำหรับ SQL ที่มีรูปแบบผิดพลาด:
- ตั้งค่าหรือคงค่า
approved-for-golden=falseไว้; - อย่าทำงานให้เสร็จสิ้นเสมือนได้รับการอนุมัติ;
- แก้ไขค่าที่ป้อนให้ตรงตาม view
v_*ที่ได้รับอนุญาต; - รันใหม่และตรวจสอบผลลัพธ์; และ
- อนุมัติและทำงานให้เสร็จสิ้นเมื่อผ่านการยืนยันแล้วเท่านั้น
หากมีคนทำงานที่มีค่าแก้ไขผิดรูปแบบให้เสร็จสิ้นไปแล้ว ให้สร้างคิว/suffix ของ task ใหม่และทำ การตรวจทานซ้ำ อย่าแก้ไขข้อมูลอย่างเงียบ ๆ จนลบล้างเส้นทางการตรวจสอบ (audit trail) คำสั่ง promotion ของโมดูล 05 ก็ตรวจสอบความเป็น read-only ของ SQL และรันมันด้วยเช่นกัน แต่การป้องกันนั้นไม่ใช่สิ่งที่ใช้แทนการตรวจสอบโดยมนุษย์ได้
ความล้มเหลวที่พบบ่อย
- ไม่พบ trace หลังกรอง — ยืนยันว่า score type เป็น Boolean และตัวกรองคือ
user-thumbs=false; อย่าค้นหาชื่อ score เก่า ให้จับคู่กับ trace ID จาก worksheet แทนการเลือก curl diagnostic ที่ไม่มีการให้คะแนน - เป้าหมายผิด — task แสดงเฉพาะ transcript/SQL เพราะเพิ่ม
llm_callเข้าไป ให้กลับไปที่เทรซและเพิ่ม rootchat_turnเข้าไปแทน - คิวขาดมิติที่ต้องมี — คิวถูกสร้างขึ้นโดยไม่ได้แนบ config ID ที่จำเป็นให้ครบ ให้สร้างคิวใหม่ที่มี suffix ต่างออกไป อย่าดำเนินการต่อด้วยแบบฟอร์มตรวจทานที่ไม่สมบูรณ์ ใช้การอัปเดต config แบบมี audit ไม่ใช่การสร้างคิวใหม่ สำหรับการแก้ไขที่รองรับกับ config ที่แนบอยู่แล้ว
- ดูเหมือนไม่มี policy metadata — มองหา
policyversionที่ถูกปล่อยออกมา ไม่ใช่ฟิลด์ต้นทางpolicy_versionแล้วยืนยัน tagpolicy-v1ของ root - ตัวเลขตรงกันโดยไม่คาดคิด — หยุดการวินิจฉัยไว้ก่อน ให้กลับไปรัน preflight ของ สถานการณ์ในโมดูล 03 อีกครั้ง และอย่าสร้างหลักฐานขึ้นจาก data snapshot ที่ไม่มีการเทียบเคียง
- ค่าที่แก้ไขเป็น SQL ที่จัดรูปแบบแล้วไม่ใช่แบบดิบ — สลับ Corrected Output ไปเป็น plain-text mode และวางเฉพาะตัว query เท่านั้น
- ค่าที่แก้ไขรันไม่ผ่าน — Langfuse จะไม่ตรวจจับสิ่งนี้ให้ คงค่า approval ไว้เป็น false แก้ไข แล้วรันข้อความที่ตรงกันเป๊ะ ๆ ผ่าน client ของขั้นตอนที่ 6 อีกครั้งก่อนทำ task ให้เสร็จสิ้น
การทำให้เสร็จสิ้นและการส่งต่อ
ก่อนย้ายไปโมดูล 05 ให้ยืนยันว่า task ที่เสร็จสิ้นนั้นเป็นของ
chat_turn ที่เป็นข้อมูลอ้างอิงหลัก, ข้อสังเกตถูกบันทึกไว้ก่อนการวินิจฉัย, ค่าที่แก้ไขเป็น
SQL ของนโยบายปัจจุบันที่ถูกต้องเป๊ะ ๆ และ task ได้รับการอนุมัติแล้ว worksheet ของผู้เรียนต้องมี:
source=production-feedback
source_trace_id=<authoritative Chat trace ID>
failure_category=stale-business-policy
source_policy_version=policy-v1
annotation_id=<task ID when available>score เชิงลบจากผู้ใช้ยังคงอยู่บนเทรซ production เดิม ในฐานะสัญญาณคัดกรอง (triage) ส่วน annotation ของมนุษย์ให้ ground truth ที่ผ่านการตรวจทานแล้ว โมดูล 05 จะรักษาแหล่งที่มา ทั้งสองส่วนนี้ไว้ตอนที่ทำการ promote ค่าที่แก้ไขและสร้าง evaluator เพื่อป้องกันไว้ล่วงหน้า
03 ปล่อยใช้งานและตรวจจับ
บันทึกผู้สอนสำหรับการปล่อยใช้งานนโยบายที่ฝังไว้ให้ล้าสมัยและสาธิตการพลาดของการประเมินออนไลน์ในสถานการณ์จริง
05 ปิดวงจรการปรับปรุง
หมายเหตุสำหรับผู้สอนในการส่งเสริมหลักฐานที่ผ่านการตรวจสอบแล้วขึ้นเป็นข้อมูลอ้างอิง สอบเทียบผู้พิพากษานโยบายทั่วไป และดำเนินการวนรอบการปรับปรุงต่อเนื่องอย่างปลอดภัย