Các bài trong khoáBài 5/30

30 bài

Domain 1: Agentic Architecture & Orchestration·Task 1.5

Hook trong Agent SDK để chặn tool và chuẩn hoá dữ liệu

Dùng hook PreToolUse để chặn thao tác vi phạm quy định, PostToolUse để chuẩn hoá kết quả tool, và khi nào chọn hook thay vì dặn trong prompt.

  • 5 phút đọc
  • Đối chiếu docs 02/11/2026
  • 3 nguồn

Đọc xong bạn nắm được

  • Biết hook là gì và hai loại hay dùng PreToolUse, PostToolUse
  • Chặn một lời gọi tool vi phạm quy định và hướng agent sang cách khác
  • Chuẩn hoá dữ liệu nhiều định dạng từ các tool trước khi Claude đọc
  • Chọn hook thay vì prompt khi quy định phải được tuân thủ tuyệt đối

Hook là một hàm do bạn viết, được Agent SDK tự gọi vào những thời điểm nhất định trong lúc agent chạy. Hai thời điểm đề thi hay hỏi nhất là ngay trước khi một tool chạy, và ngay sau khi tool chạy xong.

Nhờ hook, bạn có thể chen vào giữa agent và tool: chặn một lời gọi tool không được phép, hoặc sửa kết quả tool trước khi Claude đọc. Bài này giúp bạn biết lúc nào dùng loại hook nào, và vì sao hook đáng tin hơn lời dặn trong prompt.

Ví dụ xuyên suốt: agent đối soát và thanh toán hoá đơn

Phòng kế toán của một chuỗi nhà hàng dùng agent để đối soát hoá đơn nhà cung cấp rồi lên lệnh thanh toán. Agent lấy dữ liệu qua hai MCP server (MCP là chuẩn để nối agent với hệ thống bên ngoài, xem Domain 2):

  • mcp__erp__get_invoice: lấy hoá đơn từ phần mềm kế toán. Ngày trả về dạng Unix timestamp, ví dụ 1793577600. Trạng thái là số: 1 là chưa trả, 2 là đã trả.
  • mcp__bank__get_transfers: lấy lịch sử chuyển khoản từ ngân hàng. Ngày trả về dạng ISO 8601, ví dụ 2026-11-02T00:00:00+07:00. Trạng thái là chữ: "PENDING", "DONE".
  • mcp__bank__pay_supplier: lên lệnh chuyển tiền cho nhà cung cấp.

Quy định của công ty: khoản chi trên 100 triệu đồng phải có kế toán trưởng duyệt.

Hai vấn đề xuất hiện: agent hay so nhầm ngày vì hai hệ thống ghi ngày khác nhau, và có lần agent tự lên lệnh chi 150 triệu dù system prompt đã dặn.

Hai loại hook hay dùng

HookChạy lúc nàoDùng để
PreToolUseNgay trước khi tool chạyKiểm tham số, chặn lời gọi vi phạm quy định, sửa tham số
PostToolUseNgay sau khi tool chạy xong, trước khi Claude đọc kết quảChuẩn hoá, lọc, thêm thông tin vào kết quả tool

Mỗi hook gắn với một matcher để chọn tool nào thì hook chạy. Matcher so với tên tool, ví dụ "mcp__bank__pay_supplier" cho đúng một tool, hay "^mcp__erp__" cho mọi tool của server erp.

Chặn thao tác vi phạm quy định với PreToolUse

Hook PreToolUse nhận tên tool và tham số mà Claude định gọi. Nếu khoản chi vượt 100 triệu, hook trả về quyết định từ chối kèm lý do:

const capPayment: HookCallback = async (input) => {
  const { tool_input } = input as PreToolUseHookInput;
  const amount = (tool_input as { amount_vnd: number }).amount_vnd;
  if (amount > 100_000_000) {
    return {
      hookSpecificOutput: {
        hookEventName: "PreToolUse",
        permissionDecision: "deny",
        permissionDecisionReason: "Khoản chi trên 100 triệu cần kế toán trưởng duyệt. Gọi request_approval thay vì pay_supplier.",
      },
    };
  }
  return {}; // không trả gì: để lời gọi đi tiếp như bình thường
};

const options = {
  hooks: { PreToolUse: [{ matcher: "mcp__bank__pay_supplier", hooks: [capPayment] }] },
};

Theo tài liệu Agent SDK, permissionDecisionReason được đưa cho Claude đọc. Vì vậy lý do từ chối nên nói luôn agent phải làm gì tiếp, ở đây là gửi yêu cầu duyệt. Chặn mà không chỉ đường thì agent dễ thử lại vô ích hoặc bỏ dở việc.

Chuẩn hoá dữ liệu với PostToolUse

Hai hệ thống ghi ngày và trạng thái theo hai kiểu, nên Claude phải tự đổi qua đổi lại khi so sánh, và có lúc đổi sai. Thay vì dặn Claude "nhớ đổi Unix timestamp sang ngày", hãy để hook PostToolUse đổi giúp trước khi Claude đọc:

Dữ liệu gốcSau khi hook chuẩn hoá
"date": 1793577600"date": "2026-11-02"
"date": "2026-11-02T00:00:00+07:00""date": "2026-11-02"
"status": 1"status": "unpaid"
"status": "DONE""status": "paid"
const normalize: HookCallback = async (input) => {
  const { tool_response } = input as PostToolUseHookInput;
  return {
    hookSpecificOutput: {
      hookEventName: "PostToolUse",
      updatedToolOutput: toCommonFormat(tool_response), // đổi ngày, trạng thái về một kiểu
    },
  };
};

// hooks: { PostToolUse: [{ matcher: "^mcp__(erp|bank)__get_", hooks: [normalize] }] }

Theo tài liệu, updatedToolOutput chỉ thay đổi thứ Claude nhìn thấy. Tool đã chạy xong từ trước, dữ liệu gốc trong hệ thống không bị đụng tới.

Hook hay prompt

Cả hai vấn đề trong ví dụ đều có thể "sửa" bằng cách viết thêm vào system prompt. Vậy khi nào cần hook?

Dặn trong promptHook
Bản chấtClaude đọc và cố làm theoCode của bạn chạy, Claude không bỏ qua được
Mức bảo đảmPhần lớn thời gian (đề gọi là probabilistic compliance)Lần nào cũng vậy (deterministic guarantee)
Hợp vớiHướng dẫn về cách làm, giọng văn, ưu tiênQuy định bắt buộc: hạn mức tiền, quyền truy cập, định dạng dữ liệu

Nguồn

  1. Exam Guide CCAR-F v1.0, Task Statement 1.5(mở tab mới)
  2. Intercept and control agent behavior with hooks (Agent SDK)(mở tab mới)
  3. Hooks reference (Claude Code)(mở tab mới)

Nắm rồi thì thử sức với đề

Xem khoá luyện thi
Hook trong Agent SDK để chặn tool và chuẩn hoá dữ liệu · Anthropic Exam Pro