- Tính năng hook tùy chỉnh cho Claude Code đã được giới thiệu. Có thể kiểm soát hành vi của ứng dụng chính xác và lặp lại hơn mà không phụ thuộc vào lựa chọn của LLM
- Có thể tự động hóa nhiều tác vụ như tùy biến thông báo, tự động định dạng mã và theo dõi log lệnh
- Hoạt động tại các thời điểm như trước/sau khi thực thi lệnh, khi phát sinh thông báo, khi hoàn tất phản hồi, và có thể quản lý ở cấp dự án, người dùng, doanh nghiệp thông qua tệp cấu hình
- Thông qua cấu trúc tệp cấu hình và cơ chế matcher, có thể chỉ chạy một số hook nhất định tại thời điểm gọi công cụ cụ thể
- Đầu vào được truyền ở định dạng JSON, còn đầu ra dùng exit code hoặc JSON để điều khiển kết quả và phản hồi
- Hook tự động thực thi lệnh shell với toàn bộ quyền của người dùng, vì vậy cần lưu ý đến bảo mật và an toàn
Giới thiệu
- Hook trong Claude Code là các lệnh shell tùy chỉnh được tự động chạy ở từng giai đoạn của vòng đời thực thi mã
- Nhờ đó có thể tạo ra tự động hóa nhất quán mỗi lần, thay vì để LLM chọn chạy một cách tùy ý
-
Ví dụ sử dụng chính
- Thông báo: cung cấp thông báo tùy chỉnh cho người dùng khi chờ nhập liệu
- Tự động định dạng: tự động chạy
prettier hoặc gofmt sau khi chỉnh sửa tệp
- Ghi log: ghi lại và tổng hợp các lệnh đã chạy để phục vụ theo dõi hoặc gỡ lỗi
- Phản hồi: tự động cung cấp phản hồi khi tạo mã không phù hợp với quy tắc của codebase
- Quyền tùy chỉnh: chặn thay đổi đối với thư mục nhạy cảm hoặc tệp production
- Vì hoạt động bằng mã hệ thống chứ không phải prompt, nên được thực thi một cách xác định ở mọi lần → tăng độ tin cậy của tự động hóa
- Hook trực tiếp thực thi lệnh shell với toàn bộ quyền của người dùng, nên cần kiểm tra tính an toàn.
Ví dụ cấu hình
- Ví dụ: đăng ký hook để Claude ghi log mỗi lần trước khi chạy lệnh Bash
1. Vào menu cài đặt hook bằng lệnh /hooks, chọn sự kiện PreToolUse
2. Thêm matcher Bash (chỉ áp dụng cho lệnh Bash)
3. Đăng ký và lưu lệnh hook (nếu chọn vị trí User settings thì áp dụng cho toàn bộ dự án)
4. Có thể kiểm tra cấu hình bằng /hooks hoặc xem trực tiếp tệp ~/.claude/settings.json
Cấu trúc cấu hình
- Hook được nhóm theo matcher, và mỗi matcher có thể có nhiều hook dưới dạng mảng
- Ví dụ: chuỗi đơn (khớp chính xác), biểu thức chính quy, hoặc để trống thì áp dụng cho mọi sự kiện
- Các loại tệp cấu hình
~/.claude/settings.json: cấu hình toàn bộ người dùng
.claude/settings.json: cấu hình dự án
.claude/settings.local.json: cấu hình cục bộ (không chia sẻ)
- cấu hình chính sách doanh nghiệp
Các sự kiện hook chính
- PreToolUse: chạy trước khi gọi công cụ, có thể chặn thực thi nếu cần (matcher chính: Bash, Write, Edit, Grep, v.v.)
- PostToolUse: chạy ngay sau khi công cụ thực thi, hỗ trợ cùng matcher
- Notification: chạy khi gửi thông báo
- Stop: chạy sau khi phản hồi hoàn tất
Ví dụ matcher
Task: tác vụ agent
Bash: lệnh shell
Glob: khớp mẫu tệp
Grep: tìm kiếm nội dung
Read: đọc tệp
Edit, MultiEdit: chỉnh sửa tệp
Write: ghi tệp
WebFetch, WebSearch: tác vụ web
Định dạng đầu vào và đầu ra
- Đầu vào: JSON được truyền qua stdin (bao gồm thông tin phiên và dữ liệu theo từng sự kiện)
- Ví dụ: PreToolUse bao gồm
tool_input, PostToolUse có thêm tool_response
- Đầu ra:
- exit code 0: thực thi bình thường, stdout sẽ hiển thị cho người dùng
- exit code 2: chặn, stderr được chuyển cho Claude dưới dạng phản hồi (trong PreToolUse sẽ chặn thực thi công cụ)
- Mã khác: lỗi, chỉ stderr được hiển thị cho người dùng
- Điều khiển nâng cao: nếu stdout trả về JSON, có thể điều khiển luồng chi tiết bằng các giá trị như "continue": false hoặc
"decision": "block"
Tích hợp với công cụ MCP
- Cũng hỗ trợ các công cụ dựa trên Model Context Protocol (MCP), và có thể nhắm mục tiêu chọn lọc thông qua mẫu đặt tên đặc biệt (
mcp____)
Khuyến nghị bảo mật
- Vì hook có rủi ro thực thi lệnh tùy ý trên hệ thống, nên bắt buộc phải có các quy tắc an toàn như kiểm tra giá trị đầu vào, kiểm tra đường dẫn, loại trừ tệp nhạy cảm, dùng đường dẫn tuyệt đối
- Thay đổi cấu hình không được áp dụng ngay lập tức; hệ thống dùng snapshot khi bắt đầu phiên và sẽ hiển thị cảnh báo nếu có thay đổi từ bên ngoài
Môi trường thực thi và gỡ lỗi
- Mỗi hook có giới hạn tối đa 60 giây, chạy song song, hoạt động trong thư mục làm việc và môi trường hiện tại
- Có thể gỡ lỗi bằng cách kiểm tra cấu hình trong
/hooks, thử trực tiếp lệnh, kiểm tra exit code và đầu ra
- Quá trình và kết quả thực thi có thể xem trong transcript mode (Ctrl-R)
4 bình luận
Xin hãy làm luôn bản cho Windows nữa TT
Hãy dùng WSL
Có lẽ do cấu hình PC của tôi thấp nên trong WSL trên Windows, một số tác vụ dùng Claude Code (ví dụ: build project, chạy web server cục bộ, v.v.) quá chậm. Dù cũng có cách chỉ chạy thủ công những tác vụ đó bên ngoài WSL, nhưng khá phiền và bị nhiều hạn chế, nên từ sau khi Gemini CLI ra mắt, trên Windows tôi chủ yếu dùng Gemini CLI thay cho Claude Code.
Ý kiến trên Hacker News
Tôi từng khá bực vì Claude Code Opus 4 có thói quen không thêm ký tự xuống dòng ở cuối file.
Vì mỗi lần thử hook mới đều phải khởi động lại claude, dùng một script cho phép tiếp tục chỉnh sửa trong cùng phiên hiệu quả hơn nhiều.
Script này áp dụng formatter cho file C và shell script, còn với các file khác thì chỉ bổ sung ký tự xuống dòng bị thiếu.
AI như Claude khá yếu trong việc chia nhỏ vấn đề hợp lý, và đôi khi còn thử làm theo những cách kỳ lạ, nên tôi đã phải sửa đi sửa lại nhiều lần, ví dụ như mẫu hook ở trên: lưu file JSON ra đĩa, chỉ lấy đường dẫn rồi lưu lại, sau đó truyền đường dẫn đó vào
save-hook.sh.Tôi làm được thứ mình muốn trong 10 phút, nhưng thời gian lãng phí vì bắt nó làm những bước quá lớn trong một lần còn nhiều hơn.
Mọi người nói AI sẽ thay thế lập trình viên, nhưng ai sẽ là người cấu hình các hook này và đề xuất tính năng mới thì vẫn là con người.
Những công việc liên quan đến kiểu tooling này sẽ còn tồn tại cho đến khi AI tiến hóa tới mức tự nghĩ ra ý tưởng đó và áp dụng cho AI khác.
Nếu ví von theo nghề mộc, tôi nghĩ hiện tại giống như thời điểm chuyển từ dụng cụ cầm tay sang dụng cụ điện.
Người hiểu nền tảng cơ bản sẽ dùng công cụ tốt hơn, nhưng giờ là giai đoạn thay vì làm thủ công tinh xảo bằng tay thì dùng table saw để làm nhanh hơn, hiệu quả hơn nhưng cũng có thể nguy hiểm hơn.
Điều này cũng giống lập luận rằng máy nông nghiệp như combine harvester sẽ thay thế việc làm trong nông nghiệp.
Có hợp lý không khi cho rằng toàn bộ lực lượng lao động đơn giản chỉ chuyển sang làm người vận hành máy?
Quan điểm ở đây là dù là công cụ tự động hóa, nông nghiệp hay AI, giá trị không chỉ nằm ở một sự chuyển đổi đơn giản như vậy.
Giống câu chuyện nổi tiếng kiểu "Trái Đất đứng trên lưng rùa", sau khi AI xuất hiện thì có thể lặp vô hạn câu hỏi "thế ai sẽ quản lý AI đó?".
Đã có những trường hợp giao luôn cho Claude Code tự cập nhật
CLAUDE.md, nên việc để nó sửa cả hook của chính nó cũng không hẳn là bất khả thi.Nhưng điều thú vị là, giống như Jurassic Park, người ta rất dễ bỏ qua câu hỏi "liệu có nên làm hay không".
Ý kiến rằng AI sẽ làm giảm số nghề lập trình, và câu hỏi vậy ai sẽ cấu hình hook, đều đều đúng.
Điều cần nhấn mạnh là tiến bộ công nghệ không thể bị đơn giản hóa thành chuyện số lượng việc làm tăng hay giảm; nó vừa xóa bỏ việc làm vừa tạo ra việc làm mới.
Thực ra với đa số mọi người, kiểu việc này không phải phát triển phần mềm mà là bảo trì, DevOps và những việc tương tự.
Ngay cả trong sản phẩm SaaS cũng có rất nhiều việc liên quan đến vận hành hơn là code, và nó khác với thứ mà người dùng HN xem là phát triển phần mềm đúng nghĩa.
Tôi thật sự rất háo hức với lần bổ sung tính năng này.
Hook có vẻ sẽ đóng vai trò quan trọng trong context engineering của agent và trong việc kiểm chứng hiệu năng lúc chạy.
Nó cũng có thể mở rộng sang nhiều tình huống như compliance doanh nghiệp hay giám sát hành vi.
Việc Anthropic hỗ trợ ngay từ đề xuất issue trên GitHub cũng rất ấn tượng.
Link issue liên quan
Tôi nghĩ kiểu tính năng này rồi sẽ trở thành tuyệt kỹ phổ cập cho mọi coding agent.
Điều tôi thích ở tính năng này là có thể viết trực tiếp các rule kiểm soát thực thi lệnh phức tạp, thay vì phải lách qua
CLAUDE.md.Ví dụ,
docker compose exec django python manage.py testthì có thể cho phép, còn
docker compose exec django python manage.py makemigrationsthì có thể chặn.
.Claude/settings.json.Tôi nghĩ sẽ còn tốt hơn nếu tính năng này hoạt động như chính một MCP server.
Có thể hình dung việc tạo sẵn hook thành các công cụ mcp với tên được quy ước trước, để agent tự động phát hiện hook mà không cần biết cách hiện thực bên trong, từ đó tái sử dụng mcp server hoặc dùng lại ở agent khác.
Claude Code rất hay quên các chỉ dẫn trong file
CLAUDE.mdvà những nội dung quan trọng của codebase, nên phải thường xuyên nhắc lại.Tôi đang kỳ vọng bản cập nhật này có thể khắc phục vấn đề đó.
void! TrongCLAUDE.mdđã ghi là cấm kiểu đó mà!"Claude đọc
CLAUDE.mdrồi nói kiểu "22 giây, 2.6k token…"rồi phản hồi "Bạn nói đúng!".
Chia sẻ vài hook mẫu.
Bài viết ví dụ về cách viết hook và tự động hóa workflow
Thật vui khi Claude Code giờ đã có hỗ trợ linting/type check sau khi sửa code ở mức tương đương Cursor.
Mong là Cursor cũng sẽ có tính năng này.
Hiện tại tôi đang tạm chắp vá bằng cách kết hợp nhiều rule để xử lý phần nào.
Tôi cho rằng tính năng này đã lấp được khoảng cách chức năng lớn tồn tại bấy lâu nay.
Vì cách Claude Code tạo commit khiến các Git hook thông thường đa phần không chạy được, nên tôi đã dùng cách vòng qua
CLAUDE.mdđể chỉ thị nó tự động hóa format code bằng Qlty CLI, nhưng Claude lại không thực hiện ổn định và nhất quán.Thay đổi lần này có thể mang lại kết quả mang tính quyết định hơn.
Hiện tại các sự kiện có thể hook vẫn còn hạn chế, nhưng tôi kỳ vọng sau này sẽ dễ dàng hook được cả sự kiện Git commit và push.
Link GitHub của Qlty CLI
Nhân tiện thì Claude xử lý Java rất giỏi.
Nó nắm rất chính xác style guide của tôi, cả sở thích thụt lề, nên code Java tạo ra khớp hoàn hảo tới mức không cần reformat.
Ngay cả JavaDoc cũng được căn chỉnh rất tinh tế, làm tôi khá bất ngờ.
Có lẽ nó đã được học từ một lượng mã Java doanh nghiệp khổng lồ.
Tôi tò mò vì sao các Git hook thông thường lại không hoạt động đúng trong claude code.
Husky và lint-staged thì hoạt động bình thường, nhưng Pre Commit Hooks thì không chạy.
Theo hiểu biết ngắn gọn của tôi, tính năng này không tiêu tốn context, và cũng không phải cấu trúc kiểu Claude tự quyết định khi nào chạy như MCP, mà là cấu trúc tự động hóa do người dùng chỉ định trực tiếp cho từng lần sử dụng công cụ.