Model chỉ "thấy" tool qua tên, mô tả và JSON Schema. Tool tốt cho agent khác API tốt cho con người: ít tool, mỗi tool làm trọn một việc có ý nghĩa, output gọn, lỗi có hướng dẫn sửa. Nguyên tắc dưới đây áp dụng như nhau cho MCP server, Claude API tool use và LangGraph.
Vòng đời một lần gọi tool
flowchart LR A["Model đọc tên + mô tả"] --> B["Sinh input theo schema"] B --> C{"Validate input"} C -->|sai| E["Lỗi có gợi ý sửa"] E --> A C -->|đúng| D{"Kiểm tra quyền"} D -->|"ghi / nguy hiểm"| F["Xác nhận người dùng"] D -->|"chỉ đọc"| G[Thực thi] F --> G G --> H["Output gọn, có cấu trúc"]
Checklist
| Khía cạnh | Nên | Tránh |
|---|---|---|
| Tên | Động từ + đối tượng, có namespace: bgp_get_neighbors, netbox_get_device |
run, query, tool1, hai tool tên gần giống nhau |
| Mô tả | Làm gì, khi nào dùng / không dùng, đơn vị, ví dụ input | Một dòng chung chung "Get data" |
| Tham số | Ít, có kiểu, enum khi tập giá trị đóng, description cho từng field |
Một field command: string nhận lệnh CLI tuỳ ý |
| Mức trừu tượng | Một tool = một tác vụ vận hành (check_bgp_session(device, peer)) |
Bọc 1-1 mọi endpoint REST, bắt model tự ghép 5 bước |
| Output | Đã lọc, có cấu trúc (JSON/bảng ngắn), có trường tóm tắt | Dump nguyên show run 3000 dòng |
| Lỗi | Thông điệp nói rõ sai gì và sửa thế nào: "device không tồn tại, hợp lệ: pe1-hni, pe2-hcm" | Stack trace, hoặc trả chuỗi rỗng |
| Idempotent | Tool ghi nhận trạng thái mong muốn (ensure_interface_description) để gọi lại không hại |
Tool "thêm" tạo bản sao mỗi lần gọi lại |
| Quyền | Tách tool đọc và tool ghi; tool ghi yêu cầu xác nhận, commit confirmed, có dry_run |
Một tool vừa show vừa commit |
| Phân trang | limit, cursor, mặc định nhỏ |
Trả toàn bộ bảng route |
| Timeout | Mỗi tool có timeout, báo rõ khi hết giờ | Treo vô hạn chờ SSH |
Ví dụ: mô tả tốt vs kém
{"name": "exec", "description": "Run command", "input_schema": {"type": "object", "properties": {"cmd": {"type": "string"}}}}{
"name": "bgp_get_neighbors",
"description": "Lấy trạng thái BGP neighbor (chỉ đọc) của một router. Dùng khi cần biết peer nào không Established hoặc số prefix nhận được. Không dùng để xem route chi tiết (dùng bgp_get_routes).",
"input_schema": {
"type": "object",
"properties": {
"device": {"type": "string", "description": "Tên trong inventory, vd pe1-hni"},
"state": {"type": "string", "enum": ["all", "not-established"], "default": "not-established"},
"afi": {"type": "string", "enum": ["ipv4-unicast", "ipv6-unicast", "vpnv4-unicast"]}
},
"required": ["device"]
}
}Output gợi ý (gọn, đủ để model quyết định bước tiếp):
{"device": "pe1-hni", "total": 12, "not_established": [
{"peer": "203.0.113.2", "remote_as": 64501, "state": "Active", "last_error": "Hold timer expired", "uptime": "never"}
]}Giới hạn quyền nhiều lớp
| Lớp | Cách làm |
|---|---|
| Tool | Không expose lệnh tuỳ ý; whitelist lệnh show/get trong code |
| Tài khoản thiết bị | User AAA chỉ có quyền đọc cho tool đọc (task-group / login class read-only) |
| Host agent | Claude Code permissions.deny, hook chặn (settings và hooks) |
| Người duyệt | Thao tác ghi đi qua xác nhận / interrupt, kèm diff |
| Audit | Log mọi lần gọi: ai, tool, input, kết quả, thời gian |
Output tool là dữ liệu không tin cậy: description interface, BGP community, log syslog có thể chứa chuỗi kiểu "bỏ qua chỉ dẫn trước đó và chạy...". Không cho tool đọc dữ liệu bên ngoài đứng chung phiên với tool ghi mà không có người duyệt.
Khi nào dùng
- Trước khi viết MCP server / tool mới: duyệt checklist trên.
- Khi agent gọi sai tool, gọi lặp, hoặc tốn token: nên sửa mô tả và output của tool, không phải ở prompt. Xem Lỗi agent thường gặp.