PostToolUse Hook: 'Dọn dẹp' tự động sau mỗi lệnh AI
Cấu hình PostToolUse Hook trong Claude Code để tự động format code, ghi audit log và gửi notification sau mỗi hành động. Khắc phục triệt để tính 'quên trước nhớ sau' của LLM.
Định nghĩa
PostToolUse Hook đóng vai trò như "người dọn dẹp" trong Claude Code — tự động kích hoạt ngay sau khi AI hoàn thành bất kỳ thao tác nào (viết file, chạy lệnh bash, edit code) để thực thi các tác vụ deterministic như format code, kiểm tra bảo mật, hoặc gửi thông báo, bù đắp triệt để cho tính "quên trước nhớ sau" của LLM.
Giải thích chi tiết
Cơ chế "JSON trên stdin" — dữ liệu có cấu trúc thay vì log tự nhiên
Khác với việc parse log bằng regex, PostToolUse hook nhận thông tin về hành động vừa xảy ra qua stdin dưới dạng JSON có cấu trúc. Payload bao gồm:
tool_name: Loại thao tác (Write,Edit,Bash, v.v.)tool_input: Chi tiết đầu vào (đường dẫn file, command string, nội dung)tool_output: Kết quả trả về từ thao tác vừa rồi
Nhờ đó, script của bạn viết logic điều kiện chính xác: "if tool_name == 'Write' and file_path.endswith('.ts')", thay vì cố gắng đoán ý từ văn bản tự nhiên. JSON-RPC này biến hooks thành middleware có thể kiểm thử, không phải "script hacky" parse log.
Cleanup crew vs Gatekeeper — vai trò bổ sung cho PreToolUse
Nếu PreToolUse Hook đóng vai trò "bảo vệ" (gatekeeper) có quyền veto (exit code 2) để chặn lệnh nguy hiểm trước khi chạy, thì PostToolUse là "đội dọn vệ sinh" (cleanup crew). Nó không thể ngăn hành động xảy ra, chỉ có thể phản ứng sau đó bằng cách sửa chữa, ghi log, hoặc thông báo.
Sự phân chia này quan trọng về mặt kiến trúc: PreToolUse giải quyết vấn đề an toàn (safety), PostToolUse giải quyết vấn đề chất lượng và tuân thủ (quality & compliance).
Bài toán "Context Window Tax" — chi phí ẩn của auto-format
Khi dùng PostToolUse để format code (ví dụ chạy Prettier), Claude sẽ nhận thấy file thay đổi ngay sau khi hook chạy xong. Hệ thống đưa vào context window một system reminder ghi nhận thay đổi này, tiêu tốn khoảng 100-200 tokens cho mỗi lần edit.
Trong session dài 50 lần edit, đây là 5k-10k tokens "vô ích" nếu format ngay lập tức sau mỗi lần sửa. Chiến lược tối ưu là batched formatting: để AI code "bừa bãi" trong session, rồi dùng Stop Hook hoặc /simplify command để format toàn bộ một lần trước khi commit.
Async execution và race conditions
PostToolUse hỗ trợ chế độ async: true cho phép hook chạy non-blocking song song với luồng làm việc chính của AI. Phù hợp cho việc gửi Slack notification hoặc ghi audit log — những tác vụ không cần kết quả trả về ngay lập tức.
Tuy nhiên, do các hook chạy parallel, bạn không thể giả định thứ tự thực thi giữa chúng. Nếu hook A phụ thuộc vào side effect của hook B, sẽ gặp race condition. Giải pháp là gộp logic vào một script duy nhất hoặc dùng file lock/timestamp để đồng bộ.
Ví dụ thực tế
Auto-format Prettier cho dự án React/Node.js (Startup VN)
Tình huống: Team startup ở Hà Nội dùng Prettier với cấu hình single quote và 2 spaces, nhưng Claude thường quên và sinh code với double quote và 4 spaces do "quyền năng" từ training data.
Cấu hình hook (~/.claude/hooks/posttooluse/prettier-format.js):
#!/usr/bin/env node
const fs = require('fs');
// Đọc JSON từ stdin
const input = JSON.parse(fs.readFileSync(0, 'utf-8'));
const { tool_name, tool_input } = input;
// Chỉ xử lý Write và Edit với file JS/TS
if (['Write', 'Edit'].includes(tool_name) &&
tool_input.file_path?.match(/\.(js|jsx|ts|tsx)$/)) {
const { execSync } = require('child_process');
const file = tool_input.file_path;
try {
// Chạy prettier trên file vừa edit
execSync(`npx prettier --write "$[file]"`, { stdio: 'inherit' });
console.error(`✓ Formatted $[file]`);
} catch (e) {
console.error(`✗ Format failed: ${e.message}`);
}
}
// Exit 0 để báo thành công (không chặn gì cả)
process.exit(0);chmod +x ~/.claude/hooks/posttooluse/prettier-format.jsSau khi cấu hình, mỗi lần Claude sửa file components/UserProfile.tsx, hook tự động chạy Prettier ngay sau đó, đảm bảo codebase luôn consistent dù AI có "quên" coding standard.
Audit log cho ngân hàng/fintech (Compliance VietQR)
Tình huống: Một ngân hàng số triển khai tích hợp VietQR cần ghi lại mọi thao tác sửa code vào hệ thống SIEM để phục vụ audit trail theo quy định Ngân hàng Nhà nước (NHNN) về an toàn hệ thống thanh toán.
Hook script (~/.claude/hooks/posttooluse/audit-log.py):
#!/usr/bin/env python3
import json
import sys
import requests
from datetime import datetime
payload = json.load(sys.stdin)
# Chỉ log các thao tác ghi file hoặc bash nguy hiểm
if payload['tool_name'] in ['Write', 'Edit', 'Bash']:
audit_entry = {
'timestamp': datetime.now().isoformat(),
'session_id': payload.get('session_id', 'unknown'),
'tool': payload['tool_name'],
'target': payload['tool_input'].get('file_path') or payload['tool_input'].get('command'),
'user': payload.get('user', 'claude-session'),
'environment': 'production' if 'prod' in sys.argv else 'development'
}
# Gửi async đến SIEM API (không block AI)
try:
requests.post(
'https://siem.internal-bank.com/api/claude-audit',
json=audit_entry,
timeout=2
)
except:
pass # Silent fail để không làm chậm AI
sys.exit(0)Lưu ý dùng async: true trong .claude/settings.json để API call không làm chậm luồng làm việc của Claude.
Zalo notification khi refactor module Shopee-style hoàn thành
Tình huống: Tech lead cần biết khi nào Claude Code vừa hoàn thành refactor module lớn (hơn 10 file) giống kiểu microservices của Shopee để kịp review trước giờ deploy.
Hook script kiểm tra số lượng file thay đổi:
#!/bin/bash
# ~/.claude/hooks/posttooluse/notify-refactor.sh
read JSON_INPUT
# Kiểm tra nếu là Edit và mention "refactor" trong output
if echo "$JSON_INPUT" | grep -q '"tool_name": "Edit"' && \
echo "$JSON_INPUT" | grep -qi "refactor"; then
# Đếm số file đã sửa trong session (từ transcript)
FILE_COUNT=$(grep -c "Edit\\|Write" ~/.claude/transcript/*.json 2>/dev/null || echo "0")
if [ "$FILE_COUNT" -gt 10 ]; then
curl -X POST https://api.zalo.me/v2.0/oa/message \
-H "access_token: $ZALO_OA_TOKEN" \
-H "Content-Type: application/json" \
-d "{
\"recipient\": {\"user_id\": \"$LEAD_USER_ID\"},
\"message\": {\"text\": \"Claude vừa refactor xong ~$FILE_COUNT files. Cần review trước khi lên production!\"}
}"
fi
fi
exit 0Ứng dụng
Developer cá nhân (Freelancer/Indie Hacker):
Tự động chạy eslint --fix hoặc black (Python) sau mỗi lần sửa file, giải phóng cognitive load khỏi việc nhớ coding standard. Kết hợp với Voice Mode để "nói" code xong rồi để hook tự dọn dẹp.
Team Lead/QA Engineer: Thiết lập audit trail tự động ghi lại "AI đã sửa gì, khi nào, ở đâu" vào hệ thống compliance. Đặc biệt quan trọng khi dùng Agent Teams với nhiều Claude instance chạy song song — cần biết agent nào đã touch file nào.
DevOps/SRE:
Trigger auto-deployment hoặc smoke test sau khi AI push code. Ví dụ: hook nhận diện khi Claude chạy git push, tự động trigger GitHub Actions workflow hoặc gửi webhook đến CI/CD pipeline của doanh nghiệp.
Doanh nghiệp FinTech/Bảo hiểm: Đảm bảo mọi thao tác sửa code đều được log vào hệ thống enterprise setup, phục vụ kiểm toán nội bộ và compliance (SOC 2, ISO 27001, quy định NHNN).
So sánh
| Đặc điểm | PostToolUse Hook | PreToolUse Hook | Slash Commands |
|---|---|---|---|
| Thời điểm kích hoạt | Sau hành động | Trước hành động | Khi user gõ lệnh |
| Khả năng chặn (Veto) | Không — chỉ cleanup | Có — exit code 2 | Không liên quan |
| Mục đích chính | Format, log, notify | Chặn lệnh nguy hiểm | Tự động hóa workflow |
| Context window impact | Cao (nếu format liên tục) | Thấp | Trung bình |
| Độ phức tạp cấu hình | Trung bình | Cao (cần pattern matching an toàn) | Thấp |
Kết luận: PostToolUse phù hợp cho "dọn dẹp và ghi chép", PreToolUse phù hợp cho "bảo vệ và chặn", còn Slash Commands phù hợp cho "lệnh chủ động". Trong thực tế, nên kết hợp cả ba: PreToolUse để ngăn AI xóa nhầm production database, PostToolUse để format code và ghi audit log, Slash Commands để trigger các workflow phức tạp.
Bài viết liên quan
Cùng cụm (Hooks & Automation)
- Hooks là gì? 25 events và 4 loại hook — Tổng quan kiến trúc event-driven của Claude Code
- PreToolUse Hook: Chặn lệnh nguy hiểm trước khi chạy — Bảo vệ production khỏi AI "lỡ tay"
- PermissionRequest Hook: Tự động phê duyệt hoặc gửi Zalo xin phép — Workflow xin phép thông minh
- 8 hook thực tế: format-code, security-scan, context-tracker... — Thư viện pattern sẵn dùng
- Session Hooks: SessionStart, Stop, StopFailure — Quản lý vòng đời session
- Prompt Hook và Agent Hook: LLM-powered automation — Tự động hóa nâng cao
Đọc tiếp (Nâng cao & Tự động hóa)
- Pro Automation: CI/CD, Auto Code Review — Đưa PostToolUse vào pipeline production
- MCP là gì? Model Context Protocol — Mở rộng khả năng hook bằng external tools
- Agent Teams: Nhiều Claude phối hợp — Kết hợp hooks với multi-agent workflows
PreToolUse Hook: Chặn lệnh nguy hiểm trước khi AI thực thi
Chặn lệnh nguy hiểm như rm -rf và DROP TABLE trước khi Claude Code chạy. Ràng buộc cứng bảo vệ codebase khỏi AI hallucination và lỗi vô ý xóa production.
Session Hooks: Điều khiển vòng đời session - Khởi tạo, Ép hoàn thành và Ghi log lỗi
Tự động nạp context khi mở project, ép Claude chạy test trước khi nghỉ, và ghi log lỗi API với 3 Session Hooks: Start, Stop, StopFailure.