Tóm tắt nhanh: mỗi lớp guardrail của AgentKit chặn một loại rủi ro khác nhau. Hook như
scout-blockvàprivacy-blockchặn tool call bằng code; hard-gate và quy tắc chỉ là lời dặn; guard skill chỉ chạy khi bạn gọi. Biết lớp nào đang chạy thật mới kiểm đúng chỗ.
Phần 1 giải thích cơ chế hook trong Claude Code, bảy nhóm guardrail và các lớp settings. Phần này đi qua từng lớp một, rồi tới các chỗ hở và thói quen nên giữ. Cấu hình trong bài là ảnh chụp claudekit-engineer@2.19.1 (tháng 6/2026), đã đối chiếu lại với AgentKit 3.0.0-beta.1 như ghi chú ở Phần 1.
Công khai: mình là maintainer của AgentKit và có quan hệ affiliate: link AgentKit cuối bài là link affiliate.
Ghi chú: bản beta hiện tại của AgentKit (từ 3.0.0-beta.35, 21/10/2026) đã đổi format tên skill từ ak:<tên> sang ak-<tên>, nên lệnh trong bài đã cập nhật theo tên mới: Claude Code gõ /ak-plan, Codex gõ $ak-plan. Nếu bạn còn dùng bản cũ hơn, đổi ak- thành ak: là ra lệnh tương ứng.
scout-block: chặn đọc thư mục rác
Agent hay đọc node_modules/, chạy glob **/*.ts ở thư mục gốc (glob là mẫu khớp đường dẫn; **/*.ts nghĩa là mọi file .ts ở mọi thư mục con), hoặc cat dist/index.js. Mỗi lần như vậy là vài chục nghìn token bị nhét vào ngữ cảnh, kéo chi phí lên và chất lượng các lượt sau xuống. scout-block.cjs đăng ký ở PreToolUse, chạy trước mọi Read, Bash, Glob, Grep.
# Baseline .ckignore, do pattern-matcher.cjs xử lý
node_modules
dist
build
.next
.nuxt
__pycache__
.venv
venv
vendor
target
.git
coverageMột ngoại lệ quan trọng: các lệnh build được cho qua. Những lệnh như npm build, go build, make, docker build vẫn chạy, kể cả khi quá trình build chạm vào node_modules hay dist. Nếu chặn cả nhóm này, các luồng phát hành và test của AgentKit dễ tự vấp ngay ở bước build.
Chỗ hở 1, khi hook crash: lỗi đọc dữ liệu (parse error) đều dẫn tới exit 0, tool được cho qua. Hook có lỗi thì lớp chặn đó tắt âm thầm.
privacy-block: chặn secret, bắt người dùng duyệt rõ ràng
Khi agent đụng vào .env, id_rsa, *.pem, credentials.yaml là secret lộ vào bản ghi hội thoại. Một khi đã vào ngữ cảnh, nó có thể bị ghi log, bị trích lại trong kết quả của agent duyệt, hoặc bị dán vào PR.
@@PRIVACY_PROMPT_START@@
{ "type": "PRIVACY_PROMPT", "question": {...}, "options": [...] }
@@PRIVACY_PROMPT_END@@Claude đọc khối JSON này rồi gọi AskUserQuestion. Nếu người dùng đồng ý, thông báo của hook hướng dẫn đọc file theo đường đã được duyệt, ví dụ cat ".env" sau khi đã hỏi; code cũng hỗ trợ tiền tố APPROVED:. Điểm chính: phải có phê duyệt rõ ràng, không để model tự suy ra là người dùng đã đồng ý.
Chỗ hở 2, ngoại lệ cho Bash: privacy-block cho Bash đi qua và chỉ cảnh báo. Ai có quyền chạy Bash đều đọc được secret mà không qua bước phê duyệt.
Nếu secret đã lộ: privacy-block chỉ chặn việc đọc. Hãy đổi thông tin đăng nhập ngay, rà lại log hội thoại, rồi kiểm lịch sử git xem secret có bị commit không.
simplify-gate: chặn phát hành khi diff phình quá phạm vi
Một việc nhỏ có thể phình thành một PR đụng quá nhiều file: sửa phần kiểm tra đầu vào, thêm dọn dẹp, đổi định dạng, chỉnh vài hàm phụ bên cạnh. Khi bạn gõ kiểu "OK ship", simplify-gate.cjs (đăng ký ở UserPromptSubmit) đọc git diff HEAD rồi chỉ xét khi prompt có một trong các từ ship, merge, pr, deploy, publish.
Ngưỡng mặc định trong simplify.threshold ở bản này có ba con số:
- Tổng số dòng thêm và xoá trong diff vượt 400.
- Số file bị đụng vượt 8.
- Số dòng thêm trong một file vượt 200.
Gate chỉ chặn khi simplify.gate.enabled=true. Các ngưỡng này có thể ghi đè trong .ck.json.
Chỗ hở 3, mặc định dễ hiểu nhầm: hooks.simplify-gate = true chỉ cho Claude Code gọi script. Muốn script thật sự chặn một PR phình quá phạm vi, phải bật thêm simplify.gate.enabled = true. Bản cài mới chưa bật cờ này, nên gate chỉ kiểm nhẹ và không chặn.
// .ck.json của dự án: bật chặn thật
{ "simplify": { "gate": { "enabled": true } } }matchedSeverity() bỏ qua các cụm "don't ship" và "ship on", nên một prompt như "ship on Friday" cũng lọt qua. Muốn tắt gate cho mọi session trong một phạm vi, đặt CK_SIMPLIFY_DISABLED=1 trong settings.json, dưới key env.
workflow-artifact-gate: năm file JSON làm bằng chứng
Khi chạy đủ pipeline, mỗi giai đoạn để lại một file JSON ghi quyết định (artifact), giống hoá đơn sau mỗi bước. Hook này được thiết kế để gắn vào UserPromptSubmit và PreToolUse(Bash), nhưng không nằm trong bộ hook chạy sẵn sau khi cài mới; muốn dùng thì phải tự bật.
| Artifact | Giai đoạn | Nội dung |
|---|---|---|
context-snippets.json | scout, plan | Các đoạn code đã đọc |
risk-gate.json | predict | Cờ rủi ro cao, tự dừng |
verification.json | fix, cook | Checklist năm điểm |
review-decision.json | code-review | Kết luận của agent duyệt |
adversarial-validation.json | adversarial | Lượt kiểm đối kháng |
Gate này có hai mức xử lý. Ở bước rủi ro như phát hành, push, mở PR hay deploy, hook có thể dừng luồng ngay và trả lý do về cho model (emitBlock()). Ở bước nhẹ hơn như hoàn tất hay commit, hook cho luồng đi tiếp nhưng thêm cảnh báo vào ngữ cảnh để model tự sửa (emitSoft()).
Chỗ hở 4, gate này phải tự bật: workflow-artifact-gate là lớp kiểm artifact mạnh nhất, nhưng bản cài mới chưa tự gọi nó. Muốn dùng, phải gắn hook trong settings.json và bật cấu hình trong .ck.json. Thiếu bước này thì phát hành, push, mở PR hay deploy đều không bị gate chặn.
Hard-gate XML trong file skill
Hook chỉ chặn được tool call. Có những lỗi không nằm ở tool call mà ở trình tự: code trước khi có kế hoạch, sửa trước khi dò. AgentKit xử lý bằng cách gắn khối <HARD-GATE> vào file markdown của skill.
<HARD-GATE>
Do NOT write implementation code until a plan exists
and has been reviewed. Exception: --fast skips research
but still requires a plan step. User override: if user
explicitly says 'just code it', respect their instruction.
</HARD-GATE>ak-cook và ak-fix mỗi skill có vài hard-gate như vậy: dò hoặc lập kế hoạch trước, làm đúng yêu cầu hoặc tìm đúng nguyên nhân gốc, không gây tác dụng phụ.
Vì sao gọi là "hard" mà vẫn chỉ là lời dặn: chữ "hard" dễ gây hiểu nhầm, vì nó không chặn bằng code. Đây là lời dặn trong prompt. Model bỏ qua thì không có exit 2 nào chặn lại. Bọc trong thẻ XML chỉ tạo tín hiệu mạnh hơn quy tắc thường để model khó tự biện minh cho việc đi tắt.
dev-rules-reminder: đưa quy tắc vào ngữ cảnh
dev-rules-reminder.cjs đăng ký ở UserPromptSubmit, chèn nội dung quy tắc vào mỗi prompt. Ở đây cần tách rõ hai lớp: hook là cơ chế chèn ngữ cảnh, còn quy tắc trong CLAUDE.md là nội dung được chèn. Ở bản này, mỗi cặp (sessionId, baseDir) chỉ được chèn lại sau 5 phút (TTL) để tránh đốt token.
| File | Chống lại | Đặc trưng |
|---|---|---|
review-audit-self-decision | Lượt audit đảo ngược quyết định đã xác nhận | Quyết định đã kiểm thì giữ nguyên |
development-rules | Bỏ test, dữ liệu giả | YAGNI, KISS, DRY |
team-coordination-rules | Hai agent cùng sửa một chỗ | Phân quyền sở hữu theo glob |
commit-messages | Thân commit dài dòng | Một dòng |
orchestration-protocol | Truyền nguyên lịch sử hội thoại | Cô lập ngữ cảnh |
Quy tắc là chữ trong ngữ cảnh, không phải code. Claude có thể lệch nếu prompt của người dùng đè lên. Bù lại, thêm hay sửa rất dễ. Lớp này hợp với quy ước phong cách hơn là với lớp bảo vệ bảo mật.
Guard skill: lớp chặn do người dùng gọi
Những skill dưới đây chỉ chạy khi bạn gọi tới:
| Skill | Khi dùng | Bắt được gì |
|---|---|---|
ak-security | Trước khi phát hành | Secret, lỗ hổng đã công bố CVE (Common Vulnerabilities and Exposures), SQL injection (SQLi), cross-site scripting (XSS), path traversal |
ak-predict | Trước một tính năng rủi ro | Nhiều persona tranh luận, kết luận GO, CAUTION hoặc STOP |
ak-scenario | Trước khi triển khai | Dò trường hợp biên theo nhiều chiều |
ak-ship | Trước khi mở PR | Dừng khi test lỗi, không bao giờ force-push |
Agent code-reviewer chạy một checklist gồm: xử lý đồng thời, ranh giới lỗi, hợp đồng API (Application Programming Interface), tương thích ngược, kiểm tra đầu vào, xác thực và phân quyền, truy vấn N+1, rò rỉ dữ liệu, kiểm chứng dữ kiện. Đây là lớp chặn cuối trước khi merge.
Các chỗ hở đã biết
Đừng hiểu nhầm guardrail. Đây là các chỗ hở mình đã ghi nhận trên bản cấu hình ở trên:
- Lớp chặn truy cập file nằm ở hook. Bản cài mới dựa vào
scout-blockvàprivacy-block, không có danh sáchpermissions.denyriêng cho secret hay thư mục nặng. - Bash được miễn
privacy-block. Chỉ cảnh báo, không đi qua bước phê duyệt. workflow-artifact-gatephải tự bật. Gate mạnh nhất không chạy nếu chưa bật.simplify-gatemặc định chưa chặn. Cần bật rõ.simplify-gatetrượt theo cách viết."ship on Friday"được cho qua..ckignorecó thể phủ địnhnode_modules. Hãy kiểm trực tiếp.- Quy tắc là lời dặn. Claude có thể lệch.
- Khối HARD-GATE XML cũng là lời dặn. Nó còn có điều khoản "User override".
Ngoài ra, không có lớp chặn nào giới hạn số lần gọi hay hạn mức. Agent mất kiểm soát có thể gọi hàng nghìn lần Read, Glob, Bash. Hook của AgentKit không đếm số tool call và không tự dừng khi gần hết hạn mức. Giới hạn về hạn mức và chi phí nằm ở Claude Code, nhà cung cấp model hoặc tài khoản thanh toán, không nằm ở lớp guardrail này.
Nên làm và dễ nhầm
Phần này gom các thói quen mình thấy đáng giữ sau khi đọc kỹ bộ hook, cùng những chỗ người dùng hay hiểu sai.
| Chủ đề | Nên làm | Dễ nhầm |
|---|---|---|
| Cấu hình | Đọc cả settings.json và .ck.json sau khi cài. | Sửa cấu hình toàn cục mà tưởng đang sửa cấu hình của repo. |
simplify-gate | Muốn chặn thật thì đặt gate.enabled = true. | Tưởng nó đang chặn, trong khi mặc định chưa bật chế độ chặn. |
| Hook lỗi | Kiểm stderr xem có hook nào crash âm thầm không. | Tưởng hook lỗi thì tool bị chặn; thực tế hook lỗi thường cho qua. |
| Quy tắc trong prompt | Tưởng quy tắc trong prompt cũng chặn được như hook bằng code. | |
| Secret | Khi được hỏi phê duyệt đọc .env, đọc kỹ, đừng đồng ý theo phản xạ. | Secret đã vào commit rồi mới trông vào privacy-block. |
workflow-artifact-gate | Bật cho repo phát hành lên production. | |
node_modules | Cần đọc thì ghi đè bằng .ckignore của dự án. |
Sáu câu hỏi trước khi tin guardrail
settings.jsonđang gắn hook nào vào sự kiện nào?.ck.jsonđã tắt hook nào, ở cả cấu hình ngoài và cấu hình con?- Session Claude Code hiện tại có đang bỏ qua hộp hỏi quyền không?
- Có
.ckignorecủa dự án ghi đè không?node_modulescó bị mở bằng dấu!không? - Các file quy tắc trong
CLAUDE.mdcó đủ không? - Có hook nào crash âm thầm trong session này không (kiểm stderr)?
Thuật ngữ nhanh
| Thuật ngữ | Nghĩa gọn |
|---|---|
| Harness | Lớp điều phối giữa model và máy: gửi lệnh tool, quản quyền, chạy hook. Là chỗ gắn guardrail. |
| Hook | Script nhỏ harness tự gọi ở thời điểm cố định trong vòng đời prompt, tool hay session để xen vào kiểm tra hoặc ghi trạng thái. |
| Sự kiện vòng đời | Các mốc hook được gọi: UserPromptSubmit (nhận prompt), PreToolUse (trước tool), PostToolUse (sau tool), Stop và SubagentStop (kết thúc session hoặc subagent). |
| Exit code | Con số một tiến trình trả về khi kết thúc. 0 cho qua, 2 chặn, 1 báo lỗi nhưng không chặn. |
| Fail-open | Khi hook lỗi hoặc crash, harness cho tool chạy tiếp thay vì chặn. Lớp chặn tắt âm thầm. |
| Transcript | Toàn bộ bản ghi hội thoại giữa người dùng và agent trong một session. |
| Ngữ cảnh | Vùng thông tin model "thấy" khi suy luận. Đầy file rác thì tốn chi phí và chất lượng giảm. |
| Glob | Mẫu khớp đường dẫn. **/*.ts là mọi file .ts ở mọi thư mục con. |
| Secret | Thông tin nhạy cảm như khoá API, khoá riêng (private key), thông tin đăng nhập. Lộ vào bản ghi hội thoại là rủi ro. |
| LOC | Lines of code, số dòng code, dùng để đo độ lớn của diff. |
| Artifact | File JSON mỗi giai đoạn của pipeline để lại, ghi quyết định để giai đoạn sau kiểm tra. |
Đọc đúng lớp, tin đúng mức
Khi agent có quyền rộng, đừng kết luận "đã cài AgentKit là an toàn". Trước khi tin guardrail, kiểm hai nơi: settings.json đang gắn hook nào, .ck.json đang bật tắt gì.
Mỗi lớp bảo vệ một kiểu rủi ro: hook chặn tool call, quy tắc nhắc hành vi, hard-gate giữ quy trình, guard skill chỉ chạy khi được gọi. Biết lớp nào đang chạy và lớp nào chỉ là lời dặn giúp bạn kiểm đúng chỗ, trước khi lỗi lọt vào PR rồi đi tiếp lên production.
Nếu bạn đang tự dựng hệ thống guardrail, có thể tham khảo các mẫu đã dùng trong AgentKit. Nếu muốn dùng luôn bộ hook, skill và workflow guardrail thay vì tự ghép từng mảnh, bạn có thể xem AgentKit. Như đã nói ở đầu bài, mình là maintainer của AgentKit; nếu bạn mua qua link giới thiệu này, mình nhận hoa hồng.
Đọc tiếp: Fable 5 và bài toán unknowns cho thấy các chốt kiểm này đứng ở đâu trong một pipeline thật, từ lập kế hoạch tới phát hành.
Dùng bài này trong agent của bạn
Lấy API keyChép đoạn dưới, dán vào Claude Code, Codex hay agent bạn đang dùng. Agent đọc bài rồi đối chiếu với repo đang mở.
Đọc bài "Guardrail trong Claude Code và AgentKit (2/2): từng lớp chặn, chỗ hở và cách dùng" trên modernEngineer rồi áp dụng vào repo này.
1. Gọi tool content_get của MCP server modernengineer với locale "vi", slug "guard-rails-claude-code-agentkit-2-guard-layers". Nếu chưa nối MCP hoặc bị từ chối quyền, đọc thẳng trang https://modernengineer.dev/vi/library/guard-rails-claude-code-agentkit-2-guard-layers.
2. Tóm tắt các bước chính của bài, chỉ ra bước nào áp dụng được cho repo này.
3. Đề xuất thay đổi cụ thể và hỏi tôi trước khi sửa file.Nối MCP cho Claude Code (một lần)
claude mcp add --transport http modernengineer \
https://api.modernengineer.dev/mcp \
--header "Authorization: Bearer <API key>"Bài mở cho mọi người: chưa nối MCP thì agent vẫn đọc được thẳng từ link bài.
- Phiên bản
- v1.0.0
- Cập nhật
- 09/06/2026
- Giấy phép
- Bảo lưu mọi quyền
- Slug
- guard-rails-claude-code-agentkit-2-guard-layers


