อย่านึกถึงช้างสีชมพู: ยิ่งสั่ง model ว่า "ห้าม" มันยิ่งเขียน
10 พฤศจิกายน 2569 · ThaiPo
อย่านึกถึงช้างสีชมพู นั่นไง คุณเพิ่งทำสิ่งเดียวที่ถูกขอว่าอย่าทำไปเรียบร้อย language model ก็เป็นเหมือนกัน ต่างกันแค่ว่า model จะพิมพ์มันลงไปในแชทของใครสักคนด้วย
free tier ของ ThaiPo รันบน model ที่ถูกกว่า ส่วน Pro รันบนตัวที่เก่งกว่า ข้อจำกัดประจำของงานด้านคุณภาพนั้นพูดกันตรงๆ ได้เลย: เราจะไม่ซื้อ model ที่ใหญ่ขึ้น ทุกการปรับปรุงต้องมาจากสิ่งที่เราส่งให้ model ตัวที่มีอยู่แล้ว มันเลยน่ากระอักกระอ่วนอยู่หน่อย ที่สัญชาตญาณแรกสุดของเราเวลาจะแก้คำแปลผิด คือการบอก model ว่าอย่าเขียนอะไร กลับทำให้มันเขียนสิ่งนั้นออกมาเป๊ะๆ

gloss ที่ย้อนมาเข้าตัว
เมื่อ audit เจอคำหรือวลีที่ model อ่านผิดซ้ำๆ เราจะเขียน gloss: คำใบ้บรรทัดเดียวที่บอกว่าควรอ่านมันยังไง มีวลีภาษาอังกฤษธรรมดาๆ วลีหนึ่งที่ออกมาเป็นไทยผิดอยู่เรื่อย gloss เลยบอกว่าวลีนั้นหมายถึงอะไร แล้วเพื่อความรอบคอบ ก็ระบุคำไทยที่ผิดไว้สองคำ พร้อมสั่งว่าห้ามเขียนทั้งสองคำ
เราลองกับ row ที่เคยพลาดจริง model ตัวถูกเขียนคำต้องห้ามคำหนึ่งออกมา สองครั้งจากสองครั้ง
gloss ที่เขียนใหม่ไม่เอ่ยถึงคำผิดเลยสักคำ ให้แค่คำแปลที่ถูก ในรูปประโยคตัวอย่างเต็มๆ หนึ่งประโยค หกจากหก
คำอธิบายไม่มีอะไรลึกลับ model ตัวเล็กลอก token ที่มันมองเห็น คำที่ถูกปฏิเสธก็ยังเป็นคำที่นั่งอยู่ใน prompt อยู่ในภาษาปลายทาง ติดกับสิ่งที่กำลังจะแปล "never" เป็นสัญญาณที่อ่อน ตัวคำเองเป็นสัญญาณที่แรง เราเคยเจอญาติของอาการนี้มาก่อนแล้ว ตอนที่ตัวอย่างใน gloss รั่วออกไปอยู่ใน output
กฎที่เราเก็บไว้นั้นแคบ "never" ใช้กับแนวคิดได้ไม่มีปัญหา (ไม่ใช่ชื่อคน ไม่ใช่เรื่องอากาศ) สิ่งที่ห้ามยกมาอ้างคือ token ที่ผิดตัวนั้นเป๊ะๆ ในภาษาของ output โชว์ประโยคที่ถูก แล้วหยุดพูด
คำใบ้อยู่ตรงไหน สำคัญพอๆ กับว่ามันพูดอะไร
สัญชาตญาณข้อที่สองที่ต้องฝืนคือการเลื่อนขั้นทุกการแก้ให้เป็นกฎถาวร system prompt ที่งอกประโยคใหม่ทุกครั้งที่มี bug จะกลายเป็นกำแพงกฎ แต่ละข้อทำให้ข้ออื่นเจือจางลง และแต่ละข้อคือคำที่ model อาจโดนชี้นำได้ในข้อความที่ไม่เกี่ยวอะไรกับมันเลย
gloss จึงถูกแนบไปเฉพาะกับข้อความที่มีคำเจ้าปัญหาอยู่ มันเกาะไปที่หางของ prompt หลังส่วนที่ถูก cache สิบกว่า token เมื่อจำเป็น นอกนั้นไม่มีอะไรเลย
ตำแหน่งนี้ยังเป็นสิ่งที่ทำให้ prompt template กลางนิ่งระดับ byte ซึ่งได้ของมาสองอย่าง provider ทำ cache จาก byte ของ prefix แบบตรงตัว prefix ที่ไม่เคยเปลี่ยนจึงเป็น prefix ที่เราแทบไม่ต้องจ่าย และ template ของภาษาที่เราวัดมาดีที่สุดถูก test ตรึงไว้แบบ byte ต่อ byte เทียบกับผลที่บันทึกไว้ การแก้สำนวนจีนสักอันจึงไม่มีทางไปเปลี่ยนสิ่งที่ prompt ภาษาอังกฤษพูดได้ในทางกายภาพ prompt ของแต่ละภาษามีชื่อภาษานั้นอยู่ข้างใน แต่ละภาษาจึงนั่งอยู่บน cached prefix ของตัวเองอยู่แล้ว พร้อมโน้ตสั้นๆ ของตัวเองว่าจะอ่านภาษานั้นยังไงและเขียนยังไง แก้ภาษาเดียว ภาษาอื่นไม่มีทางรู้เลยว่ามีอะไรเกิดขึ้น
ผลการวัด เล่าตามที่วัดมาจริง:
- gloss ใหม่เก้าตัวจาก audit รอบเดียว ทำให้ failure ที่มันเล็งไว้ลดจาก 16 ใน 30 เหลือ 3 ใน 30 โดยข้อความ control ยังสะอาด
- ชุดก่อนหน้านั้น ปล่อยไปพร้อมการแก้โค้ดเล็กๆ ไม่กี่จุดและทดสอบรวมเป็นก้อนเดียว บน failure จริง 29 เคส ด้วยสาม sample ต่อ arm และ reviewer แบบ blind สองคน: ก่อนแก้ชวนเข้าใจผิด 32% หลังแก้ 1%
- กฎการอ่านข้อเดียวที่หาง ทำให้ความผิดพลาดด้านความหมายลดจาก 8 เหลือ 3 บนข้อความจริง 53 ข้อความ ส่วน model ที่แพงกว่ามาก ซึ่งไม่ได้รับกฎอะไรเลย ก็ได้ 3 เหมือนกัน
ไม่ใช่ทุกอย่างจะได้ผล และอันที่พลาดก็ให้บทเรียน กฎคู่กันสำหรับอีกทิศทางหนึ่งทำให้เกิด format failure สี่ครั้งใน 43 ข้อความ และไม่ได้ปล่อยใช้ gloss สำหรับภาษาอังกฤษแบบพิมพ์ย่อๆ ในแชทแก้ได้หนึ่งเคส แล้วเปลี่ยนคำสั่งให้กลายเป็นคำถาม มันถูกถอดออกในคืนเดียวกัน วิธีการคือการวัด ไม่ใช่ความฉลาดหลักแหลม
มุกเดิม อีกสองรอบ
ภาษาไทยมีคำว่า "I" ที่แยกตามเพศ และ model มักจะไหลสลับไปมาระหว่างคำเหล่านั้นกับผู้ส่งคนเดิมในแชทเดียว เราไม่ได้เพิ่มกฎเรื่องสรรพนาม เมื่อคำแปลของผู้ส่งคนหนึ่งตรงกันครบสามครั้ง คำใบ้ที่หางจะบอกคำที่ลงตัวแล้ว ในการ replay 21 ข้อความที่เคยออกมาผิดคำไป 12 ข้อความ ออกมาถูกทั้ง 21 ต้องยอมรับว่าคำใบ้ตัวนี้แหกกฎของเราเอง: มันบอกคำที่ลงตัวแล้ว จากนั้นก็เอ่ยชื่ออีกคำตามหลัง "never" แต่ใน replay รอบนั้นมันก็ยังอยู่รอด
และตอนที่ model สะท้อนคำทักทายภาษาอังกฤษธรรมดาๆ กลับมาโดยไม่แปลเป็นบางครั้ง retry ที่แค่ถามซ้ำก็ยังสะท้อนกลับมาเหมือนเดิม ขั้นถัดไปที่ตามมาพกคำตอบที่ถูกแบบจับต้องได้ไปด้วยจำนวนหนึ่ง: good morning คือ อรุณสวัสดิ์, thank you คือ ขอบคุณ (สำหรับส่วนที่ดื้อจริงๆ มีตารางคำทักทายแบบตายตัวอยู่ในโค้ด)
ความผิดพลาดบางอย่างไม่ได้เป็นของภาษาไหนเลย
มีความผิดพลาดสองแบบที่โผล่ในทุกคู่ภาษาที่เรา audit: คำปฏิเสธที่หล่นหาย และคำถามที่ถูกส่งไปเป็นประโยคบอกเล่า แบบที่สามเดินทางมาด้วยกัน: ตัวอักษรของภาษาต้นทางไม่กี่ตัวที่ค้างอยู่ใน output คำแปลลื่นๆ ของ "I'm not coming tomorrow" ที่ทำคำว่า "not" หาย อ่านแล้วสวยงาม และพูดความหมายตรงกันข้าม
ไม่มีโน้ตไหนรับเรื่องพวกนี้ไว้ได้ เพราะมันไม่ได้เกี่ยวกับภาษาใดภาษาหนึ่ง ส่วนทางแก้ที่ยั่วใจ คือเพิ่มอีกย่อหน้าว่า "never drop a negation" ลงในทุก prompt ก็คือช้างสีชมพูตัวเดิม ที่มาพร้อมบิลค่า cache
ที่ใช้แทนคือ guard แบบนุ่ม เขียนเป็นโค้ดธรรมดา มันตรวจต้นทางแบบ deterministic (มีคำปฏิเสธไหม เป็นคำถามหนึ่งคำถามพอดีไหม) แล้วตรวจว่า output ยังมีสิ่งนั้นอยู่หรือเปล่า ถ้าไม่มี model จะได้ repair call หนึ่งครั้งพร้อมระบุข้อบกพร่อง ถ้าซ่อมแล้วยังไม่หาย ก็ส่ง output แรกออกไปอยู่ดี
ความนุ่มนี่แหละคือตัวดีไซน์ คำปฏิเสธถูกเรียบเรียงใหม่ได้โดยชอบธรรม ("nobody came" เป็น "the place was empty") มันจึงเป็น hard failure ไม่ได้เด็ดขาด ตรวจเฉพาะการหล่นหายเท่านั้น เพราะการเพิ่มคำปฏิเสธคือวิธีที่ภาษาไทยกับภาษาจีนพูดเรื่องเชิงบวกตั้งมากมาย: คำไทยประจำวันของ "busy" แปลตรงตัวคือ "not free" ส่วนสำนวนที่คำว่า "no" ไม่ได้ปฏิเสธอะไรเลยจะถูกเอาออกจากทั้งสองฝั่งก่อนนับ "no worries" กับ ไม่เป็นไร จึงผ่านสะอาด
ตัว guard เองก็ต้อง debug รายการคำปฏิเสธชุดแรกยิงใส่ 7% ของ row ที่แปลไทยเป็นอังกฤษ คำไทยของ "don't" ซ่อนอยู่ในคำไทยของ "like" (อย่า อยู่ใน อย่าง) คำปฏิเสธภาษาฟินแลนด์สองคำเป็นคำธรรมดาในภาษาดัตช์กับฝรั่งเศส คำลงท้ายคำถามของไทยที่เขียนด้วยอักษรโรมันคือคำว่า "never" ในภาษาอิตาลี หลังผ่านรอบจัดการสำนวน มันยิงใส่ราวครึ่งเปอร์เซ็นต์ของ row และไม่มีต้นทุนอะไรกับที่เหลือ
คันโยกที่ถูกที่สุด
ขออีกเรื่อง เพราะมันเข้าธีมของการไม่เพิ่มคำ provider ของ model ตัวถูกเผยแพร่ค่า temperature ที่แนะนำสำหรับงานแปลไว้ที่ 1.3 เรารัน 157 เคส เคสละสาม sample ที่ temperature สามค่า กับ reviewer แบบ blind สามคน output ที่ชวนเข้าใจผิดเป็น 55, 49, 46 จาก 469 ที่ 1.3, 1.0 และ 0.7 ส่วนขยะล้วนๆ เป็น 2, 1, 0 ประมาณหนึ่งในสามของความผิดพลาดที่ 1.3 เป็นแค่ดวงของการ sampling: อีก sample หนึ่งของ prompt เดียวกันออกมาถูก เราใช้ 0.7 เพิ่ม prompt token ศูนย์ตัว
สรุป
prompt ไม่ใช่คู่มือกฎที่ model เปิดดู มันคือกองข้อความที่ model ได้รับอิทธิพลจากทั้งกอง รวมถึงส่วนที่ขึ้นต้นด้วย "never" เพราะฉะนั้นโชว์คำตอบที่ถูกและเฉพาะคำตอบที่ถูก โชว์เฉพาะตอนที่มันเกี่ยวข้อง ให้ทุกอย่างที่เหลือนิ่งแบบ byte ต่อ byte และเอาการตรวจที่ต้องเป็นจริงเสมอไปไว้ในโค้ด ที่ซึ่ง test ตรึงมันไว้ได้ กระบวนการ ทดสอบ prompt เหมือนโค้ด ของเราบอกได้ว่าการเปลี่ยนแปลงหนึ่งช่วยหรือเปล่า ส่วนเรื่องนี้คือสิ่งที่เราได้เรียนรู้ว่าควรลองเปลี่ยนอะไรก่อน
ThaiPo ออกแบบ สร้าง และดูแลโดยนักพัฒนาคนเดียว Steven Acreman
ลองใช้ในแชทของคุณเอง
ThaiPo อยู่ใน LINE และแปลทุกข้อความให้สองทาง ฟรีตลอดไป เริ่มใช้ฟรี หรือ เพิ่มเพื่อน @thaipo.ai ใน LINE แล้วบอทจะส่งลิงก์สมัครให้ในแชทเลย