productize.life
TH EN
AI · ความน่าเชื่อถือ

AI ที่เขียนโค้ด
มองไม่เห็นบั๊กของตัวเอง

สองครั้งที่โมเดลตัวที่สอง (Codex) จับบั๊กในโค้ดที่ AI ตัวแรกของเราเขียนเอง ครั้งหนึ่งเป็นช่องโหว่ที่นึกว่าปิดแล้ว อีกครั้งเป็น deploy ที่จะปล่อยโพสต์ในอนาคตออกก่อนเวลา กับวิธีตั้งโมเดลตัวที่สองให้รีวิวก่อน merge

Yim· เขียนด้วยกันกับ Dobby (AI Oracle)/23 มิ.ย. 2026/~6 นาที

ตอนนั้นเรากำลังปิดช่องโหว่ด้านความปลอดภัยอยู่ตัวหนึ่ง เป็นช่องที่อันตรายเกินกว่าจะปล่อยไว้ คือสั่ง shell ระดับ root ผ่าน Discord ได้เลย โค้ดที่แก้ก็ตรงไปตรงมา คือไปจำกัดสิทธิ์ของ worker ตัวนั้นให้เหลือแค่อ่านไฟล์ ห้ามรันคำสั่ง ห้ามแก้ไฟล์ เขียนเสร็จ อ่านทวนเองอีกรอบ ทุกอย่างดูเรียบร้อยดี

แต่พอเอาโค้ดก้อนเดิมไปให้โมเดลอีกตัวรีวิว จับได้ในไม่กี่วินาทีว่าในลิสต์สิทธิ์ที่เราเพิ่งเขียน คำสั่ง shell ดันโผล่อยู่ทั้งฝั่ง "อนุญาต" และฝั่ง "ห้าม" พร้อมกัน ช่องที่เรานึกว่าปิดสนิทแล้ว จริง ๆ ยังก้ำกึ่งอยู่ เพราะ config สองบรรทัดขัดกันเอง แก้คือลบบรรทัดที่ขัดออก ช่องโหว่ถึงปิดได้จริง

ที่น่ากลัวคือเราเป็นคนเขียน fix นั้นเอง อ่านทวนเองแล้วด้วย แต่มองไม่เห็น เพราะปักใจไปแล้วว่า "นี่คือโค้ดที่ปิดช่องโหว่" พอเชื่อแบบนั้น สายตาเลยเลื่อนผ่านบรรทัดที่ขัดกันไปเฉย ๆ ตัวที่จับได้ไม่ใช่เราที่ขยันขึ้น แต่เป็นโมเดลที่สองที่ไม่มีสมมติฐานนั้นติดมาด้วย

ช่วงที่ 1ทำไมคนเขียนถึงตรวจงานตัวเองไม่เจอ

เวลา AI เขียนโค้ดให้ มันไม่ได้แค่พิมพ์ออกมาเฉย ๆ แต่มีเหตุผลรองรับอยู่ในหัวว่าทำไมถึงเขียนแบบนั้นทุกบรรทัด พอให้กลับไปอ่านงานตัวเอง เหตุผลชุดเดิมก็ยังอยู่ครบ เลยอ่านผ่านจุดที่ผิดได้สบาย ๆ เพราะในมุมของมัน ทุกบรรทัดมีคำอธิบายหมดแล้ว

เรื่องนี้เราเคยเขียนไว้แล้วในแง่ที่ว่า ทำไม AI ถึงพูดผิดอย่างมั่นใจ โมเดลไม่ได้ตั้งใจโกหก แต่มันเก่งเรื่องหาเหตุผลมารองรับสิ่งที่ตัวเองทำไปแล้ว พอเอาความสามารถนี้มาใช้ตรวจงานตัวเอง ก็กลายเป็นทนายของโค้ดตัวเอง ไม่ใช่คนตรวจ

ทางออกไม่ใช่การจี้ให้โมเดลตัวเดิม "ตรวจให้ละเอียดขึ้น" เพราะปัญหาไม่ได้อยู่ที่ความละเอียด อยู่ที่มุมมองที่ติดมาต่างหาก ทางที่ได้ผลกว่าคือเอาโค้ดไปให้โมเดลอีกตัวอ่าน ตัวที่ไม่ได้เขียนมันมากับมือ ไม่มีเหตุผลเดิมติดหัวมาด้วย เลยเห็นสิ่งที่คนเขียนมองข้าม

นี่คือหลักการเดียวกับที่ทีมพัฒนาใช้กันมานานแล้ว คือคนเขียนกับคนรีวิวไม่ควรเป็นคนเดียวกัน พอย้ายหลักการนี้มาใช้กับงานที่ AI เป็นคนเขียนโค้ดให้ส่วนใหญ่ ก็ยังจริงอยู่ บางทีจริงกว่าเดิมด้วยซ้ำ เพราะ AI เขียนเร็วและมั่นใจกว่าคนมาก

ช่วงที่ 2ครั้งที่สอง: deploy ที่จะปล่อยของในอนาคตออกก่อนเวลา

อีกครั้งที่ตัวรีวิวช่วยไว้ เกิดกับสคริปต์ที่คุมการ deploy บล็อกนี้เอง ระบบออกแบบมาให้ปล่อยโพสต์วันละชิ้นตามคิว เราเขียนโค้ดส่วนที่ก๊อปปี้ไฟล์ทั้งโฟลเดอร์ขึ้นเซิร์ฟเวอร์ก่อน deploy แล้วก็คิดว่าจบ

พอเอา diff ไปให้ Codex รีวิว ก็ชี้จุดที่เรามองไม่เห็นเลย คือถ้าในคิวมีโพสต์ที่อนุมัติไว้แล้วแต่ยังไม่ถึงวันปล่อยอยู่หลายชิ้น การก๊อปปี้ทั้งโฟลเดอร์แล้ว deploy ครั้งเดียว จะดันโพสต์ในอนาคตทั้งหมดขึ้นเว็บพร้อมกัน คิววันละชิ้นที่ตั้งใจไว้ก็พังทันที

มองย้อนกลับไปก็ชัดมาก แต่ตอนเขียนเราโฟกัสอยู่กับ "ทำให้ deploy โพสต์วันนี้ได้" จนไม่ได้คิดว่าไฟล์อื่นในโฟลเดอร์เดียวกันจะติดไปด้วย ตัวรีวิวจัดให้เป็น P2 เราเลยแก้ด้วยการกันโพสต์ที่ยังไม่ถึงคิวออกไปก่อน แล้วค่อยเอากลับเข้ามาหลัง deploy เสร็จ

จุดที่อยากให้สังเกตคือ บั๊กสองตัวนี้คนละแบบกันเลย ตัวแรกเป็นเรื่องความปลอดภัย ตัวหลังเป็นเรื่อง logic ตอน deploy แต่ทั้งคู่เหมือนกันตรงที่ โค้ดรันผ่าน ไม่มี error และถ้าไม่มีตัวที่สองมาอ่าน ก็คงหลุดขึ้น production จริงทั้งคู่

ช่วงที่ 3ตัวที่สองไม่ได้ถูกเสมอ

ถึงตรงนี้ฟังดูเหมือนโมเดลตัวที่สองคือคำตอบของทุกอย่าง แต่ไม่ใช่ มีอีกรอบที่ตัวรีวิวยกจุดหนึ่งขึ้นมาเป็น P2 ในระบบ routing ข้อความ เราอ่านดูแล้วเช็คกับเทสต์ที่มีอยู่ ปรากฏว่าเส้นทางจริงไม่ได้พังอย่างที่เตือน สิ่งที่จับได้เป็นเคสที่แคบมากและยังเถียงได้ว่าถูกต้องตามที่ตั้งใจอยู่แล้ว สุดท้ายเราไม่ได้แก้ตามมัน

ตรงนี้แหละที่สำคัญ ตัวรีวิวที่สองไม่ใช่เจ้านาย แต่เป็นความเห็นที่สอง หน้าที่คือชี้จุดที่ควรหยุดดู ไม่ใช่ตัดสินแทนเรา ทุกจุดที่มันยกมา เรายังต้องเอาไปเทียบกับโค้ดจริงและเทสต์จริงเองอยู่ดี รับมาทุกอย่างโดยไม่คิด ก็อันตรายพอ ๆ กับไม่รีวิวเลย

เราเลยถือว่า ของที่ตัวรีวิวเตือน คือรายการที่ต้องไปยืนยันเอง ไม่ใช่รายการที่ต้องแก้ทั้งหมด ตัวที่ผ่านการยืนยันแล้วเท่านั้นถึงจะได้แก้จริง สองในสามครั้งที่เล่ามา เจอของจริง อีกครั้งเตือนเกิน นั่นคืออัตราที่ใช้งานได้ ตราบใดที่คนยังเป็นคนกดยืนยัน

ช่วงที่ 4ตั้งโมเดลตัวที่สองให้รีวิวก่อน merge

หลักการที่กลั่นได้จากสามครั้งนี้พูดได้ประโยคเดียว คือก่อน merge ทุกครั้ง เอา diff ไปให้โมเดลที่ไม่ได้เป็นคนเขียนโค้ดนั้นอ่านก่อน ส่วนที่เหลือคือทำยังไงให้หลักการนี้เกิดขึ้นทุกครั้งจริง ๆ ไม่ใช่แค่ตอนที่นึกได้

สิ่งที่เราตั้งไว้มีไม่กี่ข้อ ข้อแรกคือให้มันรันแบบ headless คือรันคำสั่งเดียวจบ ตัวรีวิวจะอ่าน repo อ่าน diff รันเทสต์เอง แล้วคืนผลออกมาเป็นจุด ๆ พร้อมระดับความรุนแรง เพราะถ้าต้องนั่งเปิดแชตคุยกับมันทุกครั้ง สุดท้ายก็จะขี้เกียจทำ

ข้อสองคือ งานรีวิวไม่เคยลดสเปกโมเดลเพื่อประหยัด งานอื่นเราเลือกโมเดลตามความยากได้ แต่ตอนรีวิวเราบังคับให้ใช้โมเดลตัวแรงสุดกับการคิดระดับสูงสุดเสมอ เพราะจุดประสงค์ทั้งหมดของขั้นนี้คือจับสิ่งที่คนเขียนมองข้าม จะปล่อยให้ตัวรีวิวมองข้ามตามคนเขียนไปอีกก็ไม่มีประโยชน์

ตัวที่เราใช้เป็นโมเดลที่สองคือ Codex ของ OpenAI เพราะมันมีคำสั่งรีวิว diff ในตัวอยู่แล้ว และที่สำคัญกว่าคือมันมาจากคนละค่ายกับตัวที่เขียน คนละค่ายแปลว่าจุดบอดคนละชุด นั่นคือเหตุผลทั้งหมดที่เราเอามาตรวจกันและกัน ส่วนรายละเอียดว่าเราห่อมันเป็นสคริปต์ของเรายังไง บังคับโมเดลกับตั้ง config ตรงไหน อันนั้นเป็นส่วนที่เรากำลังทำเป็นเครื่องมือของตัวเองต่อ แต่ตัวหลักการกับโครงเป็นแบบนี้

ถ้าจะลองเอาไปใช้ เริ่มจากจุดเดียวก่อนก็ได้ คือครั้งหน้าก่อนจะ merge งานที่ AI เขียนให้ อย่าเพิ่งเชื่อตัวที่เขียน ลองเปิดโมเดลอีกตัวขึ้นมา โยน diff ให้มันอ่าน แล้วถามคำถามเดียวว่า "มีอะไรที่คนเขียนน่าจะมองข้ามไหม" เท่านั้นก็พอเห็นแล้วว่าทำไมคนเขียนกับคนตรวจไม่ควรเป็นตัวเดียวกัน

ที่มาและอ้างอิง
ติดตาม

รับบทความใหม่และของฟรีก่อนใคร

ทิ้งอีเมลไว้ บทความใหม่และของฟรีเป็นครั้งคราวจะส่งไปให้ ไม่สแปม

ใช้อีเมลเพื่อส่งอัปเดตเท่านั้น

ความคิดเห็น

ร่วมพูดคุย

แบ่งปันความคิดเห็นได้เลย

ชื่อจะแสดงต่อสาธารณะ อีเมลเก็บเป็นความลับ ไม่แสดงที่ไหน

กำลังโหลดความคิดเห็น…