ผู้ช่วยเขียนโค้ดที่ขับเคลื่อนด้วย AI บนคิวเซิร์ฟเวอร์ระดับฟรีได้เขียนไฟล์ schema-migration ขึ้นมา หลังจากกฎ “freeze migrations” ของระบบหายไปในระหว่างกระบวนการบีบอัดบริบท (context compaction) แบบอัตโนมัติ เหตุการณ์นี้แสดงให้เห็นว่าการพึ่งพาคำสั่งผ่าน prompt เพื่อบังคับใช้ความปลอดภัยอาจส่งผลเสียได้ เมื่อเซสชันการแชทที่ยาวนานถูกสรุปเนื้อหา

เกิดอะไรขึ้น

coding agent ที่ใช้ร่วมกันทำงานด้วย system prompt ที่มีกฎเพียงข้อเดียวคือ: ห้ามสร้างหรือแก้ไขไฟล์ migration กฎนี้ช่วยให้ schema migrations ถูกแช่แข็ง (frozen) ไว้บน release branch ในขณะที่นักพัฒนาใช้ agent สำหรับการแก้ไขงานประจำวัน

ในระหว่างเซสชันที่ยาวนาน บทสนทนาได้เกินขีดจำกัด token ของโมเดล เซิร์ฟเวอร์จึงเรียกใช้ context compaction โดยแทนที่ประวัติการแชททั้งหมดด้วยบทสรุปสั้นๆ เพื่อให้อยู่ในงบประมาณ token บทสรุปยังคงมีการกล่าวถึงเส้นทางไฟล์ (file-path) แต่ได้ตัดข้อจำกัดเชิงปฏิเสธออกไป (“do not write to migrations/**”) เมื่อโมเดลสร้างคำตอบถัดไป กฎการแช่แข็งจึงไม่อยู่ในหน่วยความจำขณะทำงาน (working memory) อีกต่อไป

จากนั้น agent ได้แนะนำการปรับแต่ง SQL เพื่อเพิ่มความเร็วในการคิวรี เครื่องมือที่มาคู่กันได้บันทึกการเปลี่ยนแปลงนั้นเป็นไฟล์ migration ลงในดิสก์ ผลการทดสอบ unit tests ผ่านฉลุยเพราะพวกมันไม่เคยรัน raw SQL migrations และการเปลี่ยนแปลงนี้ถูกตรวจพบในภายหลังผ่าน diff ในขั้นตอน code-review เท่านั้น

ทำไมเรื่องนี้ถึงสำคัญ

  • Guardrails หายไป: นโยบายในระดับ prompt นั้นไม่เสถียร เมื่อบริบทของโมเดลถูกบีบอัด ข้อความประเภท “do not” (ห้าม) อาจสูญหายไป ทำให้ระบบสามารถดำเนินการที่ถูกสั่งห้ามได้โดยอิสระ
  • Unit tests อย่างเดียวไม่พอ: การทดสอบที่ไม่รันสคริปต์ migration อาจทำให้เกิดความรู้สึกปลอดภัยที่ผิดพลาด การเปลี่ยนแปลงนี้หลุดรอดไปได้เพราะชุดทดสอบ (test suite) ไม่เคยรัน SQL ตัวใหม่นี้
  • การตรวจสอบโดยมนุษย์ล่าช้า: กว่าที่ผู้ตรวจสอบจะเห็น diff ไฟล์ migration ก็ถูก commit ไปเรียบร้อยแล้ว ทำให้ต้องทำการ rollback หรือทำความสะอาดโค้ดเพิ่มเติม

ข้อผิดพลาดนี้ไม่ได้ทำให้ระบบล่ม แต่ทำให้ต้องเสียเวลาเพิ่มในการย้อนคืน (revert) migration ที่ไม่จำเป็น และเพิ่มความเสี่ยงที่จะเกิดความผิดพลาดในลักษณะเดียวกันกับฐานข้อมูลที่ใช้งานจริง (live databases)

Guardrail ล้มเหลวได้อย่างไร

  1. กฎที่มีแค่ใน prompt – การแช่แข็งถูกเก็บไว้เป็นข้อความธรรมดาใน system prompt
  2. เซสชันที่ยาวนาน – การแชทยาวเกินหน้าต่างบริบท (context window) ของโมเดล
  3. การบีบอัด (Compaction) – เซิร์ฟเวอร์เปลี่ยนประวัติการสนทนาทั้งหมดเป็นบทสรุปที่เน้นคำนาม
  4. การสูญเสียข้อจำกัดเชิงปฏิเสธ – บทสรุปละทิ้งคำสั่ง “do not” ทำให้กฎหายไป
  5. ผลลัพธ์ของโมเดล – เมื่อไม่มีกฎ โมเดลจึงสร้างคำตอบที่สร้าง migration ขึ้นมา

ตัวสรุปเนื้อหามักจะเก็บคำนามไว้ (เช่น เส้นทางไฟล์, ชื่อฟังก์ชัน) และตัดคำปฏิเสธออก นี่คือเหตุผลว่าทำไมกฎถึงหายไปอย่างเงียบเชียบ

วิธีแก้ไข: ย้าย guardrails ไปไว้ที่เส้นทางการเขียน (write path)

แทนที่จะฝังข้อห้ามไว้ใน prompt ให้บังคับใช้กฎในจุดที่โค้ดมีการเขียนลงดิสก์แทน

  1. สร้างไฟล์นโยบาย (เช่น agent_policy.txt) ที่ระบุเส้นทางที่ไม่อนุญาต (deny-listed paths) เช่น schema/** หรือ migrations/**
  2. เพิ่มสคริปต์ pre-apply ที่อ่านไฟล์นโยบายและสแกนทุก diff ก่อนที่เครื่องมือ apply จะทำงาน
  3. ใช้หลักการ Fail closed หากไม่พบไฟล์นโยบาย, ไฟล์ว่างเปล่า หรือหาก diff มีการแตะต้องเส้นทางที่ต้องห้าม
  4. อย่าขอให้โมเดลยืนยัน รายการที่ไม่อนุญาต เพราะการยืนยันเป็นเพียงสัญญาณ ไม่ใช่การบังคับใช้กฎ

Guardrails แบบใช้แค่ prompt เทียบกับแบบอิงตามดิสก์

หัวข้อ การแช่แข็งผ่าน prompt เท่านั้น การควบคุมผ่านดิสก์
ความเสี่ยงจากการบีบอัด กฎอาจหายไป ไฟล์นโยบายยังคงอยู่ครบถ้วน
การครอบคลุมของ unit-test อาจพลาดการเขียนที่ต้องห้าม การตรวจสอบเส้นทางจะบล็อกการเขียนโดยไม่สนผลการทดสอบ
จังหวะการตรวจสอบโดยมนุษย์ ความเสียหายอาจถูก commit ไปแล้ว การเขียนจะไม่เกิดขึ้นเลย และผู้ตรวจสอบจะไม่เห็นการเปลี่ยนแปลง
ความพยายามในการติดตั้ง น้อยมาก (แค่บรรทัดเดียวใน prompt) สคริปต์ขนาดเล็ก + ไฟล์นโยบาย

ข้อโต้แย้ง

สิ่งที่ควรจับตามองต่อไป

บทสรุป

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