{"product_id":"function-calling-tool-use-api-chi-tiết","title":"Function Calling — Tool Use API chi tiết","description":"\n\u003ch2\u003eTool Use là gì?\u003c\/h2\u003e\n\u003cp\u003eTool Use (còn gọi là Function Calling) là khả năng cho phép Claude gọi các hàm hoặc công cụ bên ngoài trong quá trình sinh câu trả lời. Thay vì chỉ trả về text, Claude có thể quyết định rằng nó cần thêm thông tin — và yêu cầu bạn chạy một hàm cụ thể, sau đó tiếp tục dựa trên kết quả trả về.\u003c\/p\u003e\n\n\u003cp\u003eĐây là cơ chế nền tảng để xây dựng AI agents thực sự hữu ích: Claude không bị giới hạn bởi kiến thức tĩnh mà có thể tìm kiếm web, truy vấn database, gọi API ngoài, hoặc thực thi code trong thời gian thực.\u003c\/p\u003e\n\n\u003ch2\u003eDefining Tools — JSON Schema\u003c\/h2\u003e\n\u003cp\u003eMỗi tool được định nghĩa bằng JSON Schema với ba trường bắt buộc:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003etools = [\n    {\n        \"name\": \"get_weather\",\n        \"description\": \"Lấy thông tin thời tiết hiện tại cho một thành phố.\",\n        \"input_schema\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"city\": {\n                    \"type\": \"string\",\n                    \"description\": \"Tên thành phố, ví dụ: 'Hà Nội', 'TP. Hồ Chí Minh'\"\n                },\n                \"unit\": {\n                    \"type\": \"string\",\n                    \"enum\": [\"celsius\", \"fahrenheit\"],\n                    \"description\": \"Đơn vị nhiệt độ\"\n                }\n            },\n            \"required\": [\"city\"]\n        }\n    }\n]\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eDescription của tool và từng parameter là yếu tố quan trọng nhất — Claude dựa vào đây để quyết định khi nào và cách nào sử dụng tool. Viết description rõ ràng, cụ thể, bao gồm ví dụ nếu cần.\u003c\/p\u003e\n\n\u003ch2\u003eTool Use Flow — Vòng lặp hoàn chỉnh\u003c\/h2\u003e\n\u003cp\u003eLuồng xử lý Tool Use có 4 bước:\u003c\/p\u003e\n\n\u003ch3\u003eBước 1: Gửi request với tools\u003c\/h3\u003e\n\u003cpre\u003e\u003ccode\u003eimport anthropic\n\nclient = anthropic.Anthropic()\n\nresponse = client.messages.create(\n    model=\"claude-opus-4\",\n    max_tokens=1024,\n    tools=tools,\n    messages=[\n        {\"role\": \"user\", \"content\": \"Thời tiết Hà Nội hôm nay thế nào?\"}\n    ]\n)\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eBước 2: Nhận tool_use response\u003c\/h3\u003e\n\u003cp\u003eKhi Claude quyết định gọi tool, \u003ccode\u003estop_reason\u003c\/code\u003e sẽ là \u003ccode\u003e\"tool_use\"\u003c\/code\u003e và content sẽ chứa block \u003ccode\u003etool_use\u003c\/code\u003e:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e# response.stop_reason == \"tool_use\"\n# response.content:\n[\n    TextBlock(text=\"Để trả lời câu hỏi này, tôi cần...\"),\n    ToolUseBlock(\n        id=\"toolu_01A09q90qw90lq917835lq9\",\n        name=\"get_weather\",\n        input={\"city\": \"Hà Nội\", \"unit\": \"celsius\"}\n    )\n]\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eBước 3: Thực thi tool và trả kết quả\u003c\/h3\u003e\n\u003cpre\u003e\u003ccode\u003eimport json\n\ndef process_tool_calls(response, tools_map):\n    tool_results = []\n    for block in response.content:\n        if block.type == \"tool_use\":\n            tool_fn = tools_map[block.name]\n            result = tool_fn(**block.input)\n            tool_results.append({\n                \"type\": \"tool_result\",\n                \"tool_use_id\": block.id,\n                \"content\": json.dumps(result)\n            })\n    return tool_results\n\n# Gọi tool thực tế\ntools_map = {\n    \"get_weather\": lambda city, unit=\"celsius\": {\n        \"temperature\": 28,\n        \"condition\": \"Nhiều mây\",\n        \"humidity\": 75\n    }\n}\n\ntool_results = process_tool_calls(response, tools_map)\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eBước 4: Tiếp tục conversation với tool_result\u003c\/h3\u003e\n\u003cpre\u003e\u003ccode\u003emessages = [\n    {\"role\": \"user\", \"content\": \"Thời tiết Hà Nội hôm nay thế nào?\"},\n    {\"role\": \"assistant\", \"content\": response.content},\n    {\"role\": \"user\", \"content\": tool_results}\n]\n\nfinal_response = client.messages.create(\n    model=\"claude-opus-4\",\n    max_tokens=1024,\n    tools=tools,\n    messages=messages\n)\n# final_response.stop_reason == \"end_turn\"\nprint(final_response.content[0].text)\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eParallel Tool Calls\u003c\/h2\u003e\n\u003cp\u003eClaude có thể gọi nhiều tools cùng lúc trong một response khi cần thông tin từ nhiều nguồn độc lập nhau:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e# Claude trả về nhiều tool_use blocks cùng lúc:\n[\n    ToolUseBlock(id=\"tu_001\", name=\"get_weather\", input={\"city\": \"Hà Nội\"}),\n    ToolUseBlock(id=\"tu_002\", name=\"get_weather\", input={\"city\": \"TP. Hồ Chí Minh\"}),\n    ToolUseBlock(id=\"tu_003\", name=\"get_exchange_rate\", input={\"currency\": \"USD\"})\n]\n\n# Bạn cần trả về kết quả cho TẤT CẢ tool calls:\ntool_results = [\n    {\"type\": \"tool_result\", \"tool_use_id\": \"tu_001\", \"content\": \"28°C, nhiều mây\"},\n    {\"type\": \"tool_result\", \"tool_use_id\": \"tu_002\", \"content\": \"32°C, nắng\"},\n    {\"type\": \"tool_result\", \"tool_use_id\": \"tu_003\", \"content\": \"25,450 VND\/USD\"}\n]\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eKhi xử lý parallel tool calls, bạn nên thực thi chúng đồng thời (asyncio hoặc threading) để giảm latency.\u003c\/p\u003e\n\n\u003ch2\u003eSequential Tool Calls\u003c\/h2\u003e\n\u003cp\u003eClaude tự động thực hiện nhiều vòng tool calls liên tiếp khi kết quả của tool trước ảnh hưởng đến tool sau:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e# Vòng 1: Claude gọi search\nToolUseBlock(name=\"web_search\", input={\"query\": \"giá iPhone 15 Pro Max VN\"})\n\n# Sau khi nhận kết quả search...\n# Vòng 2: Claude gọi calculator\nToolUseBlock(name=\"calculate\", input={\"expression\": \"34990000 * 0.95\"})\n\n# Sau khi nhận kết quả tính toán...\n# Claude trả lời cuối cùng\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eError Handling\u003c\/h2\u003e\n\u003cp\u003eKhi tool gặp lỗi, trả về \u003ccode\u003eis_error: true\u003c\/code\u003e trong tool_result. Claude sẽ xử lý lỗi và có thể thử cách khác:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003etool_results = [\n    {\n        \"type\": \"tool_result\",\n        \"tool_use_id\": block.id,\n        \"content\": \"Không thể kết nối đến API thời tiết. Lỗi: timeout\",\n        \"is_error\": True\n    }\n]\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eForcing Tool Use với tool_choice\u003c\/h2\u003e\n\u003cp\u003eMặc định Claude tự quyết định có dùng tool hay không. Bạn có thể kiểm soát hành vi này:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003e# Bắt buộc Claude PHẢI dùng tool (bất kỳ tool nào)\ntool_choice = {\"type\": \"any\"}\n\n# Bắt buộc dùng tool cụ thể\ntool_choice = {\"type\": \"tool\", \"name\": \"get_weather\"}\n\n# Không được dùng tool (chỉ text)\ntool_choice = {\"type\": \"none\"}\n\n# Tự động quyết định (mặc định)\ntool_choice = {\"type\": \"auto\"}\n\nresponse = client.messages.create(\n    model=\"claude-sonnet-4-5\",\n    max_tokens=1024,\n    tools=tools,\n    tool_choice={\"type\": \"tool\", \"name\": \"get_weather\"},\n    messages=[...]\n)\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eComplex Pattern: Search → Analyze → Respond\u003c\/h2\u003e\n\u003cp\u003eVí dụ thực tế: agent tìm kiếm thông tin, phân tích, và trả lời dựa trên dữ liệu thực:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003etools = [\n    {\n        \"name\": \"search_products\",\n        \"description\": \"Tìm kiếm sản phẩm trong database theo từ khóa\",\n        \"input_schema\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"query\": {\"type\": \"string\"},\n                \"category\": {\"type\": \"string\"},\n                \"max_price\": {\"type\": \"number\"}\n            },\n            \"required\": [\"query\"]\n        }\n    },\n    {\n        \"name\": \"get_product_reviews\",\n        \"description\": \"Lấy đánh giá của sản phẩm theo product_id\",\n        \"input_schema\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"product_id\": {\"type\": \"string\"},\n                \"limit\": {\"type\": \"integer\", \"default\": 5}\n            },\n            \"required\": [\"product_id\"]\n        }\n    },\n    {\n        \"name\": \"compare_prices\",\n        \"description\": \"So sánh giá sản phẩm trên các sàn thương mại điện tử\",\n        \"input_schema\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"product_name\": {\"type\": \"string\"}\n            },\n            \"required\": [\"product_name\"]\n        }\n    }\n]\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eCaching với Tools\u003c\/h2\u003e\n\u003cp\u003eKhi dùng nhiều tools hoặc tool definitions dài, hãy cache chúng để giảm chi phí:\u003c\/p\u003e\n\u003cpre\u003e\u003ccode\u003eresponse = client.messages.create(\n    model=\"claude-opus-4\",\n    max_tokens=1024,\n    tools=tools,\n    system=[\n        {\n            \"type\": \"text\",\n            \"text\": \"Bạn là trợ lý mua sắm thông minh...\",\n            \"cache_control\": {\"type\": \"ephemeral\"}\n        }\n    ],\n    messages=[{\"role\": \"user\", \"content\": user_query}]\n)\u003c\/code\u003e\u003c\/pre\u003e\n\u003cp\u003eTool definitions được tính vào input tokens và có thể được cache riêng nếu chúng ổn định giữa các requests.\u003c\/p\u003e\n\n\u003ch2\u003eBest Practices\u003c\/h2\u003e\n\u003cul\u003e\n  \u003cli\u003e\n\u003cstrong\u003eDescription chất lượng cao:\u003c\/strong\u003e Mô tả rõ tool làm gì, khi nào nên dùng, format input mong muốn\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eTối thiểu hóa tool set:\u003c\/strong\u003e Chỉ cung cấp tools thực sự cần thiết cho task — quá nhiều tools làm Claude khó quyết định\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eIdempotent tools:\u003c\/strong\u003e Thiết kế tools có thể gọi lại nhiều lần mà không gây side effects ngoài ý muốn\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eTimeout và retry:\u003c\/strong\u003e Luôn có timeout cho external API calls, retry logic cho transient failures\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eValidate input:\u003c\/strong\u003e Validate và sanitize input từ Claude trước khi thực thi — không tin tưởng blindly\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eLog mọi tool calls:\u003c\/strong\u003e Ghi lại tool name, input, output để debug và audit\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch2\u003eVí dụ hoàn chỉnh: Weather + Calculator\u003c\/h2\u003e\n\u003cpre\u003e\u003ccode\u003eimport anthropic\nimport json\n\nclient = anthropic.Anthropic()\n\ntools = [\n    {\n        \"name\": \"get_weather\",\n        \"description\": \"Lấy nhiệt độ và điều kiện thời tiết cho thành phố\",\n        \"input_schema\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"city\": {\"type\": \"string\", \"description\": \"Tên thành phố tiếng Việt\"}\n            },\n            \"required\": [\"city\"]\n        }\n    },\n    {\n        \"name\": \"calculate\",\n        \"description\": \"Tính toán biểu thức toán học\",\n        \"input_schema\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"expression\": {\"type\": \"string\", \"description\": \"Biểu thức toán học, ví dụ: '28 * 1.8 + 32'\"}\n            },\n            \"required\": [\"expression\"]\n        }\n    }\n]\n\ndef run_tool(name, inputs):\n    if name == \"get_weather\":\n        # Mock — thay bằng API thật\n        return {\"city\": inputs[\"city\"], \"temp_celsius\": 28, \"condition\": \"Nhiều mây\"}\n    if name == \"calculate\":\n        return {\"result\": eval(inputs[\"expression\"])}  # Trong production dùng safe eval\n\ndef agent_loop(user_message):\n    messages = [{\"role\": \"user\", \"content\": user_message}]\n\n    while True:\n        response = client.messages.create(\n            model=\"claude-sonnet-4-5\",\n            max_tokens=1024,\n            tools=tools,\n            messages=messages\n        )\n\n        if response.stop_reason == \"end_turn\":\n            return response.content[0].text\n\n        # Xử lý tool calls\n        messages.append({\"role\": \"assistant\", \"content\": response.content})\n        tool_results = []\n        for block in response.content:\n            if block.type == \"tool_use\":\n                result = run_tool(block.name, block.input)\n                tool_results.append({\n                    \"type\": \"tool_result\",\n                    \"tool_use_id\": block.id,\n                    \"content\": json.dumps(result, ensure_ascii=False)\n                })\n        messages.append({\"role\": \"user\", \"content\": tool_results})\n\nresult = agent_loop(\"Nhiệt độ Hà Nội bao nhiêu độ F?\")\nprint(result)\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eKết luận\u003c\/h2\u003e\n\u003cp\u003eTool Use API là nền tảng để biến Claude từ chatbot thành agent thực sự. Với khả năng xử lý parallel và sequential tool calls, Claude có thể orchestrate các workflow phức tạp một cách tự nhiên. Điều quan trọng nhất là thiết kế tool definitions rõ ràng và xây dựng error handling robust để agent hoạt động tin cậy trong môi trường production.\u003c\/p\u003e\n","brand":"Minh Tuấn","offers":[{"title":"Default Title","offer_id":47721071739092,"sku":null,"price":0.0,"currency_code":"VND","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0821\/0264\/9044\/files\/function-calling-tool-use-api-chi-ti_t.jpg?v=1774521596","url":"https:\/\/claude.vn\/products\/function-calling-tool-use-api-chi-ti%e1%ba%bft","provider":"CLAUDE.VN","version":"1.0","type":"link"}