
Claude Code Hooks: คู่มือฉบับพาวเวอร์ยูสเซอร์สำหรับทำให้เอเจนต์ของคุณทำงานอัตโนมัติ
Claude Code hooks รันคำสั่งของคุณโดยอัตโนมัติตามเหตุการณ์ในไลฟ์ไซเคิล — ตรวจสอบ, lint, บล็อก หรือบันทึกล็อกได้โดยไม่ต้องคอยเฝ้า มาดูอีเวนต์ต่าง ๆ, การตั้งค่า, สูตรสำเร็จ 5 แบบ, จุดพลาดเรื่อง exit-code และวิธีรัน Claude Code แบบไม่ต้องตั้งค่าอะไรเลย
Claude Code hooks คือคำสั่งที่ผู้ใช้กำหนดขึ้นเอง ซึ่งจะรันโดยอัตโนมัติในจุดเฉพาะของวงจรชีวิต (lifecycle) ของ Claude Code — ก่อนการเรียกใช้ tool, หลังการแก้ไข, เมื่อเริ่มเซสชัน, เมื่อ Claude จบเทิร์น — เพื่อให้คุณสามารถตรวจสอบ จัดรูปแบบ บันทึกล็อก หรือบล็อกการทำงานได้โดยไม่ต้องคอยควบคุมทุกครั้ง นี่คือความแตกต่างระหว่าง AI coding agent ที่ แนะนำ กับตัวที่ทำตาม กฎของคุณ อย่างแน่นอน (deterministically) คู่มือนี้จะอธิบายว่า hooks คืออะไร ทุกอีเวนต์ที่มันสามารถทำงานได้ วิธีตั้งค่า สูตรตัวอย่างที่ใช้งานได้จริง 5 แบบที่คุณสามารถนำไปใช้ได้เลย จุดที่มักทำให้พลาดเกี่ยวกับ exit code และวิธีใช้พลังเต็มรูปแบบของ Claude Code โดยไม่ต้องตั้งค่าอะไรในเครื่องของคุณ
Claude Code Hooks คืออะไร?
Hook คือ handler — อาจเป็นคำสั่ง shell, HTTP endpoint, การเรียกใช้ MCP tool หรือแม้แต่ model prompt — ที่ Claude Code จะรันโดยอัตโนมัติเมื่อเกิดอีเวนต์เฉพาะขึ้น handler จะได้รับข้อมูลนำเข้าที่มีโครงสร้าง (ผ่าน stdin สำหรับ command hooks หรือเป็น POST body สำหรับ HTTP hooks) สามารถตรวจสอบสิ่งที่กำลังเกิดขึ้น ดำเนินการ และเลือกที่จะส่งคืนคำตัดสินที่เปลี่ยนแปลงสิ่งที่ Claude จะทำต่อไปได้
ส่วนสุดท้ายนี้คือสิ่งที่ทำให้ hooks มีพลังมากกว่าแค่ความสะดวก hook ไม่ได้เป็นแค่การแจ้งเตือน — มันสามารถ บล็อก การเรียกใช้ tool, เขียนใหม่ ข้อมูลนำเข้าหรือผลลัพธ์ของ tool, แทรกบริบทเพิ่มเติม หรือหยุด Claude ได้ทั้งหมด กล่าวอีกนัยหนึ่ง hooks เปลี่ยน Claude Code จากผู้ช่วยที่ฉลาดให้กลายเป็นผู้ช่วยที่ สามารถโปรแกรมได้ ซึ่งบังคับใช้แนวป้องกันของทีมคุณอย่างแน่นอน ไม่ใช่แค่เมื่อโมเดลจำได้เป็นบางครั้ง
Hooks ทำงานเมื่อไหร่: วงจรชีวิต (Lifecycle)
Hooks ผูกติดกับอีเวนต์ต่างๆ และ Claude Code เปิดให้ใช้อีเวนต์เหล่านี้จำนวนมาก แบ่งกลุ่มตามความถี่: บางตัวทำงานครั้งเดียวต่อเซสชัน บางตัวครั้งเดียวต่อเทิร์น และบางตัวทำงานทุกครั้งที่มีการเรียกใช้ tool
ตำแหน่งที่ hooks ทำงานในระหว่างเซสชันของ Claude Code — จาก SessionStart ถึง SessionEnd
อีเวนต์ที่คุณจะใช้บ่อยที่สุด:
SessionStart/SessionEnd— ครั้งเดียวเมื่อเซสชันเริ่มต้นหรือสิ้นสุด เหมาะสำหรับการโหลดบริบท (issue ที่เปิดอยู่, ข้อมูล branch, environment variables) หรือการทำความสะอาดUserPromptSubmit— ทำงานเมื่อคุณส่ง prompt ก่อนที่ Claude จะประมวลผลมัน คุณสามารถกรองหรือเพิ่มเติม prompt ได้PreToolUse— ก่อนการเรียกใช้ tool ใดๆ นี่คือจุดที่คุณ บล็อก การกระทำที่เป็นอันตรายPostToolUse(และPostToolUseFailure) — หลังจากการเรียกใช้ tool สำเร็จ (หรือล้มเหลว) เป็นจุดสำหรับการ lint, การจัดรูปแบบ, และการตรวจสอบStop/StopFailure— เมื่อ Claude ตอบกลับเสร็จสิ้น หรือเทิร์นจบลงด้วยข้อผิดพลาดNotification— เมื่อ Claude Code ส่งการแจ้งเตือน (มีประโยชน์สำหรับการแจ้งเตือนบนเดสก์ท็อป)
นอกเหนือจากนี้ Claude Code ยังทำงาน hooks สำหรับ subagents (SubagentStart/SubagentStop), tasks (TaskCreated/TaskCompleted), การบีบอัดบริบท (PreCompact/PostCompact), การเปลี่ยน working directory (CwdChanged), การเปลี่ยนแปลงไฟล์บนดิสก์ (FileChanged), การโหลดคำสั่ง (InstructionsLoaded), และอื่นๆ อีกมากมาย ความหลากหลายนี้คือประเด็นสำคัญ: แทบทุกช่วงเวลาในลูปของ agent เป็นจุดที่คุณสามารถผูกนโยบายเข้าไปได้
ห้าประเภทของ Hook Handler
อีเวนต์ hook หนึ่งตัวสามารถทำให้เกิด handler ได้ 5 ประเภทที่แตกต่างกัน ซึ่งนี่คือสิ่งที่ทำให้ระบบมีความยืดหยุ่น:
command— รันคำสั่ง shell; อ่านข้อมูลนำเข้าผ่าน stdin ส่งสัญญาณคำตัดสินผ่าน exit code และ stdouthttp— POST ข้อมูล JSON ของอีเวนต์ไปยัง URL และอ่านการตอบกลับเป็น JSONmcp_tool— เรียกใช้ tool บน MCP server ที่เชื่อมต่ออยู่prompt— การประเมินโดยโมเดลแบบเทิร์นเดียวที่ส่งคืนคำตัดสิน JSON ว่าใช่หรือไม่ใช่ (มีประโยชน์สำหรับการตรวจสอบที่ไม่ชัดเจน)agent— สร้าง subagent (ยังอยู่ในขั้นทดลอง)
สำหรับทีมส่วนใหญ่ command hooks ทำงานได้ 90% ของงานทั้งหมด — สคริปต์ shell ก็เพียงพอสำหรับการ lint, บล็อก, หรือบันทึกล็อก
วิธีตั้งค่า Hook
Hooks อยู่ในไฟล์ settings (เอกสารทางการของ Claude Code hooks คือแหล่งอ้างอิงหลัก) และตำแหน่งที่คุณวางไฟล์นี้จะเป็นตัวกำหนดขอบเขตของมัน:
| ตำแหน่ง | ขอบเขต |
|---|---|
~/.claude/settings.json | ทุกโปรเจกต์ของคุณ |
.claude/settings.json | หนึ่งโปรเจกต์ (สามารถ commit ได้ — แชร์กับทีมของคุณได้) |
.claude/settings.local.json | หนึ่งโปรเจกต์ เฉพาะในเครื่อง (gitignore) |
| Managed policy settings | ทั่วทั้งองค์กร (ผู้ดูแลระบบ) |
โครงสร้างซ้อนกันสามระดับ: เลือก event, เพิ่มกลุ่ม matcher, จากนั้นกำหนด handlers Matchers จะตัดสินว่า hook ใช้กับการเรียกใช้ tool ตัวใด — "*" (หรือไม่ระบุ) จะจับคู่กับทุกอย่าง, Edit|Write แบบง่ายๆ จะจับคู่กับ tool เหล่านั้นตรงตัว, และอะไรที่ซับซ้อนกว่านั้นจะถูกถือว่าเป็น regular expression (MCP tools จับคู่กับรูปแบบ mcp__<server>__<tool>)
นี่คือตัวอย่าง PostToolUse hook ที่รันการตรวจสอบ lint หลังจากการแก้ไขทุกครั้ง:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [{ "type": "command", "command": "/path/to/lint-check.sh" }]
}
]
}
}ห้าสูตร Hook ที่ใช้งานได้จริง
นี่คือรูปแบบที่ทีมมักหยิบมาใช้เป็นอันดับแรก:
- Lint หรือ format หลังการแก้ไขทุกครั้ง hook
PostToolUseที่จับคู่กับEdit|Writeซึ่งรัน formatter หรือ linter ของคุณ เพื่อให้โค้ดของ agent ตรงตามกฎสไตล์ของคุณเสมอ - บล็อกคำสั่งที่เป็นอันตราย hook
PreToolUseที่จับคู่กับBashซึ่งตรวจสอบคำสั่งและบล็อกrm -rfและคำสั่งประเภทเดียวกันก่อนที่มันจะถูกรัน - การแจ้งเตือนบนเดสก์ท็อป hook
Notificationที่ส่งข้อความแจ้งเตือนคุณเมื่อ Claude ต้องการความสนใจหรือทำงานที่ใช้เวลานานเสร็จสิ้น - การบันทึกล็อกเพื่อการตรวจสอบ hook
PostToolUse(หรือมุ่งเป้าไปที่ MCP) ที่บันทึกทุกการเรียกใช้ tool เพื่อการปฏิบัติตามข้อกำหนด — สิ่งที่รัน เมื่อไหร่ และด้วยอาร์กิวเมนต์อะไร - โหลดบริบทของโปรเจกต์ตอนเริ่มต้น hook
SessionStartที่ดึงข้อมูล issue ที่เปิดอยู่, branch ปัจจุบัน, หรือ environment variables เพื่อให้ agent เริ่มต้นแต่ละเซสชันด้วยความเข้าใจบริบทอยู่แล้ว
ห้าสูตร hook ที่พบบ่อย และอีเวนต์ที่มันผูกติดอยู่
จุดที่มักทำให้พลาดเกี่ยวกับ Exit Code
นี่คือรายละเอียดที่ทำให้ทุกคนพลาด จึงควรจำให้ขึ้นใจ: สำหรับ command hooks มีเพียง exit code 2 เท่านั้นที่บล็อก Exit 0 หมายถึงสำเร็จ (และ stdout จะถูกแปลงเพื่อหาคำตัดสิน JSON ใดๆ) Exit 2 คือข้อผิดพลาดแบบ บล็อก — stderr ของมันจะถูกส่งกลับไปให้ Claude โค้ดอื่นใดก็ตาม รวมถึง exit 1 คือข้อผิดพลาดแบบไม่บล็อก — Claude จะดำเนินการต่อไป
ดังนั้นหากคุณเขียน hook "บล็อกสิ่งนี้" และใช้ exit 1 มันจะ ไม่ บล็อก — การกระทำจะดำเนินต่อไป เพื่อบังคับใช้นโยบายอย่างแท้จริงจาก command hook ต้อง exit 2 (Command hooks ยังสามารถส่งคืนการควบคุมที่ละเอียดกว่าเป็น JSON ผ่าน stdout ได้ — permissionDecision: "deny" สำหรับ PreToolUse, updatedInput เพื่อเขียนอาร์กิวเมนต์ใหม่, additionalContext เพื่อแทรกข้อมูล และ continue: false เพื่อหยุด Claude ทั้งหมด)
ตัวอย่างการทำงาน: การบล็อก rm -rf
มาสร้างระบบป้องกันคำสั่งที่เป็นอันตรายแบบครบวงจรกัน เพราะมันแสดงให้เห็นทุกส่วนที่เกี่ยวข้อง ก่อนอื่นคือการตั้งค่า — hook PreToolUse ที่จับคู่กับ Bash:
{ "hooks": { "PreToolUse": [{ "matcher": "Bash",
"hooks": [{ "type": "command", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/guard.sh" }] }] } }จากนั้นคือสคริปต์ guard.sh Claude Code จะส่งอีเวนต์เป็น JSON ผ่าน stdin ซึ่งรวมถึงข้อมูลนำเข้าของ tool; สคริปต์จะอ่านมัน ตรวจสอบคำสั่ง และตัดสินใจ:
#!/usr/bin/env bash
input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command // ""')
if echo "$cmd" | grep -Eq 'rm +-rf|mkfs'; then
echo "Blocked: destructive command refused by policy." >&2
exit 2 # exit 2 blocks — exit 1 would NOT
fi
exit 0บรรทัดที่ตัดสินใจคือ exit 2 ส่งคืน 0 แล้วคำสั่งจะรัน; ส่งคืน 1 แล้ว — อย่างขัดต่อสัญชาตญาณ — มัน ยัง รันเป็นข้อผิดพลาดแบบไม่บล็อก; มีเพียง exit 2 เท่านั้นที่บล็อกและส่งข้อความ stderr ของคุณกลับไปให้ Claude เพื่อให้มันเข้าใจสาเหตุ ทำให้สคริปต์รันได้ (executable), commit มันไว้ใต้ .claude/hooks/ แล้วทุกการเรียกใช้ Bash จะผ่านการป้องกันของคุณ — สำหรับทั้งทีมของคุณ เนื่องจาก settings.json ของโปรเจกต์สามารถแชร์ได้ สำหรับการรับประกันที่แน่นอนแทนที่จะเป็นความพยายามที่ดีที่สุด ให้จับคู่มันกับกฎการอนุญาตของ Claude Code; ในฐานะระบบป้องกันความปลอดภัยที่แน่นอนและควบคุมด้วยเวอร์ชัน hook นี้ก็ทำหน้าที่ของมันได้ดีแล้ว
เมื่อ Hooks ไม่ใช่คำตอบ
Hooks เหมาะสำหรับนโยบายที่แน่นอนและทำซ้ำได้ — "lint เสมอหลังการแก้ไข", "ไม่รัน rm -rf เด็ดขาด" มันเป็นเครื่องมือที่ผิดสำหรับสิ่งที่ต้องใช้การตัดสินใจ (ใช้โมเดลหรือ prompt hook สำหรับการตัดสินใจที่ไม่ชัดเจน) และสำหรับการรับประกันความปลอดภัยที่แน่นอน (ใช้ระบบการอนุญาต เนื่องจากตัวกรอง if ของ command-hook จะล้มเหลวแบบเปิด) อย่าใช้ hook มากเกินไปด้วย: ทุก command hook รันโปรเซสที่มี timeout และกลุ่ม hooks ที่ทำงานช้าจำนวนมากจะเพิ่ม latency ให้กับทุกการเรียกใช้ tool ให้มันเร็ว น้อย และมุ่งเน้นไปที่กฎที่สำคัญจริงๆ
บันทึกด้านความปลอดภัยที่ควรรู้
ข้อเท็จจริงบางอย่างที่เอกสารระบุอย่างชัดเจน:
- ตัวกรอง
ifล้มเหลวแบบเปิด หากคุณใช้ฟิลด์ifเพื่อกำหนดขอบเขตของ hook ให้กับกฎการอนุญาต และคำสั่งนั้นไม่สามารถแปลงได้ hook จะรันต่อไปอยู่ดี สำหรับการบังคับใช้การอนุญาต/ปฏิเสธอย่างแน่นอน ให้ใช้ระบบการอนุญาตของ Claude Code ไม่ใช่ hooks - Hooks รันโดยไม่มี controlling terminal — มันไม่สามารถแสดง prompt บน
/dev/ttyได้ ใช้systemMessageหรือผลลัพธ์terminalSequenceที่มีข้อจำกัดสำหรับข้อความที่แสดงต่อผู้ใช้ - Stdout ต้องสะอาด มีเพียง JSON decision object เท่านั้นที่ควรอยู่บน stdout; ผลลัพธ์ที่หลุดออกมาจาก shell profile อาจทำให้การแปลงข้อมูลผิดพลาด
- จัดการกับบริบทที่แทรกเข้ามาอย่างระมัดระวัง
additionalContextควรเขียนเป็นข้อความเชิงข้อเท็จจริง ไม่ใช่คำสั่งเชิงบังคับ เพื่อให้เข้ากันได้ดีกับระบบป้องกัน prompt-injection
Hooks คือ Harness Engineering แบบย่อส่วน
ถอยกลับมามองภาพรวม hooks เป็นตัวอย่างที่ชัดเจนของแนวคิดที่ใหญ่กว่า: โมเดลไม่ใช่ agent ทั้งหมด — ระบบที่อยู่รอบๆ มันคือส่วนสำคัญ Hooks เป็นส่วนหนึ่งของ harness ที่ทำให้ coding agent น่าเชื่อถือ อยู่เคียงข้างกับ loop, tools, memory, และ sandbox (เราลงรายละเอียดเกี่ยวกับโมเดลความคิดนี้ใน harness engineering) เมื่อคุณเขียน PreToolUse block หรือ PostToolUse linter คุณกำลังทำ harness engineering — กำหนดพฤติกรรมของ agent อย่างแน่นอน แทนที่จะหวังว่าโมเดลจะทำตัวดี
กรอบความคิดนี้ยังบอกคุณด้วยว่าเมื่อไหร่ hooks จึงคุ้มค่าที่จะลงทุนเวลา: กฎใดๆ ที่คุณต้องคอยเตือน agent ทุกครั้งคือตัวเลือกที่เหมาะสมสำหรับ hook
ใช้พลังเต็มรูปแบบของ Claude Code โดยไม่ต้องตั้งค่าในเครื่อง
Hooks อยู่ใน Claude Code CLI ซึ่งหมายความว่าคุณต้องติดตั้งและตั้งค่ามันเพื่อใช้งาน — เป็นกำแพงสำหรับคนที่ไม่ได้ตั้งค่าใน terminal และเป็นไปไม่ได้เลยสำหรับเพื่อนร่วมทีมที่ไม่ใช่นักพัฒนา หากคุณต้องการความสามารถของ agent ของ Claude Code โดยไม่ต้องจัดการการติดตั้งในเครื่อง คุณสามารถรัน Claude Code ในเบราว์เซอร์ของคุณบน Happycapy: มันจะรัน Claude Code ใน managed cloud sandbox ที่ harness — loop, tools, memory, และการแยกส่วนที่ hooks เชื่อมต่อเข้าไป — ถูกเชื่อมต่อให้พร้อมใช้งานแล้วสำหรับคุณ คุณอธิบายงาน แล้วเฝ้าดู agent ทำงานบนเดสก์ท็อปแบบมองเห็นได้ ไม่ต้องใช้ terminal เลย
ลองคิดแบบนี้: hooks ให้ผู้ใช้ระดับสูงปรับแต่ง harness ของ Claude Code ด้วยมือ; Happycapy ให้ managed harness แก่ทุกคนพร้อมใช้งานตั้งแต่แรก หากคุณอยากใช้ Claude Code ทำงานแต่การตั้งค่า CLI เป็นสิ่งที่หยุดคุณไว้ เริ่มใช้งานฟรีที่ happycapy.ai และรันงานจริงในเบราว์เซอร์ของคุณวันนี้
คำถามที่พบบ่อย
คำถาม: Claude Code hooks คืออะไร?
พวกมันคือ handler ที่ผู้ใช้กำหนดขึ้น — คำสั่ง shell, HTTP endpoint, การเรียกใช้ MCP tool, หรือ model prompt — ที่ Claude Code รันโดยอัตโนมัติในเหตุการณ์ต่างๆ ของ lifecycle เช่น ก่อนการเรียกใช้ tool (PreToolUse), หลังการแก้ไข (PostToolUse), หรือตอนเริ่มเซสชัน พวกมันสามารถตรวจสอบ, จัดรูปแบบ, บันทึกล็อก, บล็อก, หรือเขียนใหม่การกระทำต่างๆ ได้
คำถาม: Claude Code รองรับอีเวนต์ hook อะไรบ้าง?
มีมากมาย — รวมถึง SessionStart/SessionEnd, UserPromptSubmit, PreToolUse, PostToolUse (และ PostToolUseFailure), Stop/StopFailure, Notification, อีเวนต์ subagent และ task, และอีเวนต์การบีบอัด พวกมันทำงานครั้งเดียวต่อเซสชัน ครั้งเดียวต่อเทิร์น หรือทุกครั้งที่มีการเรียกใช้ tool
คำถาม: ผมจะทำให้ hook บล็อกการเรียกใช้ tool ได้อย่างไร?
สำหรับ command hooks ให้ออกด้วยโค้ด 2 — มีเพียง exit 2 เท่านั้นที่บล็อก (exit 1 ไม่บล็อก) สำหรับ PreToolUse คุณยังสามารถส่งคืน JSON ที่มี permissionDecision: "deny" ได้ สำหรับการบังคับใช้อย่างแน่นอน ให้เลือกใช้ระบบการอนุญาตของ Claude Code เนื่องจากตัวกรอง if ของ hook จะล้มเหลวแบบเปิด
คำถาม: ผมจะตั้งค่า Claude Code hooks ได้ที่ไหน?
ในไฟล์ settings: ~/.claude/settings.json (ทุกโปรเจกต์), .claude/settings.json (หนึ่งโปรเจกต์ แชร์ได้), หรือ .claude/settings.local.json (เฉพาะในเครื่อง) คุณเลือกอีเวนต์ เพิ่ม matcher และกำหนด handlers
คำถาม: ผมสามารถใช้ Claude Code hooks โดยไม่ต้องติดตั้ง CLI ได้หรือไม่?
Hooks เองต้องใช้ Claude Code CLI หากเป้าหมายของคุณคือการใช้ Claude Code โดยไม่ต้องตั้งค่าในเครื่อง ให้รันมันใน managed browser sandbox อย่าง Happycapy ซึ่งมี agent และ harness ของมันพร้อมใช้งานอยู่แล้ว — เหมาะอย่างยิ่งเมื่อคุณไม่ต้องการติดตั้งและตั้งค่า CLI ด้วยตัวเอง
คำถาม: hook แรกที่ดีที่ควรเพิ่มคืออะไร?
linter ของ PostToolUse ที่จับคู่กับ Edit|Write — มันรัน formatter ของคุณหลังการเปลี่ยนแปลงโค้ดทุกครั้ง เพื่อให้ผลลัพธ์ของ agent ตรงตามกฎสไตล์ของคุณเสมอ มันมีความเสี่ยงต่ำและมีประโยชน์ในทันที
คู่มือที่เกี่ยวข้อง
- How Claude Code Review Actually Works: Diffs, Hooks, and What the Agent Catches
- Build Autonomous Agents with the Claude Code SDK: A Practical Developer's Guide
- Claude Code Web: How to Run Claude Code in Your Browser (No Install)
- Claude Code vs GitHub Copilot: Autonomous Agent or In-Editor Assistant?

