{"product_id":"thiết-kế-tool-use-cho-ai-agent-nguyen-tắc-va-best-practices","title":"Thiết kế Tool Use cho AI Agent — Nguyên tắc và best practices","description":"\n\u003cp\u003eTool use (hay function calling) là khả năng cho phép AI Agent tương tác với thế giới bên ngoài — gọi API, truy vấn database, xử lý file, gửi email. Chất lượng của tool quyết định trực tiếp khả năng của Agent. Một tool được thiết kế tốt giúp Agent hoạt động chính xác và đáng tin cậy. Một tool thiết kế kém dẫn đến lỗi, hiểu sai và trải nghiệm người dùng tệ. Bài viết này trình bày các nguyên tắc thiết kế tool hiệu quả, kèm ví dụ thực tế và anti-patterns cần tránh.\u003c\/p\u003e\n\n\u003ch2\u003eNguyên tắc 1: Tên tool rõ ràng và nhất quán\u003c\/h2\u003e\n\u003cp\u003eTên tool là tín hiệu đầu tiên giúp Agent quyết định nên dùng tool nào. Tên tốt giúp Agent chọn đúng tool mà không cần đọc description chi tiết.\u003c\/p\u003e\n\n\u003ch3\u003eQuy tắc đặt tên\u003c\/h3\u003e\n\u003cul\u003e\n  \u003cli\u003e\n\u003cstrong\u003eDùng verb_noun format:\u003c\/strong\u003e get_weather, search_products, create_order, send_email. Verb cho biết hành động, noun cho biết đối tượng.\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eTránh tên mơ hồ:\u003c\/strong\u003e \"process_data\" (xử lý gì? dữ liệu gì?) hoặc \"handle\" (handle cái gì?). Thay vào đó dùng \"validate_email\", \"calculate_shipping_cost\".\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eNhất quán trong cùng bộ tool:\u003c\/strong\u003e Nếu bạn có \"get_user\", hãy dùng \"get_order\" thay vì \"fetch_order\" hoặc \"retrieve_order\". Chọn một convention và giữ nhất quán.\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eTránh viết tắt:\u003c\/strong\u003e \"calc_ship\" khó hiểu hơn \"calculate_shipping\". Agent đọc tên tool nên sự rõ ràng quan trọng hơn sự ngắn gọn.\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cpre\u003e\u003ccode\u003e\/\/ Tên tốt\n\"get_customer_by_id\"\n\"search_products\"\n\"create_invoice\"\n\"cancel_subscription\"\n\"list_recent_transactions\"\n\n\/\/ Tên kém\n\"data\"           \/\/ Quá mơ hồ\n\"doStuff\"        \/\/ Không rõ làm gì\n\"helper\"         \/\/ Không mô tả chức năng\n\"process\"        \/\/ Quá chung chung\n\"customerAPI\"    \/\/ Không rõ hành động\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eNguyên tắc 2: Mô tả (Description) chính xác\u003c\/h2\u003e\n\u003cp\u003eDescription là thông tin quan trọng nhất giúp Agent hiểu khi nào nên dùng tool và kỳ vọng kết quả gì. Một description tốt cần ba phần:\u003c\/p\u003e\n\u003col\u003e\n  \u003cli\u003e\n\u003cstrong\u003eChức năng:\u003c\/strong\u003e Tool làm gì, bằng một câu ngắn gọn\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eKhi nào dùng:\u003c\/strong\u003e Tình huống nào nên dùng tool này (và không nên dùng)\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eKết quả trả về:\u003c\/strong\u003e Format và nội dung kết quả\u003c\/li\u003e\n\u003c\/ol\u003e\n\n\u003cpre\u003e\u003ccode\u003e\/\/ Description tốt\n{\n  \"name\": \"search_products\",\n  \"description\": \"Tìm kiếm sản phẩm trong catalog theo từ khóa, danh mục hoặc khoảng giá. Trả về danh sách tối đa 20 sản phẩm phù hợp nhất, sắp xếp theo độ liên quan. Dùng tool này khi người dùng hỏi về sản phẩm, muốn so sánh hoặc tìm mua hàng. KHÔNG dùng cho tra cứu đơn hàng — dùng get_order cho việc đó.\"\n}\n\n\/\/ Description kém\n{\n  \"name\": \"search_products\",\n  \"description\": \"Tìm sản phẩm\"\n  \/\/ Quá ngắn: không biết tìm theo tiêu chí gì, trả về gì\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eNguyên tắc 3: Schema chặt chẽ với validation\u003c\/h2\u003e\n\u003cp\u003eInput schema định nghĩa chính xác những gì tool chấp nhận. Schema tốt giúp Agent truyền đúng tham số và giảm lỗi runtime.\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003e\/\/ Schema tốt — chi tiết, có constraint và description cho từng field\n{\n  \"name\": \"search_products\",\n  \"input_schema\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"query\": {\n        \"type\": \"string\",\n        \"description\": \"Từ khóa tìm kiếm. Có thể là tên sản phẩm, thương hiệu hoặc mô tả.\",\n        \"minLength\": 1,\n        \"maxLength\": 200\n      },\n      \"category\": {\n        \"type\": \"string\",\n        \"description\": \"Danh mục sản phẩm. Để trống nếu muốn tìm tất cả danh mục.\",\n        \"enum\": [\"electronics\", \"clothing\", \"food\", \"home\", \"beauty\"]\n      },\n      \"min_price\": {\n        \"type\": \"number\",\n        \"description\": \"Giá tối thiểu (VND). Mặc định 0.\",\n        \"minimum\": 0\n      },\n      \"max_price\": {\n        \"type\": \"number\",\n        \"description\": \"Giá tối đa (VND). Mặc định không giới hạn.\",\n        \"minimum\": 0\n      },\n      \"sort_by\": {\n        \"type\": \"string\",\n        \"description\": \"Tiêu chí sắp xếp kết quả\",\n        \"enum\": [\"relevance\", \"price_asc\", \"price_desc\", \"rating\", \"newest\"],\n        \"default\": \"relevance\"\n      },\n      \"limit\": {\n        \"type\": \"integer\",\n        \"description\": \"Số kết quả tối đa trả về\",\n        \"minimum\": 1,\n        \"maximum\": 50,\n        \"default\": 20\n      }\n    },\n    \"required\": [\"query\"]\n  }\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eLưu ý quan trọng về schema\u003c\/h3\u003e\n\u003cul\u003e\n  \u003cli\u003e\n\u003cstrong\u003eMô tả rõ từng field:\u003c\/strong\u003e Agent đọc description để biết nên truyền giá trị gì. Field không có description dễ bị truyền sai.\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eDùng enum khi có giá trị cố định:\u003c\/strong\u003e Thay vì cho phép string tự do, liệt kê các giá trị hợp lệ giúp Agent chọn đúng.\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eĐặt default cho tham số tùy chọn:\u003c\/strong\u003e Agent không cần truyền giá trị cho mọi field.\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003ePhân biệt required vs optional:\u003c\/strong\u003e Chỉ required những field thật sự cần thiết. Càng ít required, Agent càng dễ sử dụng tool.\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch2\u003eNguyên tắc 4: Xử lý lỗi rõ ràng\u003c\/h2\u003e\n\u003cp\u003eAgent cần hiểu tại sao tool thất bại để quyết định hành động tiếp theo: thử lại, hỏi thêm thông tin, hoặc báo lỗi cho người dùng.\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003e\/\/ Xử lý lỗi tốt — trả về thông tin đủ để Agent xử lý\nfunction handleToolError(error) {\n  \/\/ Phân loại lỗi\n  if (error.code === \"NOT_FOUND\") {\n    return {\n      is_error: true,\n      content: [{\n        type: \"text\",\n        text: JSON.stringify({\n          error_type: \"not_found\",\n          message: \"Không tìm thấy sản phẩm với ID này.\",\n          suggestion: \"Kiểm tra lại ID hoặc dùng search_products để tìm kiếm.\"\n        })\n      }]\n    };\n  }\n\n  if (error.code === \"VALIDATION_ERROR\") {\n    return {\n      is_error: true,\n      content: [{\n        type: \"text\",\n        text: JSON.stringify({\n          error_type: \"validation\",\n          message: \"Tham số không hợp lệ: \" + error.details,\n          invalid_fields: error.fields,\n          suggestion: \"Kiểm tra lại giá trị các tham số.\"\n        })\n      }]\n    };\n  }\n\n  if (error.code === \"RATE_LIMIT\") {\n    return {\n      is_error: true,\n      content: [{\n        type: \"text\",\n        text: JSON.stringify({\n          error_type: \"rate_limit\",\n          message: \"Đã vượt giới hạn số request.\",\n          retry_after_seconds: error.retryAfter,\n          suggestion: \"Đợi \" + error.retryAfter + \" giây rồi thử lại.\"\n        })\n      }]\n    };\n  }\n\n  \/\/ Lỗi không xác định\n  return {\n    is_error: true,\n    content: [{\n      type: \"text\",\n      text: JSON.stringify({\n        error_type: \"internal\",\n        message: \"Lỗi hệ thống. Vui lòng thử lại sau.\",\n        suggestion: \"Nếu lỗi tiếp tục, hãy báo cho quản trị viên.\"\n      })\n    }]\n  };\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eCác nguyên tắc xử lý lỗi\u003c\/h3\u003e\n\u003cul\u003e\n  \u003cli\u003e\n\u003cstrong\u003ePhân loại lỗi:\u003c\/strong\u003e Agent cần biết đây là lỗi input (có thể sửa) hay lỗi hệ thống (cần thử lại hoặc bỏ qua)\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eĐề xuất hành động:\u003c\/strong\u003e Kèm gợi ý để Agent biết làm gì tiếp theo\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eKhông expose thông tin nhạy cảm:\u003c\/strong\u003e Stack trace, connection string, internal path không nên xuất hiện trong error message trả về Agent\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eRetry guidance:\u003c\/strong\u003e Với lỗi tạm thời (rate limit, timeout), cho biết khi nào nên thử lại\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch2\u003eNguyên tắc 5: Khi nào expose tool vs ẩn complexity\u003c\/h2\u003e\n\u003cp\u003eKhông phải mọi thao tác đều nên là một tool riêng. Cần cân bằng giữa tính linh hoạt (nhiều tool nhỏ) và tính đơn giản (ít tool, mỗi tool làm nhiều việc).\u003c\/p\u003e\n\n\u003ch3\u003eNên expose thành tool riêng khi:\u003c\/h3\u003e\n\u003cul\u003e\n  \u003cli\u003eAgent cần quyết định có dùng hay không tùy ngữ cảnh\u003c\/li\u003e\n  \u003cli\u003eThao tác có input\/output rõ ràng và độc lập\u003c\/li\u003e\n  \u003cli\u003eNgười dùng có thể yêu cầu trực tiếp (ví dụ: \"gửi email\", \"tìm sản phẩm\")\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch3\u003eNên ẩn (abstract) bên trong tool khi:\u003c\/h3\u003e\n\u003cul\u003e\n  \u003cli\u003eCác bước luôn thực hiện cùng nhau theo thứ tự cố định\u003c\/li\u003e\n  \u003cli\u003eAgent không cần biết chi tiết implementation\u003c\/li\u003e\n  \u003cli\u003eExpose quá nhiều bước nhỏ khiến Agent khó điều phối\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cpre\u003e\u003ccode\u003e\/\/ Ví dụ: Tạo hóa đơn\n\n\/\/ Cách 1: Quá nhiều tool nhỏ (KHÔnG NÊN)\n\/\/ Agent phải gọi tuần tự: validate_customer -\u0026gt; calculate_tax\n\/\/ -\u0026gt; generate_invoice_number -\u0026gt; create_invoice_record\n\/\/ -\u0026gt; send_invoice_email\n\/\/ =\u0026gt; Quá phức tạp, dễ sai thứ tự, dễ bỏ sót bước\n\n\/\/ Cách 2: Một tool gộp mọi thứ (cũng KHÔNG NÊN)\n\/\/ create_and_send_invoice: tạo + gửi luôn, không cho phép\n\/\/ tạo mà không gửi\n\/\/ =\u0026gt; Thiếu linh hoạt\n\n\/\/ Cách 3: Cân bằng (NÊN)\n\/\/ create_invoice: validate, calculate, generate, save (gộp logic nội bộ)\n\/\/ send_invoice: gửi hóa đơn đã tạo qua email\n\/\/ =\u0026gt; Agent quyết định tạo xong có gửi ngay hay không\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eTool Composition Patterns\u003c\/h2\u003e\n\u003cp\u003eKhi Agent cần kết hợp nhiều tool, có các pattern phổ biến:\u003c\/p\u003e\n\n\u003ch3\u003ePattern 1: Sequential (Tuần tự)\u003c\/h3\u003e\n\u003cp\u003eOutput của tool A là input của tool B.\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e\/\/ Ví dụ: Tìm khách hàng rồi lấy đơn hàng\n\/\/ Bước 1: search_customers(\"Nguyen Van A\") -\u0026gt; customer_id: 123\n\/\/ Bước 2: get_orders(customer_id: 123) -\u0026gt; danh sách đơn hàng\n\/\/ Agent tự quyết định truyền customer_id từ bước 1 sang bước 2\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003ePattern 2: Conditional (Có điều kiện)\u003c\/h3\u003e\n\u003cp\u003eDựa trên kết quả tool A, Agent quyết định gọi tool B hay tool C.\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e\/\/ Ví dụ: Kiểm tra tồn kho rồi xử lý đơn\n\/\/ Bước 1: check_inventory(product_id: \"SKU001\") -\u0026gt; in_stock: true\/false\n\/\/ Nếu true -\u0026gt; create_order(...)\n\/\/ Nếu false -\u0026gt; find_alternative_products(...) hoặc notify_restock(...)\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003ePattern 3: Parallel (Song song)\u003c\/h3\u003e\n\u003cp\u003eClaude hỗ trợ gọi nhiều tool cùng lúc khi các tool không phụ thuộc nhau.\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e\/\/ Ví dụ: Lấy thông tin tổng hợp cho dashboard\n\/\/ Gọi đồng thời:\n\/\/ - get_sales_summary(period: \"today\")\n\/\/ - get_active_orders_count()\n\/\/ - get_low_stock_alerts()\n\/\/ Agent tổng hợp kết quả từ cả 3 tool để trả lời\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003ePattern 4: Iterative (Lặp)\u003c\/h3\u003e\n\u003cp\u003eAgent lặp lại tool call cho đến khi đạt kết quả mong muốn hoặc hết dữ liệu.\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e\/\/ Ví dụ: Phân trang kết quả tìm kiếm\n\/\/ Lần 1: search_products(query: \"laptop\", page: 1) -\u0026gt; 20 results, has_more: true\n\/\/ Lần 2: search_products(query: \"laptop\", page: 2) -\u0026gt; 15 results, has_more: false\n\/\/ Agent dừng khi has_more = false hoặc đã đủ thông tin\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003e5 ví dụ tool được thiết kế tốt\u003c\/h2\u003e\n\n\u003ch3\u003eTool 1: Tra cứu thời tiết\u003c\/h3\u003e\n\u003cpre\u003e\u003ccode\u003e{\n  \"name\": \"get_weather\",\n  \"description\": \"Lấy thông tin thời tiết hiện tại và dự báo 5 ngày cho một địa điểm. Trả về nhiệt độ, độ ẩm, mô tả thời tiết và dự báo. Dùng khi người dùng hỏi về thời tiết tại một nơi cụ thể.\",\n  \"input_schema\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"location\": {\n        \"type\": \"string\",\n        \"description\": \"Tên thành phố hoặc địa điểm (ví dụ: 'Ha Noi', 'Ho Chi Minh City')\"\n      },\n      \"units\": {\n        \"type\": \"string\",\n        \"enum\": [\"celsius\", \"fahrenheit\"],\n        \"default\": \"celsius\",\n        \"description\": \"Đơn vị nhiệt độ\"\n      }\n    },\n    \"required\": [\"location\"]\n  }\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eTool 2: Gửi email\u003c\/h3\u003e\n\u003cpre\u003e\u003ccode\u003e{\n  \"name\": \"send_email\",\n  \"description\": \"Gửi email đến một hoặc nhiều người nhận. Hỗ trợ plain text và HTML. Trả về message_id nếu gửi thành công. CHÚ Ý: Luôn xác nhận với người dùng trước khi gửi — không gửi tự động.\",\n  \"input_schema\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"to\": {\n        \"type\": \"array\",\n        \"items\": { \"type\": \"string\", \"format\": \"email\" },\n        \"description\": \"Danh sách email người nhận\",\n        \"minItems\": 1,\n        \"maxItems\": 50\n      },\n      \"subject\": {\n        \"type\": \"string\",\n        \"description\": \"Tiêu đề email\",\n        \"maxLength\": 200\n      },\n      \"body\": {\n        \"type\": \"string\",\n        \"description\": \"Nội dung email (plain text)\"\n      },\n      \"html_body\": {\n        \"type\": \"string\",\n        \"description\": \"Nội dung email HTML (tùy chọn, ưu tiên hơn body nếu có)\"\n      }\n    },\n    \"required\": [\"to\", \"subject\", \"body\"]\n  }\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eTool 3: Tìm kiếm tài liệu nội bộ\u003c\/h3\u003e\n\u003cpre\u003e\u003ccode\u003e{\n  \"name\": \"search_knowledge_base\",\n  \"description\": \"Tìm kiếm trong kho tài liệu nội bộ bằng semantic search. Trả về top 5 tài liệu liên quan nhất kèm đoạn trích phù hợp. Dùng khi người dùng hỏi về quy trình, chính sách, hoặc thông tin nội bộ công ty.\",\n  \"input_schema\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"query\": {\n        \"type\": \"string\",\n        \"description\": \"Câu hỏi hoặc từ khóa tìm kiếm\",\n        \"minLength\": 3\n      },\n      \"department\": {\n        \"type\": \"string\",\n        \"enum\": [\"hr\", \"engineering\", \"sales\", \"finance\", \"all\"],\n        \"default\": \"all\",\n        \"description\": \"Lọc theo phòng ban\"\n      },\n      \"doc_type\": {\n        \"type\": \"string\",\n        \"enum\": [\"policy\", \"procedure\", \"guide\", \"faq\", \"all\"],\n        \"default\": \"all\",\n        \"description\": \"Lọc theo loại tài liệu\"\n      }\n    },\n    \"required\": [\"query\"]\n  }\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eTool 4: Tạo task trong project management\u003c\/h3\u003e\n\u003cpre\u003e\u003ccode\u003e{\n  \"name\": \"create_task\",\n  \"description\": \"Tạo task mới trong hệ thống quản lý dự án. Trả về task_id và URL. Dùng khi người dùng muốn tạo việc cần làm, bug report, hoặc feature request. Yêu cầu xác nhận title và assignee trước khi tạo.\",\n  \"input_schema\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"title\": {\n        \"type\": \"string\",\n        \"description\": \"Tiêu đề task, ngắn gọn và rõ ràng\",\n        \"maxLength\": 200\n      },\n      \"description\": {\n        \"type\": \"string\",\n        \"description\": \"Mô tả chi tiết task\"\n      },\n      \"assignee\": {\n        \"type\": \"string\",\n        \"description\": \"Username người được giao task\"\n      },\n      \"priority\": {\n        \"type\": \"string\",\n        \"enum\": [\"low\", \"medium\", \"high\", \"urgent\"],\n        \"default\": \"medium\"\n      },\n      \"due_date\": {\n        \"type\": \"string\",\n        \"format\": \"date\",\n        \"description\": \"Ngày deadline (YYYY-MM-DD)\"\n      },\n      \"labels\": {\n        \"type\": \"array\",\n        \"items\": { \"type\": \"string\" },\n        \"description\": \"Danh sách nhãn (bug, feature, improvement...)\"\n      }\n    },\n    \"required\": [\"title\"]\n  }\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eTool 5: Chuyển đổi tiền tệ\u003c\/h3\u003e\n\u003cpre\u003e\u003ccode\u003e{\n  \"name\": \"convert_currency\",\n  \"description\": \"Chuyển đổi giữa các loại tiền tệ theo tỷ giá hiện tại. Trả về số tiền đã chuyển đổi và tỷ giá áp dụng. Tỷ giá được cập nhật mỗi giờ, không phải real-time. Dùng khi người dùng hỏi về quy đổi tiền hoặc so sánh giá quốc tế.\",\n  \"input_schema\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"amount\": {\n        \"type\": \"number\",\n        \"description\": \"Số tiền cần chuyển đổi\",\n        \"minimum\": 0,\n        \"exclusiveMinimum\": true\n      },\n      \"from_currency\": {\n        \"type\": \"string\",\n        \"description\": \"Mã tiền tệ nguồn (ISO 4217)\",\n        \"pattern\": \"^[A-Z]{3}$\"\n      },\n      \"to_currency\": {\n        \"type\": \"string\",\n        \"description\": \"Mã tiền tệ đích (ISO 4217)\",\n        \"pattern\": \"^[A-Z]{3}$\"\n      }\n    },\n    \"required\": [\"amount\", \"from_currency\", \"to_currency\"]\n  }\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eAnti-patterns cần tránh\u003c\/h2\u003e\n\n\u003ch3\u003eAnti-pattern 1: Tool \"thùng rác\" (Kitchen Sink Tool)\u003c\/h3\u003e\n\u003cp\u003eMột tool làm quá nhiều việc không liên quan. Agent khó biết khi nào nên dùng và truyền tham số gì.\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e\/\/ KHÔNG NÊN: Tool làm mọi thứ\n{\n  \"name\": \"manage_customer\",\n  \"description\": \"Tạo, cập nhật, xóa, tìm kiếm khách hàng, xem đơn hàng, gửi email...\"\n  \/\/ Agent sẽ confused: truyền tham số cho create hay search hay delete?\n}\n\n\/\/ NÊN: Tách thành các tool riêng biệt\n\"create_customer\", \"search_customers\", \"get_customer\",\n\"update_customer\", \"delete_customer\"\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eAnti-pattern 2: Thiếu description cho tham số\u003c\/h3\u003e\n\u003cpre\u003e\u003ccode\u003e\/\/ KHÔNG NÊN\n{\n  \"properties\": {\n    \"type\": { \"type\": \"string\" },\n    \"status\": { \"type\": \"integer\" },\n    \"flag\": { \"type\": \"boolean\" }\n  }\n}\n\/\/ Agent: \"type\" là type gì? \"status\" 0 hay 1 nghĩa là gì? \"flag\" bật nghĩa là sao?\n\n\/\/ NÊN\n{\n  \"properties\": {\n    \"order_type\": {\n      \"type\": \"string\",\n      \"enum\": [\"standard\", \"express\", \"same_day\"],\n      \"description\": \"Loại giao hàng\"\n    },\n    \"payment_status\": {\n      \"type\": \"string\",\n      \"enum\": [\"pending\", \"paid\", \"refunded\"],\n      \"description\": \"Trạng thái thanh toán đơn hàng\"\n    },\n    \"include_cancelled\": {\n      \"type\": \"boolean\",\n      \"default\": false,\n      \"description\": \"Có bao gồm đơn đã hủy trong kết quả không\"\n    }\n  }\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eAnti-pattern 3: Không xử lý lỗi\u003c\/h3\u003e\n\u003cpre\u003e\u003ccode\u003e\/\/ KHÔNG NÊN: throw hoặc trả về lỗi không rõ ràng\n\/\/ Tool crash -\u0026gt; Agent không biết chuyện gì xảy ra\n\n\/\/ NÊN: Luôn trả về response có cấu trúc, kể cả khi lỗi\n\/\/ { is_error: true, content: [{ type: \"text\", text: \"...\" }] }\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eAnti-pattern 4: Side effects không thông báo\u003c\/h3\u003e\n\u003cpre\u003e\u003ccode\u003e\/\/ KHÔNG NÊN: Tool \"get\" nhưng lại modify dữ liệu\n{\n  \"name\": \"get_report\",\n  \"description\": \"Lấy báo cáo\"\n  \/\/ Nhưng thực tế tool này tạo mới report mỗi lần gọi,\n  \/\/ tốn tài nguyên và tạo dữ liệu trùng lặp\n}\n\n\/\/ NÊN: Tên và description phản ánh đúng hành vi\n{\n  \"name\": \"generate_report\",\n  \"description\": \"Tạo báo cáo mới. Mỗi lần gọi tạo một bản mới. Dùng get_report nếu muốn lấy báo cáo đã tạo.\"\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eAnti-pattern 5: Quá nhiều tool tương tự\u003c\/h3\u003e\n\u003cpre\u003e\u003ccode\u003e\/\/ KHÔNG NÊN: 10 tool search khác nhau\n\"search_by_name\", \"search_by_email\", \"search_by_phone\",\n\"search_by_id\", \"search_by_date\", ...\n\/\/ Agent sẽ confused dùng tool nào\n\n\/\/ NÊN: 1 tool search linh hoạt\n{\n  \"name\": \"search_customers\",\n  \"input_schema\": {\n    \"properties\": {\n      \"query\": { \"type\": \"string\", \"description\": \"Tìm theo tên, email hoặc SĐT\" },\n      \"customer_id\": { \"type\": \"string\", \"description\": \"Tìm chính xác theo ID\" },\n      \"date_range\": { \"type\": \"object\", \"description\": \"Lọc theo ngày tạo\" }\n    }\n  }\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eTesting tool\u003c\/h2\u003e\n\u003cp\u003eTool cần được test kỹ trước khi đưa vào Agent. Các loại test cần có:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003e\/\/ Test framework cho tool\ndescribe(\"search_products\", () =\u0026gt; {\n  \/\/ Test input validation\n  test(\"reject empty query\", async () =\u0026gt; {\n    const result = await searchProducts({ query: \"\" });\n    expect(result.is_error).toBe(true);\n    expect(result.content[0].text).toContain(\"query must not be empty\");\n  });\n\n  \/\/ Test kết quả bình thường\n  test(\"return matching products\", async () =\u0026gt; {\n    const result = await searchProducts({ query: \"laptop\" });\n    const data = JSON.parse(result.content[0].text);\n    expect(data.products.length).toBeGreaterThan(0);\n    expect(data.products.length).toBeLessThanOrEqual(20);\n  });\n\n  \/\/ Test không tìm thấy\n  test(\"return empty for no matches\", async () =\u0026gt; {\n    const result = await searchProducts({ query: \"xyznonexistent123\" });\n    const data = JSON.parse(result.content[0].text);\n    expect(data.products.length).toBe(0);\n    expect(data.message).toContain(\"Không tìm thấy\");\n  });\n\n  \/\/ Test edge cases\n  test(\"handle special characters\", async () =\u0026gt; {\n    const result = await searchProducts({ query: \"laptop \u003cscript\u003e\" });\n    expect(result.is_error).not.toBe(true);\n  });\n\n  \/\/ Test rate limiting\n  test(\"respect rate limits\", async () =\u003e {\n    const promises = Array(20).fill().map(() =\u003e\n      searchProducts({ query: \"test\" })\n    );\n    const results = await Promise.all(promises);\n    const rateLimited = results.filter(r =\u003e\n      r.is_error \u0026\u0026 JSON.parse(r.content[0].text).error_type === \"rate_limit\"\n    );\n    expect(rateLimited.length).toBeGreaterThan(0);\n  });\n});\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eTest với Agent thực tế\u003c\/h3\u003e\n\u003cp\u003eNgoài unit test, hãy test tool trong ngữ cảnh Agent thực tế. Cho Claude các câu hỏi đa dạng và kiểm tra xem Claude có chọn đúng tool, truyền đúng tham số và xử lý kết quả hợp lý không.\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003eCác kịch bản test cần thực hiện:\n\n1. Happy path: Câu hỏi rõ ràng, tool hoạt động bình thường\n2. Ambiguous: Câu hỏi mơ hồ, Agent cần hỏi lại hoặc chọn tool phù hợp\n3. Tool error: Tool trả về lỗi, Agent cần xử lý gracefully\n4. Wrong tool: Agent có chọn đúng tool không khi có nhiều tool tương tự?\n5. Multi-tool: Agent có phối hợp nhiều tool đúng thứ tự không?\n6. Edge case: Input đặc biệt (số âm, chuỗi rỗng, Unicode, emoji)\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eBước tiếp theo\u003c\/h2\u003e\n\u003cp\u003eThiết kế tool tốt là nền tảng cho Agent đáng tin cậy. Hãy bắt đầu với ít tool, thiết kế kỹ lưỡng từng tool, test cả unit lẫn integration với Agent thực tế. Khi hệ thống tool lớn lên, áp dụng các composition pattern và monitoring để duy trì chất lượng. Tham khảo thêm tại \u003ca href=\"\/collections\/nang-cao\"\u003eThư viện Nâng cao Claude\u003c\/a\u003e.\u003c\/p\u003e\n\u003c\/script\u003e\u003c\/code\u003e\u003c\/pre\u003e","brand":"Minh Tuấn","offers":[{"title":"Default Title","offer_id":66959058141229,"sku":null,"price":0.0,"currency_code":"VND","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0763\/9531\/5245\/files\/thi_t-k_-tool-use-cho-ai-agent-nguyen-t_c-va-best-practices.jpg?v=1782892428","url":"https:\/\/claudeae.com\/products\/thi%e1%ba%bft-k%e1%ba%bf-tool-use-cho-ai-agent-nguyen-t%e1%ba%afc-va-best-practices","provider":"Claude.vn","version":"1.0","type":"link"}