Hoàn thành bài "Bài 5: Slash commands và Custom commands" trước để mở khoá bài này.Đến bài trước

Giới thiệu

Khi làm việc với Claude Code trong các dự án thực tế, bạn sẽ nhanh chóng nhận ra rằng một agent đơn lẻ chạy tuần tự không đủ để xử lý những tác vụ phức tạp. Bài này tập trung vào hai cơ chế nâng cao: hooks cho phép bạn can thiệp vào hành vi agent trước và sau mỗi thao tác, và subagents cho phép phân chia công việc thành nhiều luồng xử lý song song.

Hiểu và sử dụng tốt hai cơ chế này là ranh giới giữa một workflow tự động cơ bản và một hệ thống thực sự có thể mở rộng.

Hooks: Kiểm soát hành vi trước và sau thao tác

Hooks trong Claude Code là các hàm callback được đăng ký để chạy tại các điểm cụ thể trong vòng đời của một tool call. Có hai loại chính: PreToolUse chạy trước khi tool được thực thi, và PostToolUse chạy sau khi tool hoàn thành.

Cấu hình hooks được khai báo trong file settings, thường là .claude/settings.json:

json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash /scripts/validate_command.sh"
}
]
}
],
"PostToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "bash /scripts/run_linter.sh"
}
]
}
]
}
}

Trường matcher xác định hook này áp dụng cho tool nào. Bạn có thể dùng tên tool cụ thể như Bash, Write, Edit, hoặc dùng ký tự đại diện để bắt tất cả.

sơ đồ vòng đời tool call với PreToolUse và PostToolUse ở hai đầu

Khi hook script chạy, Claude Code truyền thông tin về tool call qua stdin dưới dạng JSON. Script của bạn có thể đọc dữ liệu này để đưa ra quyết định. Exit code quyết định hành vi tiếp theo: exit 0 nghĩa là cho phép tiếp tục, exit 2 sẽ block thao tác đó và trả thông báo lỗi về cho agent.

Dưới đây là ví dụ một validate script đơn giản dùng cho PreToolUse trên Bash tool, ngăn agent xóa file ngoài thư mục dự án:

bash
#!/bin/bash
input=$(cat)
command=$(echo "$input" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('tool_input',{}).get('command',''))")
if echo "$command" | grep -qE 'rm -rf /|sudo rm'; then
echo "Blocked: lệnh xóa nguy hiểm bị từ chối" >&2
exit 2
fi
exit 0

PostToolUse hooks hữu ích cho các tác vụ như tự động chạy linter sau mỗi lần agent ghi file, log kết quả ra file audit, hoặc gửi thông báo khi agent hoàn thành một nhóm thao tác.

Subagents: Xử lý song song các tác vụ phức tạp

Subagent là cơ chế để agent chính (orchestrator) khởi tạo và điều phối các agent con chạy độc lập. Mỗi subagent có context riêng, tool access riêng, và có thể chạy đồng thời với nhau.

Trong Claude Code, bạn kích hoạt subagent bằng cách dùng tool Task trong prompt của orchestrator. Orchestrator mô tả nhiệm vụ, và hệ thống tạo một agent con với context tách biệt để thực thi:

bash
claude -p "Hãy phân tích codebase này bằng cách:
1. Dùng Task tool để tạo subagent A: quét toàn bộ file .py và liệt kê các function chưa có docstring
2. Dùng Task tool để tạo subagent B: kiểm tra tất cả file config và báo cáo các key bị thiếu so với .env.example
3. Tổng hợp kết quả từ cả hai và tạo báo cáo audit.md"

Các subagent A và B chạy song song, sau đó orchestrator chờ kết quả từ cả hai trước khi tổng hợp. Điều này giúp tiết kiệm thời gian đáng kể so với chạy tuần tự.

sơ đồ orchestrator phân chia 1 tác vụ thành 3 subagent chạy song song rồi gộp kết quả

Một điểm quan trọng: mỗi subagent tiêu thụ context window riêng, vì vậy hãy thiết kế nhiệm vụ cho từng subagent đủ cụ thể và tự chứa. Tránh tình huống subagent cần giao tiếp qua lại với orchestrator nhiều lần — điều đó làm mất đi lợi thế song song hóa.

Có thể kết hợp hooks với subagents: hooks áp dụng cho cả agent chính lẫn subagent, giúp bạn duy trì chính sách kiểm soát nhất quán trên toàn bộ hệ thống dù có bao nhiêu agent con đang chạy.

Lỗi thường gặp

Lỗi phổ biến nhất khi dùng hooks là script thoát với exit code không đúng, khiến agent bị block hoặc không được block khi cần. Luôn test script hook độc lập trước khi tích hợp bằng cách pipe một JSON mẫu vào script và kiểm tra exit code trả về.

Với subagents, lỗi hay gặp là giao nhiệm vụ quá mơ hồ hoặc phụ thuộc lẫn nhau cho hai subagent chạy song song. Ví dụ, nếu subagent B cần đọc file mà subagent A tạo ra, hai task này không thể chạy song song — orchestrator phải chạy A xong mới chạy B.

Một lỗi khác là không xử lý trường hợp subagent thất bại. Orchestrator cần có hướng dẫn rõ ràng về việc làm gì khi một task con báo lỗi, thay vì mặc định bỏ qua và tiếp tục tổng hợp kết quả thiếu.

Tổng kết

Hooks cho bạn quyền kiểm soát chi tiết hành vi agent tại từng bước, từ việc validate lệnh nguy hiểm đến tự động hóa QA sau mỗi thao tác. Subagents mở ra khả năng xử lý song song, phù hợp khi tác vụ có thể tách thành các phần độc lập. Kết hợp cả hai, bạn có thể xây dựng pipeline tự động hóa vừa an toàn vừa hiệu quả cho những dự án quy mô thực tế.

Luyện tập sau buổi học

Bài kiểm tra cuối bài

Ôn lại kiến thức, thử sức và nhận góp ý cho bài làm.

0/1
Đã trả lời · 0/1
Bài 6: Hooks, Subagents và tự động hóa nâng cao