Tool: bash — คำสั่งค้น/ตรวจไฟล์แบบอ่านอย่างเดียว หลัง rag_search หาไม่เจอ

หลังจาก Tool: rag_search ค้นหาไฟล์แล้ว bash คือทางเลือกสำหรับตรวจหรือค้นต่อในระดับ shell แต่ไม่ได้เป็น shell ที่เปิดให้รันอะไรก็ได้ ระบบจำกัดให้ทำงานแบบอ่านอย่างเดียว
Tool นี้คืออะไร
Schema บอกไว้ตรงๆ ว่านี่คือ “read-only-oriented” bash command สำหรับ find, grep, ls, cat, wc ฯลฯ — ไม่ใช่ shell ทั่วไปที่รันอะไรก็ได้ คำสั่งทำลายล้าง (rm, sudo, disk-wiping) ถูกบล็อก และ path แบบ relative จะ resolve เข้าโฟลเดอร์ private ของ agent เอง (workspect) ไม่ใช่โปรเจกต์ผู้ใช้ — เพราะแบบนี้ system prompt จึงบังคับให้โมเดลใช้ absolute path เสมอเวลาต้องการตรวจไฟล์จริง
Agent เรียก tool นี้เมื่อไร
Docstring มี self-check ให้โมเดลถามตัวเองก่อนเรียกทุกครั้ง:
Call this first only when the user explicitly asks to use/run bash. Otherwise rag_search must have run earlier this turn and returned no relevant hit… SELF-CHECK: explicit bash request OR prior insufficient RAG result? If NO, call rag_search first. If YES, continue here.
พูดอีกแบบ: bash เป็นตัวสำรอง ไม่ใช่ตัวเลือกแรก — ใช้ตอนนับ/ลิสต์ไฟล์ตามเงื่อนไข (rag_search คืนแค่ snippet พิสูจน์ความครบถ้วนไม่ได้), ค้นทั้งเครื่องผ่าน Spotlight, หรือ grep เนื้อหาแบบเต็มเมื่อ rag_search หาไม่เจอ
Layer ที่ 1: Allow-list คำสั่งที่อนุญาต ไม่ใช่ deny-list
จุดออกแบบสำคัญที่สุด: ระบบใช้ allow-list เป็นนโยบายหลัก ไม่ใช่แค่ deny pattern — คำสั่งที่อนุญาตมีแค่: cat, date, df, du, echo, find, git, grep, head, hostname, id, ls, mdfind, pwd, rg, sort, sw_vers, tail, uname, uptime, wc, whoami — คำสั่งอื่นทั้งหมดถูกปฏิเสธโดยดีฟอลต์ ไม่ใช่แค่ blacklist คำอันตรายที่นึกออก
Deny pattern (เช่นตรวจจับ rm -rf, sudo, fork bomb, pipe-to-shell) ยังมีอยู่เป็นชั้นอธิบายเพิ่มเติมให้ error message ชัดเจนขึ้น แต่ตัว allow-list ต่างหากที่เป็นด่านจริง — มีบั๊กจริงที่เคยแก้: pattern เดิมตรวจจับ rm -rf แบบ -[a-z]*r[a-z]*f ต้องมี r ก่อน f ใน flag เดียวกัน ทำให้ rm -fr, rm -fR, rm -r -f (แยก flag), และ rm --recursive --force หลุดผ่านได้ทั้งหมด — แก้ด้วย lookahead ที่เช็คว่ามีทั้ง flag แบบ recursive และ force ปรากฏที่ไหนก็ได้ในคำสั่งเดียวกัน (ไม่ข้าม ;, &, |)
ห้าม shell syntax ที่อาจซ่อนคำสั่งอื่น เช่น redirect (>), chain (;, &&), substitution (`, $()) — บล็อกทั้งหมดตั้งแต่ต้น ไม่ใช่พยายามแยกแยะว่าอันไหนอันตรายอันไหนไม่
แต่ละคำสั่งมีกฎเฉพาะของตัวเอง
ไม่ใช่แค่ “อยู่ใน allow-list ก็รันได้เลย” — แต่ละคำสั่งมีเงื่อนไขเพิ่มเติม เช่น:
findห้ามมี-delete,-exec,-execdir(ป้องกันใช้ find เป็นช่องทางรันคำสั่ง/ลบไฟล์)rgห้าม--pre(รันโปรแกรมภายนอกได้)sortห้าม-o/--output/--compress-program(เขียนไฟล์หรือเรียกโปรแกรมได้)gitจำกัดเฉพาะ subcommand อ่านข้อมูล (branch,diff,grep,log,ls-files,rev-parse,show,status) และบล็อก option ที่เปลี่ยน metadata หรือรันโปรแกรมภายนอก (--ext-diff,--textconv)- ทุก path operand (สำหรับ
cat/find/grep/mdfindฯลฯ) ต้องผ่านการเช็ค sensitive-path ก่อนเสมอ
Layer ที่ 2: macOS sandbox-exec — ชั้น OS ที่เป็น backstop
แม้ allow-list ชั้น Python จะเข้มงวดแค่ไหน โค้ดก็มีโอกาสมีบั๊ก (อย่างที่เห็นในกรณี rm -rf ข้างบน) — ทุกคำสั่งจึงถูกรันผ่าน sandbox-exec ของ macOS ด้วยเสมอ เป็นชั้นระดับ kernel ที่ทำงานเป็นอิสระจากโค้ด Python:
(deny file-write*)
(deny file-read* (subpath ".ssh") (subpath ".aws") (subpath "Keychains") ...)
(deny network*)
หมายความว่าแม้ allow-list ชั้น Python พลาด sandbox ชั้น OS ก็ยังบล็อกการเขียนไฟล์และการเข้าถึง network ได้อยู่ดี — ปิด network ทั้งหมดด้วย เพราะ tool นี้ไม่มีเหตุผลต้องต่อเน็ตเลย
ผลลัพธ์ก็ยังถูกกรองก่อนส่งกลับ
แม้คำสั่งรันผ่านทุกด่านแล้ว ผลลัพธ์ (output) ก็ยังถูกสแกนก่อนส่งกลับให้โมเดล: ถ้าเจอ pattern คล้าย credential ในผลลัพธ์ทั้งก้อน จะบล็อกทันที และสำหรับ find/ls/grep/rg แต่ละบรรทัดที่เป็น path ที่ sensitive จะถูกกรองทิ้งก่อนแสดง (ไม่ใช่บล็อกทั้งผลลัพธ์เพราะมีบรรทัดเดียวที่มีปัญหา)
แก้ไขคำสั่งให้ถูกต้องอัตโนมัติก่อนรัน
มีชั้น normalize_command_for_query ที่แก้คำสั่งที่โมเดลสร้างมาไม่ตรงเจตนาผู้ใช้ ก่อนรันจริง เช่น:
- ผู้ใช้ถามหาไฟล์
.pdfแต่โมเดลลืมใส่ตัวกรองนามสกุลในfind→ เติมให้อัตโนมัติ - ผู้ใช้ถามหา “ทั้งเครื่อง” แต่โมเดลสร้าง
grepที่จำกัดแค่โปรเจกต์เดียว → เปลี่ยนเป็นmdfind(ค้นทั้งเครื่องผ่าน Spotlight) ให้แทน - ผู้ใช้ขอ “รายการ” (list) แต่โมเดลต่อ
| wc -l(นับจำนวน) ต่อท้าย → ตัดwcออก ไม่ให้ list กลายเป็นนับโดยไม่ตั้งใจ
ทั้งหมดนี้เป็นการแก้ปัญหาจริงที่สังเกตได้จากพฤติกรรมของโมเดล 2B ที่บางครั้งเข้าใจเจตนาผิดเล็กน้อย — แก้ด้วยโค้ดที่ตรวจสอบได้ แทนที่จะหวังให้โมเดลไม่พลาด
ทำไมเรื่องนี้ถึงสำคัญ
bash คือ tool ที่มีความเสี่ยงสูงสุดใน AGENT LITE เพราะเปิดทางให้ “รันคำสั่งจริง” ทีมพัฒนาจึงลงทุนออกแบบสามชั้นป้องกันอิสระต่อกัน: allow-list เข้มงวดระดับ Python, sandbox-exec ระดับ OS, และการกรองผลลัพธ์ก่อนแสดง — แม้ชั้นใดชั้นหนึ่งพลาด ชั้นอื่นยังทำงานปกป้องอยู่
ความคิดเห็น
กำลังโหลดความคิดเห็น...