วิธีใช้ Claude Code hooks กับโปรเจกต์ Laravel

guideline เป็นแค่คำแนะนำ เรื่องที่พลาดแล้วเสียหายจึงต้องกันด้วยเครื่องมือ ผมตั้งรั้วไว้สี่ชั้น test ที่เร็วพอให้ agent รันเองทุกครั้ง hook ที่จัดโค้ดและกันคำสั่งอันตราย CI ที่ต้องผ่านก่อน deploy และสิทธิ์ที่ให้ agent อ่าน production ได้อย่างเดียว

เผยแพร่
เวลาอ่าน
4 นาที
แท็ก
#AI#CI/CD#Laravel
ในโพสต์นี้ 6 หัวข้อ
  1. test ต้องเร็วพอให้ agent รันเองทุกครั้ง
  2. hook จัดโค้ดให้ทุกครั้งที่ agent จบงาน
  3. hook ปฏิเสธคำสั่งที่พังทั้งเครื่อง
  4. CI เป็นด่านสุดท้ายก่อน deploy
  5. agent อ่าน production ได้ แต่เขียนเองไม่ได้
  6. รั้วแทนการอ่านทุกบรรทัด

ใน CLAUDE.md ของเว็บนี้ ผมเขียนไว้ว่าห้ามใช้ migrate:fresh agent ทำตามเกือบทุกครั้ง แต่คำว่าเกือบก็พอให้ฐานข้อมูลหายได้ guideline จึงเป็นแค่คำแนะนำ ส่วนเรื่องที่พลาดแล้วเสียหายต้องกันไว้ด้วยสิ่งที่ไม่ต้องพึ่งความจำของ agent

ผมแบ่งรั้วเป็นสี่ชั้น เรียงจากใกล้ตัว agent ที่สุดไปถึง production

ชั้น กันอะไร ทำงานเมื่อไหร่
test โค้ดที่ทำงานผิด ฐานข้อมูลที่โดนล้าง agent รันเองระหว่างทำงาน
hook โค้ดที่ไม่เป็นระเบียบ คำสั่งที่อันตราย ก่อนรันคำสั่ง และทุกครั้งที่ agent จบงาน
CI ทุกอย่างที่หลุดจากสองชั้นแรก ทุก push ก่อน deploy
สิทธิ์ การเขียนข้อมูลบน production, secret ตลอดเวลา

test ต้องเร็วพอให้ agent รันเองทุกครั้ง

agent จะรัน test บ่อยแค่ไหนขึ้นกับว่า test ใช้เวลานานเท่าไหร่ ถ้ารันทีละหลายนาที agent ก็รันน้อยลง หรือรันแค่บางไฟล์แล้วบอกว่าผ่าน

ผมจัดฐานข้อมูลสำหรับ test ด้วย snapshot ที่ commit ไว้ และ DatabaseTransactions แทนการรัน migration ใหม่ทุกครั้ง แล้วรัน test แบบขนาน ส่วนผลของ test ที่ยาว Laravel PAO ย่อให้ agent อ่านได้โดยไม่เปลือง context

โปรเจกต์ของผมสั่ง DB::prohibitDestructiveCommands() ไว้ทุก environment ตามค่าที่ตั้งตั้งแต่วันแรก คำสั่งอย่าง migrate:fresh จะแค่เตือนแล้วจบโดยไม่แตะฐานข้อมูล ถึง agent จะลืมกฎก็ล้างฐานข้อมูลไม่ได้

hook จัดโค้ดให้ทุกครั้งที่ agent จบงาน

hook ของ Claude Code คือคำสั่งที่เราตั้งให้รันเองตามจังหวะ เช่น ก่อน agent รันคำสั่ง หรือตอน agent จบงานแต่ละรอบ ผมตั้งไว้สามตัว

{
  "hooks": {
    "Stop": [{ "hooks": [{ "type": "command", "command": "~/.claude/hooks/laravel-quality.sh" }] }],
    "PreToolUse": [{ "matcher": "Bash", "hooks": [{ "type": "command", "command": "python3 ~/.claude/hooks/block-broad-kill.py" }] }],
    "UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "~/.claude/hooks/session-status-reminder.sh" }] }]
  }
}

ตัวที่ช่วยมากที่สุดคือ hook ตอนจบงาน ทุกครั้งที่ agent แก้ไฟล์เสร็จหนึ่งรอบ hook จะรัน Rector แล้ว Pint กับไฟล์ PHP และ ESLint แล้ว Prettier กับไฟล์ JS เฉพาะไฟล์ที่ session นั้นแก้ และเฉพาะโปรเจกต์ที่มีไฟล์ตั้งค่าของเครื่องมือนั้น เรื่องสไตล์ที่เคยต้องเขียนเป็นกฎยาว ๆ ก็มาอยู่ตรงนี้แทน รายละเอียดของเครื่องมือแต่ละตัวอยู่ในโพสต์เรื่อง lint, formatter และ static analysis

hook ปฏิเสธคำสั่งที่พังทั้งเครื่อง

hook ก่อนรันคำสั่งผมตั้งขึ้นหลังเหตุการณ์หนึ่งในเดือนตุลาคม 2569 agent จะหยุด process ที่ค้างอยู่ตัวเดียว แต่สั่ง pkill -f ด้วยคำค้นสั้น ๆ คำว่า cat บน macOS -f จับคำนี้ในทุก path ที่มีคำว่า Application, Location หรือ Notification ผลคือแอปราว 80 ตัวปิดพร้อมกัน ทั้งเบราว์เซอร์ LINE และตัวแอป Claude เอง ผมเห็นเหมือน Mac ปิดตัวเอง

เรื่องนี้เกิดสองครั้ง ตอนนี้ hook ปฏิเสธ pkill, killall และ kill แบบกว้างทุกตัวในทุกโปรเจกต์ agent ต้องหา PID ที่แน่นอนแล้วสั่ง kill ทีละตัว

Matt Pocock มี skill ที่ตั้ง hook แบบเดียวกันกับคำสั่ง git ที่ย้อนไม่ได้ อย่าง git push --force, git reset --hard หรือ git clean ถ้าเพิ่งเริ่มตั้ง hook กันคำสั่งอันตราย ชุดนี้เป็นจุดเริ่มที่ดี

CI เป็นด่านสุดท้ายก่อน deploy

ทุก push ต้องผ่าน GitHub Actions ก่อน deploy ใน CI มี test ทั้งชุด Pint, Rector, ESLint และ Prettier เฉพาะไฟล์ที่เปลี่ยน PHPStan ทั้งโปรเจกต์ และ gitleaks ที่หา secret ที่หลุดเข้า commit

ทั้งผมและ agent ไม่ deploy จากเครื่องตัวเอง ทางเดียวที่โค้ดขึ้น production ได้คือผ่าน CI ถ้า agent พลาดอะไรที่ hook และ test ในเครื่องไม่จับ CI จะจับได้อีกรอบ และ agent ที่ push ต้องเฝ้า CI จนผ่าน ไม่ใช่ push แล้วจบ

Superpowers มี skill ชื่อ verification-before-completion ที่ห้าม agent บอกว่างานเสร็จหรือ test ผ่าน ถ้ายังไม่ได้รันคำสั่งตรวจในรอบนั้นจริง ๆ ปัญหาเดียวกับที่ CI ของผมกันไว้ คือ agent ที่บอกว่าผ่านทั้งที่ยังไม่ได้รัน

agent อ่าน production ได้ แต่เขียนเองไม่ได้

agent ช่วยไล่ปัญหาบน production ได้ดีมาก ถ้าเห็นข้อมูลจริง แต่ผมไม่อยากให้ agent มีสิทธิ์เขียน

  • ฐานข้อมูล production agent ต่อผ่าน SSH tunnel ด้วย user ที่อ่านได้อย่างเดียว เล่าไว้ในวิธีให้ AI อ่านฐานข้อมูล production อย่างปลอดภัย
  • คำสั่งบนเซิร์ฟเวอร์ อ่าน log และดูไฟล์ได้เอง แต่การเขียนหรือรัน artisan ที่เปลี่ยนข้อมูล ต้องถามผมในแชทก่อนทุกครั้ง
  • secret อย่าง API key ไม่ผ่านแชทเลย ผมพิมพ์ใน terminal ที่ซ่อนข้อความ ค่าเก็บใน Keychain ของ macOS แล้วส่งเข้าคำสั่งเป็น environment variable agent ใช้ได้โดยไม่เห็นค่า ส่วน .env ของ production เข้ารหัสเก็บไว้ใน git

รั้วแทนการอ่านทุกบรรทัด

Jason McCreary เล่าไว้ในสี่ขั้นที่เขาปล่อยงานให้ AI agentว่าสิ่งที่ทำให้เขาเลิกรีวิวโค้ดได้ คือรั้วที่ตั้งไว้ตั้งแต่ก่อนมี AI ของผมก็คล้ายกัน ส่วนที่ต่างคือรั้วหลายตัวของผมเกิดขึ้นหลังมี AI เพราะ agent ทำบางอย่างที่คนไม่ค่อยทำ อย่างสั่ง pkill แบบกว้าง หรือบอกว่า test ผ่านทั้งที่รันไม่ครบ

ถ้าจะเริ่มตั้งรั้วเอง ผมว่าเริ่มจากเรื่องที่พลาดแล้วย้อนไม่ได้ก่อน คือฐานข้อมูล การ deploy และ secret แล้วค่อยเพิ่มตัวอื่นทุกครั้งที่ agent ทำอะไรที่ไม่อยากให้เกิดซ้ำ

อ่านต่อ

ล่าสุด

ดูทั้งหมด →