1.5 Agent SDK Hooks
Agent SDK Hooks คืออะไร
Hooks คือ callback functions ที่ถูกเรียกในจุดต่างๆ ของ agent lifecycle — ก่อน/หลังเรียก tool, เมื่อเกิด error, ตอนเริ่ม/จบ turn เป็นต้น Hooks ให้เราแทรก custom logic เข้าไปในการทำงานของ agent โดยไม่ต้องแก้ core logic — ใช้สำหรับ logging, monitoring, security checks, หรือ modify behavior
ใน Claude Code ecosystem hooks ถูกกำหนดใน settings (~/.claude/settings.json) และทำงานเป็น shell commands ที่ execute ณ จุดที่กำหนด
Hook Types ใน Claude Code
Pre-tool Hooks
ทำงานก่อนที่ tool จะถูก execute:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"command": "python3 ~/.claude/hooks/validate-bash.py"
},
{
"matcher": "Edit",
"command": "python3 ~/.claude/hooks/check-file-permissions.py"
}
]
}
}
Post-tool Hooks
ทำงานหลังจาก tool execute เสร็จ:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write",
"command": "python3 ~/.claude/hooks/lint-written-file.py"
}
]
}
}
Notification Hooks
แจ้งเตือนเมื่อเกิด events:
{
"hooks": {
"Notification": [
{
"command": "terminal-notifier -message '$NOTIFICATION_MESSAGE'"
}
]
}
}
Hook Input/Output Protocol
Hooks รับ input เป็น JSON ผ่าน stdin และส่ง output ผ่าน stdout:
Input ที่ Hook ได้รับ
{
"tool_name": "Bash",
"tool_input": {
"command": "rm -rf /important/data"
},
"session_id": "abc123",
"agent_type": "main"
}
Output ที่ Hook ส่งกลับ
{
"decision": "block",
"reason": "Destructive command detected: rm -rf on important directory"
}
Decision values:
"allow"— อนุญาตให้ tool ทำงาน (default ถ้าไม่มี output)"block"— ห้ามไม่ให้ tool ทำงาน พร้อมแจ้ง reason"modify"— แก้ไข tool input ก่อนส่งต่อ (advanced)
ตัวอย่าง Hook Scripts
Security Hook — Block Dangerous Commands
#!/usr/bin/env python3
import sys, json
data = json.load(sys.stdin)
command = data.get("tool_input", {}).get("command", "")
DANGEROUS_PATTERNS = [
"rm -rf /",
"DROP TABLE",
"chmod 777",
"> /dev/sda",
]
for pattern in DANGEROUS_PATTERNS:
if pattern in command:
print(json.dumps({
"decision": "block",
"reason": f"Blocked: dangerous pattern '{pattern}' detected"
}))
sys.exit(0)
# Allow by default
print(json.dumps({"decision": "allow"}))
Logging Hook — Track All Tool Usage
#!/usr/bin/env python3
import sys, json, datetime
data = json.load(sys.stdin)
log_entry = {
"timestamp": datetime.datetime.now().isoformat(),
"tool": data.get("tool_name"),
"input_summary": str(data.get("tool_input", ""))[:200],
"session": data.get("session_id")
}
with open("/tmp/claude-tool-log.jsonl", "a") as f:
f.write(json.dumps(log_entry) + "\n")
print(json.dumps({"decision": "allow"}))
Cost Tracking Hook
#!/usr/bin/env python3
import sys, json, os
data = json.load(sys.stdin)
BUDGET_FILE = os.path.expanduser("~/.claude/budget.json")
try:
with open(BUDGET_FILE) as f:
budget = json.load(f)
except FileNotFoundError:
budget = {"spent": 0, "limit": 10.0}
if budget["spent"] >= budget["limit"]:
print(json.dumps({
"decision": "block",
"reason": f"Budget exhausted: ${budget['spent']:.2f} / ${budget['limit']:.2f}"
}))
else:
print(json.dumps({"decision": "allow"}))
Hook Composition
Hooks ทำงานเป็น pipeline — ถ้ามีหลาย hooks สำหรับ event เดียว จะ execute ตามลำดับ ถ้าตัวใดตัวหนึ่ง block การ execute หยุดทันที:
{
"hooks": {
"PreToolUse": [
{"matcher": "Bash", "command": "hook-security.py"},
{"matcher": "Bash", "command": "hook-cost-check.py"},
{"matcher": "Bash", "command": "hook-rate-limit.py"}
]
}
}
Key Concepts
- Matcher — กำหนดว่า hook จะ fire สำหรับ tool ไหน (เช่น
"Bash","Edit","*"สำหรับทุก tool) - Non-blocking Default — ถ้า hook crash หรือ timeout agent ยังทำงานต่อได้ (fail-open)
- Context Available — hooks ได้รับ session info, tool input, agent type ครบเพื่อ decision making
- Stateless Preferred — hooks ควรเป็น stateless (อ่าน state จาก file/db) เพื่อ reliability
Exam Tips
- จำ hook types: PreToolUse, PostToolUse, Notification — แต่ละตัวใช้ตอนไหน
- Hook ที่ return
"block"จะหยุด tool execution ทันที — agent จะเห็น error message จาก reason - Hooks execute as shell commands ไม่ใช่ in-process — มี overhead ของ process spawn
- ข้อสอบอาจถามเรื่อง security hooks: ใช้ PreToolUse เพื่อ validate ก่อน execute
- Hooks เหมาะสำหรับ cross-cutting concerns (logging, security, cost) ไม่ควรใส่ business logic