Boom Field Lab

ทำไมต้องรัน AI Agent ใน Sandbox — ออกแบบ 'วงความเสียหาย' แบบที่ใช้จริงตอนสร้าง Terminal

คำถามไม่ใช่ 'agent จะพลาดไหม' แต่คือ 'ถ้าพลาด ความเสียหายกว้างแค่ไหน และกู้คืนเร็วแค่ไหน' นี่คือ 4 ชั้นที่ผมใช้กั้น AI agent ตอนสร้าง fintech product — กล่อง container, ด่านคำสั่งก่อนรัน, ข้อมูลอ่อนไหวที่ห้ามออกนอกเครื่อง และงานสาธารณะที่ต้องให้คนสั่งเท่านั้น

โดย วรัญชัย ยิ่งคำนึง (Boom) · เผยแพร่ครั้งแรก · ตรวจทานล่าสุด

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

เมื่อไม่กี่ปีก่อน AI ที่เราใช้คือแชตบอต ความเสียหายสูงสุดคือ "ตอบผิด" ซึ่งเราจับได้ตอนอ่าน แต่ agent อย่าง Claude Code รันคำสั่งบนเครื่อง แก้ไฟล์ ลบไฟล์ และเรียก API ได้เอง ในงานสาย model risk มีคำถามหนึ่งที่ติดตัวจนเป็นนิสัย: อย่าถามว่ามันจะพลาดไหม ให้ถามว่าถ้าพลาด ความเสียหายลามไปได้ไกลแค่ไหน และเรากู้กลับได้เร็วแค่ไหน

บันทึกนี้คือคำตอบที่ผมใช้จริงตอนสร้าง Boom Leverage Terminal ด้วย agent ที่บางส่วน รันเองตลอด 24 ชั่วโมง

Sandbox คืออะไร แบบสั้นที่สุด?

Sandbox คือสภาพแวดล้อมที่ถูกขังไว้ agent ทำงานข้างในได้เต็มที่ พังอะไรข้างในก็ได้ แต่แตะของจริงข้างนอกไม่ได้ สำหรับคนทำงานทั่วไป sandbox ที่คุ้มและทำซ้ำง่ายที่สุดคือ container (เช่น Docker)

หัวใจไม่ได้อยู่ที่เทคโนโลยี แต่อยู่ที่หลักคิด least privilege — agent เห็นเฉพาะโฟลเดอร์ที่ตั้งใจให้เห็น ใช้เฉพาะสิทธิ์ที่ตั้งใจให้ และถ้าลบ container ทิ้ง ทุกอย่างที่มันทำไว้ในกล่องก็หายไปด้วย

4 ชั้นที่ผมใช้กั้น agent ตอนสร้าง Terminal

แผนภาพ 4 ชั้นของวงความเสียหาย: กล่อง container เห็นเฉพาะโฟลเดอร์งาน, ด่านคำสั่ง hooks ดักก่อนรัน, ข้อมูลอ่อนไหวห้ามออกนอกเครื่อง และงานสาธารณะต้องให้คนสั่งเท่านั้น
ชั้นกั้นที่ใช้จริง · เรียงจากชั้นที่ทำงานบ่อยที่สุด (บน) ไปถึงชั้นที่ปกป้องชื่อเสียงของบริษัท (ล่าง)
ชั้นทำงานยังไงถ้าไม่มีจะเกิดอะไร
1. กล่อง (container)agent ที่รันเองอยู่ใน container ที่เห็นเฉพาะโฟลเดอร์โปรเจกต์ ไม่เห็น home ทั้งหมดคำสั่งพลาดครั้งเดียวลามถึงไฟล์ส่วนตัวและ credential อื่นในเครื่อง
2. ด่านคำสั่ง (hooks)สคริปต์ดักคำสั่งก่อนรัน — อ่านไฟล์ลับทั้งก้อน, ยิง HTTP ตรงจาก shell, แก้ไฟล์ที่ถูกแช่แข็ง = ถูกตัดทิ้งต้องพึ่งให้โมเดล "จำได้" ว่าห้ามทำ ซึ่งมันลืมได้เสมอ
3. ข้อมูลอ่อนไหวงานที่มีข้อมูลส่วนบุคคลต้องใช้โมเดลที่รันในเครื่องเท่านั้น ถ้าใช้ไม่ได้ = หยุดรอระบบ fallback อัตโนมัติส่งข้อมูลออก cloud เงียบๆ ตอนโมเดลหลักล่ม
4. งานสาธารณะเว็บและบทความต้องเกิดจากคนสั่งเท่านั้น ไม่ใช่ runner หรือ cronงานที่มีชื่อบริษัทอยู่บนนั้นหลุดออกไปโดยไม่มีคนรับผิดชอบ

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

ถ้า agent พลาดจริง ความเสียหายหยุดตรงไหน?

แผนภาพลำดับเมื่อ agent พลาด: คำสั่งผิด ถูก hook ดักก่อนรัน ถ้าหลุดก็อยู่แค่ในกล่อง ลบไฟล์กลายเป็นย้ายไปถังพัก และ container สร้างใหม่ได้ในคำสั่งเดียว
เส้นทางของความผิดพลาดหนึ่งครั้ง · ทุกขั้นถูกออกแบบให้ 'หยุดได้' หรือ 'กู้คืนได้' ไม่ใช่ 'ต้องไม่พลาด'

ความผิดพลาดไม่ใช่เรื่องทฤษฎี มันเกิดจากเหตุง่ายๆ: agent เข้าใจ path ผิด, สคริปต์ที่มันเขียนมีบั๊ก, หรือมันอ่านเจอไฟล์ที่มีคำสั่งฝังอยู่แล้วทำตาม (prompt injection) การออกแบบของผมจึงไม่ได้พยายามทำให้ agent ไม่พลาด แต่ทำให้ความผิดพลาดแต่ละครั้ง หยุดเร็วและกู้ได้:

  • ดักก่อนรัน — hook เห็นคำสั่งก่อน shell จะรัน ถ้าตรงรูปแบบอันตราย คำสั่งถูกตัดพร้อมบอกเหตุผลกลับไปให้ agent แก้เอง
  • ลบไม่ได้จริง — กฎคือห้ามลบไฟล์ถาวร ให้ย้ายไปถังพักที่มีวันที่กำกับแทน ลบพลาด = ย้ายกลับใน 10 วินาที
  • พังแค่ในกล่อง — ถ้าทุกอย่างข้างบนหลุด ความเสียหายก็อยู่แค่ในโฟลเดอร์ที่ mount ไว้
  • reset ถูก — container ถูกนิยามด้วยไฟล์ ลบแล้วสร้างใหม่ได้สภาพเดิมเป๊ะ

ทำไมการยิง HTTP ตรงจาก shell ถึงถูกบล็อก?

เพราะการเรียก API ภายนอกคือจุดที่ข้อมูลออกจากเครื่อง และคือจุดที่เงินถูกใช้ ผมจึงบังคับให้ทุกการเรียกภายนอกผ่านสคริปต์ wrapper ที่บันทึก log ได้ แทนการพิมพ์ curl สดๆ ข้อความที่ agent เห็นเมื่อลองฝ่าคือ:

การ์ดข้อความจริงจาก hook ที่บล็อกคำสั่ง curl ของ agent และบอกให้ใช้สคริปต์ wrapper แทน
ข้อความจริงจาก PreToolUse hook (ภาษาต้นฉบับ) · ผลคือทุกการเรียกภายนอกมี log ให้ตรวจย้อน

curl blocked — ใช้ python3 tools/*.py สำหรับ external API calls

และสำหรับข้อมูลอ่อนไหว กฎในไฟล์ CLAUDE.md เขียนไว้ชัดว่าการที่ระบบล่มไม่ใช่ข้ออ้างให้ส่งข้อมูลออก:

backend ล่มเป็นเหตุให้ รอ ไม่ใช่เหตุให้ส่งข้อมูลออกนอกเครื่อง

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

ถ้าอยากเริ่มเอง ต้องมีอะไรขั้นต่ำ?

sandbox ขั้นต่ำสำหรับ Claude Code ไม่ต้องซับซ้อน ตัวอย่างนี้เป็นโครงทั่วไป (ไม่ใช่ไฟล์ production ของผม) ที่ก็อปไปตั้งต้นได้:

FROM node:22-slim
RUN apt-get update \
 && apt-get install -y --no-install-recommends git ripgrep ca-certificates \
 && rm -rf /var/lib/apt/lists/*
RUN npm install -g @anthropic-ai/claude-code
RUN useradd -m agent
USER agent
WORKDIR /work
docker build -t claude-sandbox .
docker run --rm -it -v "$PWD":/work claude-sandbox claude
ส่วนกันอะไร
--rmออกแล้วลบตัวเอง ไม่มีของตกค้าง — ปุ่ม reset ในตัว
-v "$PWD":/workagent เห็นเฉพาะโฟลเดอร์ปัจจุบัน ไม่เห็นไฟล์อื่นในเครื่อง
USER agentต่อให้ในกล่องพลาด ก็ไม่ได้เป็น root
ส่ง key ผ่านตัวแปรชั่วคราวตอนรันไม่ฝัง key ในอิมเมจ ไม่ mount โฟลเดอร์ความลับเข้าไป

จะเข้มขึ้นอีกก็ได้ตามงาน เช่น ปิดเน็ตทั้งกล่อง (--network none) ตอนงานไม่ต้องออนไลน์ หรือจำกัด RAM/CPU กันสคริปต์หลุดกินเครื่อง หลักเดิมทุกข้อ: เปิดเท่าที่งานต้องใช้ ปิดที่เหลือไว้ก่อน

เมื่อไหร่ที่ยังไม่ต้องลงทุนกับ sandbox?

ถ้าใช้ AI แค่ช่วยอ่านโค้ดหรือตอบคำถาม โดย ไม่เปิดให้มันรันคำสั่งหรือแก้ไฟล์เอง ความเสี่ยงยังต่ำ แต่ทันทีที่เปิดโหมดให้มันลงมือเอง — โดยเฉพาะแบบข้าม permission prompt หรือรันข้ามคืน — sandbox ไม่ใช่ของเสริมแล้ว มันคือเงื่อนไขขั้นต่ำ

สรุป

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

BOOM FIELD LAB

อยากเห็นว่าเครื่องมือพวกนี้ประกอบร่างเป็น Terminal จริงได้ยังไง?

Workshop 60 นาที — ดูการทำงานจริงบนหน้าจอ พร้อม workbook ให้ลงมือตาม ไม่ใช่สไลด์ทฤษฎี