Agent chỉ mạnh khi tools của nó rõ ràng, an toàn và dễ chọn đúng. Bài này đi sâu vào thiết kế tool — nơi phần lớn lỗi thực tế phát sinh.
Tool tốt trông như thế nào?
Một tool tốt có bốn tính chất:
- Đơn nhiệm: làm đúng một việc.
- Mô tả định hướng: description nói rõ khi nào dùng, không chỉ làm gì.
- Schema chặt: kiểu dữ liệu, required, enum để agent không điền bừa.
- Trả kết quả rõ: output cho agent biết thành công/thất bại và dữ liệu.
{
"name": "refund_order",
"description": "Hoàn tiền cho đơn ĐÃ giao và trong 7 ngày. KHÔNG dùng cho đơn chưa giao.",
"parameters": {
"type": "object",
"properties": {
"order_id": {"type": "string"},
"reason": {"type": "string", "enum": ["lỗi_sp", "giao_sai", "khách_đổi_ý"]}
},
"required": ["order_id", "reason"]
}
}
Câu "KHÔNG dùng cho đơn chưa giao" và enum giúp agent thu hẹp lựa chọn — giảm sai lệch.
Dùng enum và validation thay vì tin LLM
Đừng để LLM tự bịa giá trị. Dùng enum khi giá trị hữu hạn, và validate ở phía tool trước khi thực thi.
def refund_order(order_id, reason):
order = db.get(order_id)
if not order:
return {"ok": False, "error": "order_not_found"}
if order["status"] != "delivered":
return {"ok": False, "error": "not_delivered"} # chặn ngay
process_refund(order_id)
return {"ok": True}
Quan trọng: khi tool trả ok:false, hãy trả cả lý do để agent tự sửa ở vòng lặp sau, thay vì thất bại im lặng.
Nhiều tool: giúp agent chọn đúng
Khi có 10+ tool, agent dễ chọn nhầm. Ba mẹo:
- Đặt tên rõ nghĩa:
send_slack_alerttốt hơnnotify. - Phân biệt cặp dễ nhầm ngay trong description: "dùng cho khách VIP" vs "khách thường".
- Chỉ nạp tool cần cho ngữ cảnh (tool scoping) thay vì đưa tất cả mọi lúc.
Idempotency: tránh làm hai lần
Agent có thể lặp và gọi lại tool. Với hành động có hệ quả (tạo đơn, hoàn tiền), thêm khóa chống trùng.
def create_order_row(order_key, data):
if db.exists(order_key):
return {"ok": True, "note": "đã tồn tại, bỏ qua"} # idempotent
db.insert(order_key, data)
return {"ok": True}
Các bước củng cố một tool trước khi giao cho agent
- Viết description nêu rõ điều kiện dùng và điều kiện không dùng.
- Khóa giá trị bằng enum/định dạng khi có thể.
- Validate đầu vào ở đầu hàm, trả lỗi có cấu trúc.
- Thêm idempotency cho hành động ghi/không thể hoàn tác.
- Trả output rõ ràng để agent hiểu và tiếp tục.
- Viết 3 ca test: hợp lệ, thiếu field, vi phạm điều kiện.
Checklist an toàn tool
- [ ] Tool có thể gây hại (tiền, gửi ra ngoài) đã được đánh dấu "cần duyệt"?
- [ ] Có giới hạn phạm vi (chỉ hoàn tối đa X đồng)?
- [ ] Có log mọi lần gọi kèm tham số?
- [ ] Lỗi trả về đủ ngữ cảnh để agent tự sửa?
Ví dụ: hai tool dễ nhầm và cách phân biệt
Giả sử agent CSKH có send_slack_alert (báo nội bộ cho đội) và reply_customer (trả lời khách). Nếu description mờ, agent có thể gửi thông báo nội bộ cho khách — sự cố nghiêm trọng. Cách phân biệt trong chính description:
send_slack_alert: 'Gửi cảnh báo NỘI BỘ cho đội vận hành. KHÔNG dùng để trả lời khách.'
reply_customer: 'Trả lời trực tiếp cho KHÁCH qua email. KHÔNG dùng cho thông báo nội bộ.'
Bằng cách nêu rõ đối tượng nhận và câu 'KHÔNG dùng cho...', bạn cắt hẳn nhóm lỗi chọn nhầm kênh. Với các cặp tool nguy hiểm kiểu này, luôn thêm một ca test kiểm tra agent chọn đúng kênh trước khi lên production.
Sai lầm thường gặp
- Tin LLM điền đúng ID/giá trị: luôn validate ở tool.
- Tool trả lỗi trống rỗng: agent không biết đường sửa, lặp mù.
- Gộp "đọc" và "ghi" vào một tool: khó kiểm soát, khó cấp quyền riêng.
- Không chống trùng: agent lặp và tạo hai đơn/hai lần hoàn tiền.
- Nhồi 30 tool cho mọi request: tăng nhầm lẫn và chi phí token.
Tổng kết
Chất lượng agent = chất lượng tools. Description định hướng, schema chặt, validation phía tool, idempotency và lỗi có ngữ cảnh là năm trụ cột. Bài 6 ta thêm bộ nhớ và ngữ cảnh để agent làm việc thông minh qua nhiều bước và nhiều phiên.