CaMeL: กัน prompt injection ด้วยการออกแบบระบบ ไม่ใช่ด้วย prompt ที่ดีกว่า
งานวิจัย CaMeL จาก Google DeepMind แยก control flow ออกจากข้อมูลที่ไม่น่าเชื่อถือ ติดป้าย capability ให้ทุกค่า แล้วตรวจ policy ตอนเรียก tool ผลบน AgentDojo และข้อจำกัด
- CaMeL ให้โมเดลวางแผนเป็นโค้ดจากคำขอของผู้ใช้อย่างเดียว ข้อมูลจากข้างนอกจึงเปลี่ยนลำดับขั้นของงานไม่ได้
- ทุกค่าติดป้ายว่ามาจากไหนและใครอ่านได้ แล้ว policy ตรวจป้ายตอนเรียก tool ไม่ได้พึ่งโมเดลตัดสิน
- บน AgentDojo ทำงานสำเร็จ 77% แบบมีการรับประกันความปลอดภัย เทียบกับ 84% ของระบบที่ไม่ป้องกัน
- ข้อจำกัดคือ token เพิ่มราว 2.8 เท่า ต้องเขียน policy เอง งานที่ต้องตัดสินจากข้อมูลข้างนอกทำไม่ได้ และยังไม่ได้แก้ prompt injection ทุกแบบ
CaMeL คืองานวิจัยจาก Google DeepMind (Defeating Prompt Injections by Design, มีนาคม 2025 ปรับปรุงมิถุนายน 2025) ที่เลิกพยายามสอนโมเดลให้ “ไม่หลงเชื่อ” ข้อความแปลกปลอม แล้วหันไปออกแบบระบบรอบโมเดลจนข้อความแปลกปลอมสั่งอะไรไม่ได้ตั้งแต่ต้น Simon Willison ผู้ตั้งชื่อ prompt injection เรียกมันว่าวิธีลดความเสี่ยงแรกที่น่าเชื่อถือที่เขาเห็นโดยไม่ต้องเพิ่ม AI อีกชั้น
ตรวจข้อเท็จจริงกับเปเปอร์ arXiv 2503.18813 ฉบับ v2, README ของโค้ดที่เผยแพร่ และบทความของ Simon Willison ณ ตุลาคม 2026 โค้ดในบทเป็นภาพประกอบแนวคิด ไม่ใช่โค้ดจากเปเปอร์
ทำไมต้องแก้ที่โครงสร้าง
พื้นฐานของ prompt injection และการป้องกันหลายชั้นอยู่ใน บทเรื่อง prompt injection แล้ว ประเด็นที่ CaMeL ตอบคือ ทำไมการป้องกันด้วยโมเดลอย่างเดียวไม่พอ
ตัวตรวจจับที่เป็น AI ทำงานแบบความน่าจะเป็น ในงานความปลอดภัย จับได้ 99% ถือว่าสอบตก เพราะผู้โจมตีลองได้ไม่จำกัดจนเจอ 1% ที่หลุด สิ่งที่ต้องการคือกฎที่ บังคับด้วยโค้ด ไม่ใช่กฎที่ขอให้โมเดลช่วยทำตาม
จุดเริ่ม: รูปแบบ Dual LLM และรูรั่วของมัน
ปี 2023 Simon Willison เสนอรูปแบบ Dual LLM
- P-LLM (privileged) มี tool ได้ เห็นแค่คำขอของผู้ใช้
- Q-LLM (quarantined) ไม่มี tool เป็นตัวอ่านข้อความที่ไม่น่าเชื่อถือ แล้วคืนผลเป็นตัวแปรอ้างอิง P-LLM ใช้ตัวแปรได้โดยไม่เห็นเนื้อหา
ตัวอย่างในเปเปอร์ทำให้เห็นรูรั่ว ผู้ใช้สั่งว่า “ส่งเอกสารที่ Bob ขอในประชุมครั้งล่าสุดให้เขาที” แผนคือ หาบันทึกประชุม → ดึงอีเมลของ Bob กับชื่อเอกสาร → หาเอกสาร → ส่ง ขั้นดึงอีเมลต้องให้ Q-LLM อ่านบันทึกประชุม ถ้ามีคนแอบใส่ข้อความในบันทึกให้เปลี่ยนอีเมลเป็นของผู้โจมตี Q-LLM ก็คืนอีเมลผิดมา แผนไม่ถูกแก้ แต่ข้อมูลที่ไหลในแผนถูกแก้ เอกสารก็ไปผิดคน
CaMeL ทำงานยังไง
CaMeL (CApabilities for MachinE Learning) เติมสองอย่างให้ Dual LLM
1. แผนเป็นโค้ด รันด้วย interpreter ของตัวเอง P-LLM แปลงคำขอเป็นโค้ดใน Python ชุดย่อย interpreter ที่สร้างบนโมดูล ast ของ Python เป็นคนรัน และจดว่าแต่ละค่ามาจากไหน
2. ทุกค่ามีป้าย capability บอกสองเรื่อง
- ที่มา (provenance): มาจากผู้ใช้ (ค่าที่อยู่ในโค้ดของ P-LLM), จาก CaMeL เอง (ผลการแปลงค่า) หรือจาก tool ไหน บางครั้งระบุละเอียดถึงผู้ส่งอีเมล
- ผู้อ่านที่อนุญาต (readers): สาธารณะ หรือรายชื่อผู้ใช้ tool ติดป้ายเองได้ เช่น tool cloud storage ติดรายชื่อผู้แก้ไขเอกสารให้
Q-LLM ไม่มี tool และต้องตอบตาม schema ที่กำหนด (ใช้ structured output ของผู้ให้บริการ) มีช่อง have_enough_information ไว้บอกว่าข้อมูลไม่พอ แต่บอก P-LLM ไม่ได้ว่าต้องการอะไรเพิ่ม เพราะช่องนั้นจะกลายเป็นทางให้ผู้โจมตีส่งคำสั่งได้
ภาพประกอบ (ไม่ใช่โค้ดจริงจากเปเปอร์):
# P-LLM wrote this from the user's request alone; it never saw the notes
notes = get_last_meeting_notes() # tagged: source = tool, untrusted
req = query_quarantined_llm( # Q-LLM: no tools, fixed output schema
"Find Bob's email and the document he asked for", notes,
schema=DocRequest) # {email: str, doc_name: str}
doc = find_document(req.doc_name) # tagged: readers = document editors
send_email(to=req.email, attachment=doc) # the policy runs before this call
# policy for send_email, enforced in code by the interpreter
def send_email_policy(to, attachment):
if to.source == "user": # address typed by the user
return ALLOW
if to.value in attachment.readers: # already allowed to read this doc
return ALLOW
return ASK_USER # otherwise a human decides
ถ้าบันทึกประชุมถูกฉีดอีเมลผู้โจมตี ค่า req.email มีป้ายว่ามาจากข้อมูลไม่น่าเชื่อถือ และผู้โจมตีไม่อยู่ในรายชื่อผู้อ่านเอกสาร การส่งจึงถูกกันไว้ให้คนตัดสิน ไม่ว่าโมเดลจะถูกหลอกแค่ไหน
กฎที่บังคับด้วยโค้ดไม่สนว่าโมเดลเชื่ออะไร มันดูแค่ว่าข้อมูลมาจากไหน และกำลังจะไปไหน
ผลบน AgentDojo
AgentDojo เป็น benchmark ความปลอดภัยของ agent ที่เรียก tool มี 4 ชุดงาน: Workspace, Banking, Travel, Slack
| ตัวชี้วัด | ไม่ป้องกัน | CaMeL |
|---|---|---|
| งานที่ทำสำเร็จ (ตามบทคัดย่อ) | 84% | 77% แบบรับประกันความปลอดภัย |
| การโจมตีที่สำเร็จ, Claude 3.5 Sonnet (ทั้งหมด 949 ครั้ง) | วิธีป้องกันที่ดีรองลงมา (tool filter) ยังโดน 8 | 0 |
| การโจมตีที่สำเร็จ, Gemini 2.5 Pro | 300 | 0 |
| token ต่องาน (ค่ามัธยฐาน) | 1 เท่า | input 2.82 เท่า, output 2.73 เท่า |
ยังมีการโจมตี 2 แบบที่ผ่านได้ (ในชุด Banking และ Travel) โดยแบบใน Travel ผู้วิจัยบอกว่าไม่ใช่ prompt injection จริง เป็นการที่โมเดลพิมพ์รีวิวที่มีข้อความฉีดไว้ออกมาให้ผู้ใช้เห็น ชุด Travel ได้คะแนนต่ำสุด เพราะโครงสร้างผลจาก tool อธิบายไว้ไม่ดี P-LLM จึงเขียนโค้ดอ่านผิด และดีขึ้นเองเมื่อโมเดลเก่งขึ้น: Claude Sonnet 3.5 ได้ 25%, 3.7 ได้ 55%, 4 ได้ 75% โดยไม่ได้แก้ CaMeL
ตัวอย่างคำนวณ: ยอมเสียอะไรไปบ้าง
- งานที่ทำได้ 77 ÷ 84 = 0.917 คือรักษางานที่ระบบไม่ป้องกันทำได้ไว้ประมาณ 92% เสียไปราว 8% ของงาน
- ค่า token สมมติงานหนึ่งใช้ input 10,000 token และ output 1,000 token ตามปกติ กับ CaMeL จะเป็น 10,000 × 2.82 = 28,200 และ 1,000 × 2.73 = 2,730 token ค่าใช้จ่ายต่องานเกือบสามเท่า
- ลดต้นทุนได้บ้าง เปเปอร์ลองใช้ Claude 3.5 Haiku เป็น Q-LLM คู่กับ Claude 4 Sonnet เป็น P-LLM คุณภาพลดราว 1% แต่ต้นทุนงานมัธยฐานลดราว 12%
สำหรับระบบที่ AI ส่งอีเมล โอนข้อมูล หรือแก้เอกสารแทนคน การจ่ายเกือบสามเท่าเพื่อให้การโจมตีที่สำเร็จเป็นศูนย์ในชุดทดสอบนี้ มักคุ้ม สำหรับแชตตอบคำถามที่ไม่มี tool อันตราย อาจไม่คุ้ม
ข้อจำกัดที่เปเปอร์บอกเอง
- ยังไม่ได้แก้ prompt injection หมด ผู้วิจัยเขียนไว้ตรง ๆ
- ต้องเขียนและดูแล policy เอง เป็นภาระของผู้ใช้หรือผู้ดูแลระบบ
- ความล้าจากการกดอนุมัติ ถามบ่อยเกินไปคนจะกดอนุมัติทุกอย่าง รวมถึงของอันตราย
- งานที่ต้องตัดสินจากข้อมูลข้างนอกทำไม่ได้ (“data requires action”) เช่น “ทำตามขั้นตอนที่เขียนในอีเมลนี้” P-LLM วางแผนจากข้อมูลที่มันไม่ได้อ่านไม่ได้
- side channel เช่นอนุมานข้อมูลทางอ้อม หรือรั่วทีละบิตผ่าน exception โหมด STRICT ลดได้บางส่วน
- นอกขอบเขต การโจมตีที่ไม่เปลี่ยนการไหลของข้อมูล เช่นทำให้สรุปบิดเบือน หรือหลอกผู้ใช้ให้กดลิงก์ฟิชชิง
ข้อผิดพลาดที่เจอบ่อยเมื่อเอาแนวคิดไปใช้
- ให้โมเดลที่อ่านข้อมูลข้างนอกเป็นคนเรียก tool เอง คือกลับไปมีรูเดิม แยกตัววางแผนกับตัวอ่านให้ขาด
- ให้ Q-LLM ตอบเป็นข้อความอิสระ แล้วเอาไปต่อเป็นคำสั่ง ต้องบังคับ schema และตรวจรูปแบบค่า เช่นอีเมลต้องเป็นอีเมล
- ตรวจ policy ใน prompt แทนในโค้ดที่ชั้น tool policy ที่โมเดลเป็นคนตัดสินถูกหลอกได้
- ถามผู้ใช้ทุกครั้ง จนกลายเป็นปุ่มที่กดผ่านโดยไม่อ่าน ถามเฉพาะเมื่อข้อมูลไม่น่าเชื่อถือกำลังจะไปที่ใหม่
- เอาโค้ดวิจัยไปขึ้น production ตรง ๆ README บอกเองว่าอาจมี bug และไม่มีการดูแลต่อ
แหล่งอ้างอิง
คำถามที่พบบ่อย
CaMeL ใช้ได้เลยไหม มีของสำเร็จรูปหรือเปล่า
ยังไม่ใช่ผลิตภัณฑ์ โค้ดที่เผยแพร่เป็นของสำหรับรันซ้ำผลงานวิจัย README บอกว่าไม่ใช่ผลิตภัณฑ์ของ Google อาจมี bug และไม่มีแผนดูแลต่อ สิ่งที่นำไปใช้ได้ทันทีคือหลักการออกแบบ
ต่างจากการใช้ AI อีกตัวตรวจจับ prompt injection ยังไง
ตัวตรวจจับเป็นความน่าจะเป็น จับได้ 99% ก็ยังแพ้ เพราะผู้โจมตีต้องการแค่ 1% ที่หลุด CaMeL บังคับด้วยโค้ด ข้อมูลที่ไม่น่าเชื่อถือไปเปลี่ยนแผนไม่ได้โดยโครงสร้าง และการส่งข้อมูลออกต้องผ่าน policy เสมอ
ถ้าทำเองแบบง่ายที่สุด เริ่มตรงไหน
เริ่มจากตรวจสิทธิ์ที่ชั้น tool ด้วยโค้ด เช่นส่งอีเมลได้เฉพาะผู้รับที่มาจากผู้ใช้หรืออยู่ใน allowlist และผูกป้ายที่มาให้ข้อมูลที่อ่านจากข้างนอก ไม่ต้องสร้าง interpreter ทั้งตัวก็ได้ประโยชน์ส่วนใหญ่
คำสั่งและค่าตั้งในบทความทดสอบบนระบบตัวอย่าง ลองบนเครื่องทดสอบก่อนใช้กับระบบจริงเสมอ