คุณได้สร้างเครื่องมือภายในที่ช่วยให้ทีมสามารถรัน unit test 28 รายการสำหรับฟีเจอร์ที่ขับเคลื่อนด้วย LLM โดยไม่ต้องเรียกใช้ API ของโมเดลเลยแม้แต่ครั้งเดียว คุณทำได้โดยการห่อหุ้มโมเดลไว้ในอินเทอร์เฟซที่สามารถจำลองได้ (fakeable interface) และเพิ่มการประเมินผลสามชั้น ทั้งแบบ deterministic, heuristic และแบบใช้ LLM
การใช้ assertion แบบมาตรฐานจะใช้ไม่ได้ทันทีเมื่อ LLM สร้างข้อความบรรยาย (prose) เพราะ prompt เดียวกันอาจให้ประโยคที่แตกต่างกันในการรันแต่ละครั้ง ดังนั้น assertEqual(output, expected) จึงแจ้งว่าล้มเหลวแม้ว่าโมเดลจะทำงานได้อย่างถูกต้องก็ตาม กลุ่มวิศวกรรมส่วนใหญ่มักจะเลือกปล่อยฟีเจอร์ออกไปโดยไม่มีการตรวจสอบ หรือไม่ก็พยายามทดสอบตัวโมเดลเอง ซึ่งเป็นการปฏิบัติกับเป้าหมายที่เปลี่ยนแปลงอยู่ตลอดเวลา (constantly shifting target) ราวกับว่าเป็นไลบรารีที่คงที่
ทำไมปัญหานี้ถึงสำคัญ
ปัจจุบัน LLM เข้ามาอยู่ในเวิร์กโฟลว์ที่ต้องเผชิญหน้ากับลูกค้า ไม่ว่าจะเป็นการส่งอีเมลหาลูกค้า, การตอบกลับฝ่ายสนับสนุน หรือการสร้างเนื้อหา ข้อมูลที่หลอนขึ้นมา (hallucinated fact) เพียงจุดเดียว หรือข้อมูลระบุตัวตนที่รั่วไหลเพียงอย่างเดียว ก็สามารถทำลายชื่อเสียงของแบรนด์ เปิดเผยข้อมูลส่วนตัว หรือทำให้เกิดการละเมิดข้อกำหนดด้านการปฏิบัติตามกฎระเบียบ (compliance) ได้ หากไม่มีกลยุทธ์การทดสอบที่เชื่อถือได้ ทีมงานจะต้องเสียเวลาไปกับการไล่ตามความล้มเหลวที่ไม่เสถียร (flaky failures) หรือปล่อยบั๊กที่เพิ่งจะมาปรากฏในขั้นตอน production
แนวทาง: ลดขอบเขตความรับผิดชอบของโมเดลลง
ขั้นตอนแรกคือการจำกัดสิ่งที่ LLM ต้องทำจริงๆ ในระบบของผู้เขียน โมเดลจะทำหน้าที่เพียงแค่ร่างข้อความติดต่อเท่านั้น ส่วนตรรกะการกำหนดเส้นทาง (routing logic), การจัดการสถานะ (state management) และการตรวจสอบความปลอดภัย (safety checks) ทั้งหมดจะยังคงอยู่ในโค้ดปกติ การจำกัดโมเดลให้เหลือเพียงผลลัพธ์เดียวที่กำหนดไว้ชัดเจน จะช่วยให้ระบบโดยรอบยังคงมีความแน่นอน (deterministic) และสามารถทดสอบได้
เพื่อให้สิ่งนี้เป็นไปได้ LLM จะทำงานอยู่เบื้องหลัง provider interface ซึ่งช่วยให้สามารถใช้เวอร์ชันจำลอง (fake version) ในการทดสอบได้ ในสภาพแวดล้อม production ตัว implementation จะเรียกใช้ API ภายนอก แต่ในชุดทดสอบ (test suite) ตัว fake ที่มีน้ำหนักเบาจะส่งคำตอบที่เตรียมไว้ล่วงหน้า (canned response) กลับมา เนื่องจากโค้ดส่วนที่เหลือมีปฏิสัมพันธ์กับอินเทอร์เฟซเท่านั้น เวิร์กโฟลว์ทั้งหมดจึงสามารถทดสอบได้ด้วย unit test โดยไม่ต้องเชื่อมต่อเครือข่ายเลย ผลลัพธ์ที่ได้คือแกนหลักที่คาดเดาได้ซึ่ง unit test ทั้ง 28 รายการจะช่วยตรวจสอบ
ชุดเครื่องมือประเมินผลที่ใช้งานได้จริง
แม้จะมีการจำกัดขอบเขตแล้ว แต่ผลลัพธ์ของโมเดลก็ยังคงมีความไม่แน่นอน (nondeterministic) ผู้เขียนจึงได้สร้างชุดเครื่องมือประเมินผล (evaluation harness) แบบสามชั้น โดยแต่ละชั้นจะจัดการกับความเสี่ยงที่แตกต่างกัน
เลเยอร์ที่ 1 – การตรวจสอบแบบ Deterministic ใช้กฎ regular-expression ง่ายๆ เพื่อดักจับข้อผิดพลาดที่ชัดเจน เช่น ID ของอาคารที่ผิด หรือโทเค็นที่ต้องห้าม การตรวจสอบเหล่านี้ทำได้รวดเร็วและให้ผลลัพธ์แบบ pass/fail ที่ชัดเจน
เลเยอร์ที่ 2 – การตรวจสอบแบบ Heuristic สคริปต์จะมองหาตัวเลขหรือวันที่ที่หลอนขึ้นมา เพื่อระบุการสร้างข้อมูลเท็จที่เห็นได้ชัด อย่างไรก็ตาม วิธีนี้อาจพลาดการกล่าวอ้างที่เป็นเท็จซึ่งไม่มีตัวเลขประกอบ ซึ่งผู้เขียนก็ได้ยอมรับข้อจำกัดนี้อย่างเปิดเผย
เลเยอร์ที่ 3 – LLM judge โมเดลตัวที่สองจะทำหน้าที่ประเมินโทนเสียงและความเป็นมืออาชีพ เนื่องจากขั้นตอนนี้ต้องพึ่งพาระบบที่มีความน่าจะเป็น (probabilistic system) อีกตัวหนึ่ง จึงจะใช้เฉพาะกับแง่มุมที่เป็นอัตวิสัย (subjective) ซึ่งกฎแบบ deterministic ไม่สามารถทำได้
หัวใจสำคัญของชุดเครื่องมือนี้คือชุดข้อมูลที่ใช้ในการประเมิน ผู้เขียนได้เข้ารหัสรูปแบบความล้มเหลวที่ทราบกันดีอยู่แล้ว เช่น กับดักเฉพาะทางและความรู้ในโดเมนนั้นๆ เพื่อให้ชุดเครื่องมือทดสอบความผิดพลาดที่เคยเกิดขึ้นจริงในทางปฏิบัติ มันไม่ใช่เครื่องมือ "ครอบจักรวาล" ที่วิเศษวิโส แต่เป็นตาข่ายนิรภัยที่มุ่งเป้าไปยังจุดที่สำคัญ
สิ่งนี้หมายถึงอะไรสำหรับทีมงาน
- จำกัดหน้าที่ของ LLM ให้เหลือน้อยที่สุด ความรับผิดชอบที่น้อยลงจะทำให้การแยกส่วน (isolation) และการทดสอบทำได้ง่ายขึ้น
- ใส่ตรรกะการกำหนดเส้นทาง, สถานะ และความปลอดภัยไว้ในโค้ด ตรรกะแบบดั้งเดิมจะยังคงมีความแน่นอน (deterministic) และสามารถทดสอบได้อย่างสมบูรณ์
- เปิดให้เข้าถึงโมเดลผ่านอินเทอร์เฟซที่สามารถจำลอง (fakeable interface) ได้ unit test จะทำงานได้โดยไม่ต้องเรียกใช้งานภายนอก ทำให้ชุดการทดสอบรวดเร็วและเชื่อถือได้
- แบ่งการประเมินเป็นชั้นๆ เริ่มต้นด้วยกฎแบบ deterministic เพิ่ม heuristic สำหรับการหลอน (hallucinations) ที่ทราบกันดี และสำรอง LLM judge ไว้สำหรับการตรวจสอบคุณภาพที่เป็นอัตวิสัย
- ระบุข้อจำกัดให้ชัดเจน ไม่มีเลเยอร์ใดที่รับประกันความสมบูรณ์แบบ ชุดเครื่องมือนี้จะดักจับได้เฉพาะสิ่งที่คุณเขียนโปรแกรมให้ตรวจจับเท่านั้น
มุมมองที่ต่างออกไป: คุณยังไม่สามารถทำ unit-test ตัวโมเดลเองได้
ผู้เขียนยอมรับว่าโมเดลคือเป้าหมายที่เคลื่อนที่อยู่ตลอดเวลา แม้แต่เลเยอร์ LLM judge เองก็ยังได้รับความไม่แน่นอน (nondeterminism) แบบเดียวกับที่มันพยายามจะประเมิน ด้วยเหตุนี้ ระบบจึงไม่สามารถรับประกันได้ว่าการหลอนหรือการละเมิดนโยบายทุกอย่างจะถูกตรวจพบก่อนการปล่อยใช้งาน แนวทางนี้ช่วยลดความเสี่ยง แต่ไม่ได้กำจัดความเสี่ยงให้หมดไป และมันต้องอาศัยความสามารถของทีมในการอัปเดตข้อมูลการประเมินให้ทันสมัยอยู่เสมอเมื่อมีรูปแบบความล้มเหลวใหม่ๆ ปรากฏขึ้น
บทสรุป
คุณไม่สามารถเขียน unit test แบบดั้งเดิมเพื่อยืนยันผลลัพธ์ที่แน่นอนของ LLM ได้ แต่คุณสามารถสร้างระบบที่จำกัดขอบเขตอิทธิพลของโมเดล, สามารถเปลี่ยนอินเทอร์เฟซได้ และมีการตรวจสอบผลลัพธ์ผ่านการประเมินแบบเป็นชั้นๆ ที่โปร่งใส การผสมผสานนี้จะเปลี่ยนส่วนประกอบที่เคยไม่เสถียร ให้กลายเป็นส่วนหนึ่งที่คาดเดาได้ของแอปพลิเคชันขนาดใหญ่ที่สามารถทดสอบได้
