{"product_id":"tool-choice-kiểm-soat-cach-claude-chọn-va-gọi-tools","title":"Tool Choice — Kiểm soát cách Claude chọn và gọi tools","description":"\n\u003cp\u003eKhi bạn truyền tools vào Claude API, mặc định Claude tự quyết định có cần gọi tool không. Đôi khi điều này gây ra vấn đề: Claude \u003cem\u003equá hăng hái\u003c\/em\u003e gọi tool cho những câu hỏi đơn giản, hoặc ngược lại, \u003cem\u003ebỏ qua\u003c\/em\u003e tool khi bạn muốn nó dùng.\u003c\/p\u003e\n\n\u003cp\u003eParameter \u003ccode\u003etool_choice\u003c\/code\u003e cho phép bạn kiểm soát chính xác hành vi này với ba chế độ: \u003ccode\u003eauto\u003c\/code\u003e, \u003ccode\u003etool\u003c\/code\u003e, và \u003ccode\u003eany\u003c\/code\u003e.\u003c\/p\u003e\n\n\u003ch2\u003eChế độ 1: auto (mặc định)\u003c\/h2\u003e\n\n\u003cp\u003eClaude tự quyết định dùng tool hay trả lời trực tiếp.\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport anthropic\n\nclient = anthropic.Anthropic()\n\ntools = [\n    {\n        \"name\": \"get_weather\",\n        \"description\": \"Lay thong tin thoi tiet theo thanh pho\",\n        \"input_schema\": {\n            \"type\": \"object\",\n            \"properties\": {\n                \"city\": {\"type\": \"string\", \"description\": \"Ten thanh pho\"}\n            },\n            \"required\": [\"city\"]\n        }\n    }\n]\n\n# Che do auto - Claude tu quyet dinh\nresponse = client.messages.create(\n    model=\"claude-opus-4-5\",\n    max_tokens=512,\n    tools=tools,\n    tool_choice={\"type\": \"auto\"},  # Day la mac dinh, co the bo qua\n    messages=[{\"role\": \"user\", \"content\": \"Thoi tiet Ha Noi hom nay the nao?\"}]\n)\n# Claude SE goi tool vi cau hoi lien quan den thoi tiet\n\nresponse2 = client.messages.create(\n    model=\"claude-opus-4-5\",\n    max_tokens=512,\n    tools=tools,\n    tool_choice={\"type\": \"auto\"},\n    messages=[{\"role\": \"user\", \"content\": \"Cho toi biet 2 + 2 bang may?\"}]\n)\n# Claude KHONG goi tool vi co the tra loi truc tiep\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003e\u003cstrong\u003eKhi dùng auto:\u003c\/strong\u003e Trường hợp tổng quát khi bạn muốn Claude linh hoạt — đôi khi trả lời trực tiếp, đôi khi dùng tool tùy ngữ cảnh.\u003c\/p\u003e\n\n\u003ch3\u003eVấn đề với auto: Claude có thể quá hăng hái\u003c\/h3\u003e\n\n\u003cp\u003eVới \u003ccode\u003eauto\u003c\/code\u003e, chất lượng prompt ảnh hưởng trực tiếp đến quyết định của Claude. Nếu tools được mô tả quá rộng, Claude có thể gọi tool ngay cả khi không cần thiết:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003e# Tool mo ta qua rong - Claude co the goi bat ky luc nao\nbad_tool = {\n    \"name\": \"lookup_info\",\n    \"description\": \"Tim kiem bat ky thong tin gi\",  # Qua chung chung!\n    \"input_schema\": {...}\n}\n\n# Tool mo ta cu the - Claude chi goi khi thich hop\ngood_tool = {\n    \"name\": \"lookup_product_price\",\n    \"description\": \"Tra cuu gia san pham tu catalog. Chi dung khi user hoi ve gia cu the cua mot san pham.\",\n    \"input_schema\": {...}\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eChế độ 2: tool (Force một tool cụ thể)\u003c\/h2\u003e\n\n\u003cp\u003eÉp Claude phải gọi đúng một tool, bất kể câu hỏi là gì.\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003eresponse = client.messages.create(\n    model=\"claude-opus-4-5\",\n    max_tokens=512,\n    tools=tools,\n    tool_choice={\n        \"type\": \"tool\",\n        \"name\": \"get_weather\"  # Claude PHAI goi tool nay\n    },\n    messages=[{\"role\": \"user\", \"content\": \"Cho toi biet 2 + 2 bang may?\"}]\n)\n\n# Ket qua: Claude van goi get_weather du cau hoi khong lien quan!\n# Tool input co the la: {\"city\": \"khong xac dinh\"} hoac tuong tu\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003e\u003cstrong\u003eKhi dùng tool:\u003c\/strong\u003e\u003c\/p\u003e\n\u003cul\u003e\n  \u003cli\u003eBạn cần guarantee tool luôn được gọi (ví dụ: logging, analytics)\u003c\/li\u003e\n  \u003cli\u003eSử dụng tool như structured output generator (xem phần dưới)\u003c\/li\u003e\n  \u003cli\u003eTesting và debugging tool cụ thể\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch2\u003eChế độ 3: any (Phải dùng ít nhất một tool)\u003c\/h2\u003e\n\n\u003cp\u003eClaude phải gọi ít nhất một tool trong danh sách, nhưng tự chọn tool nào.\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003etools = [\n    get_weather_tool,\n    get_time_tool,\n    get_exchange_rate_tool\n]\n\nresponse = client.messages.create(\n    model=\"claude-opus-4-5\",\n    max_tokens=512,\n    tools=tools,\n    tool_choice={\"type\": \"any\"},  # Claude phai dung it nhat 1 tool\n    messages=[{\"role\": \"user\", \"content\": \"Bao cao buoi sang: thoi tiet, gio, ty gia?\"}]\n)\n# Claude se goi ca 3 tools (hoac it nhat 1 tuy theo context)\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003e\u003cstrong\u003eKhi dùng any:\u003c\/strong\u003e\u003c\/p\u003e\n\u003cul\u003e\n  \u003cli\u003eBạn muốn Claude luôn kết nối với external data, không được trả lời \"từ trí nhớ\"\u003c\/li\u003e\n  \u003cli\u003eDashboard\/report generation cần data thực\u003c\/li\u003e\n  \u003cli\u003eKhi bạn có nhiều tools và muốn Claude chọn công cụ phù hợp nhất\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch2\u003eBảng tóm tắt\u003c\/h2\u003e\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n\u003cth\u003etool_choice\u003c\/th\u003e\n\u003cth\u003eHành vi\u003c\/th\u003e\n\u003cth\u003estop_reason\u003c\/th\u003e\n\u003cth\u003eDùng khi\u003c\/th\u003e\n\u003c\/tr\u003e\n  \u003c\/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eauto\u003c\/code\u003e\u003c\/td\u003e\n\u003ctd\u003eClaude tự quyết\u003c\/td\u003e\n\u003ctd\u003eend_turn hoặc tool_use\u003c\/td\u003e\n\u003ctd\u003eHầu hết trường hợp\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003etool\u003c\/code\u003e\u003c\/td\u003e\n\u003ctd\u003eBắt buộc tool cụ thể\u003c\/td\u003e\n\u003ctd\u003etool_use (luôn)\u003c\/td\u003e\n\u003ctd\u003eStructured output, guaranteed call\u003c\/td\u003e\n\u003c\/tr\u003e\n    \u003ctr\u003e\n\u003ctd\u003e\u003ccode\u003eany\u003c\/code\u003e\u003c\/td\u003e\n\u003ctd\u003ePhải dùng ít nhất 1\u003c\/td\u003e\n\u003ctd\u003etool_use (luôn)\u003c\/td\u003e\n\u003ctd\u003eCần external data, không dùng cached knowledge\u003c\/td\u003e\n\u003c\/tr\u003e\n  \u003c\/tbody\u003e\n\u003c\/table\u003e\n\n\u003ch2\u003eUse Case thực tế: Structured Sentiment Analysis\u003c\/h2\u003e\n\n\u003cp\u003eKết hợp \u003ccode\u003etool_choice: tool\u003c\/code\u003e với \"fake tool\" là cách mạnh nhất để tạo structured output:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003esentiment_schema = {\n    \"name\": \"record_sentiment\",\n    \"description\": \"Luu tru ket qua phan tich cam xuc\",\n    \"input_schema\": {\n        \"type\": \"object\",\n        \"properties\": {\n            \"sentiment\": {\n                \"type\": \"string\",\n                \"enum\": [\"positive\", \"negative\", \"neutral\", \"mixed\"]\n            },\n            \"score\": {\n                \"type\": \"number\",\n                \"description\": \"Tu -1.0 den 1.0\"\n            },\n            \"confidence\": {\n                \"type\": \"number\",\n                \"description\": \"Do tin cay 0.0 den 1.0\"\n            },\n            \"dominant_emotion\": {\n                \"type\": \"string\",\n                \"enum\": [\"joy\", \"anger\", \"sadness\", \"fear\", \"surprise\", \"disgust\", \"neutral\"]\n            },\n            \"brief_reason\": {\n                \"type\": \"string\",\n                \"description\": \"Ly giai ngan trong 1 cau\"\n            }\n        },\n        \"required\": [\"sentiment\", \"score\", \"confidence\", \"dominant_emotion\", \"brief_reason\"]\n    }\n}\n\ndef analyze_sentiment_batch(texts):\n    results = []\n    for text in texts:\n        response = client.messages.create(\n            model=\"claude-opus-4-5\",\n            max_tokens=256,\n            tools=[sentiment_schema],\n            tool_choice={\"type\": \"tool\", \"name\": \"record_sentiment\"},\n            messages=[{\n                \"role\": \"user\",\n                \"content\": f\"Phan tich cam xuc doan van sau:\n\n{text}\"\n            }]\n        )\n\n        # Ket qua la JSON truc tiep - khong can parse text\n        sentiment_data = response.content[0].input\n        results.append({\n            \"text\": text[:50] + \"...\",\n            **sentiment_data\n        })\n\n    return results\n\n# Test\nreviews = [\n    \"San pham rat tot, giao hang nhanh, toi rat hai long!\",\n    \"That vong qua, hang bi hong khi nhan duoc, chat luong kem.\",\n    \"Binh thuong, khong co gi dac biet nhung cung dung duoc.\",\n    \"Gia kha dat nhung chat luong tuong xung, se mua lai.\"\n]\n\nresults = analyze_sentiment_batch(reviews)\nfor r in results:\n    print(f\"Text: {r['text']}\")\n    print(f\"  Sentiment: {r['sentiment']} (score: {r['score']:.2f}, confidence: {r['confidence']:.0%})\")\n    print(f\"  Emotion: {r['dominant_emotion']}\")\n    print(f\"  Reason: {r['brief_reason']}\")\n    print()\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eOutput đảm bảo 100% là JSON hợp lệ với đúng types và enum values — không cần try\/except cho JSON parsing.\u003c\/p\u003e\n\n\u003ch2\u003eXử lý Parallel Tool Calls với tool_choice\u003c\/h2\u003e\n\n\u003cp\u003eKhi dùng \u003ccode\u003eany\u003c\/code\u003e hoặc \u003ccode\u003eauto\u003c\/code\u003e, Claude có thể gọi nhiều tools cùng một lúc. Đây là cách xử lý đúng:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003edef process_response_with_multiple_tools(response, messages):\n    \"\"\"Xu ly response co the co nhieu tool calls\"\"\"\n\n    if response.stop_reason != \"tool_use\":\n        # Claude tra loi truc tiep\n        return response.content[0].text\n\n    # Thu thap tat ca tool results\n    tool_results = []\n    for block in response.content:\n        if block.type == \"tool_use\":\n            result = execute_tool(block.name, block.input)\n            tool_results.append({\n                \"type\": \"tool_result\",\n                \"tool_use_id\": block.id,\n                \"content\": str(result)\n            })\n\n    # Them assistant response va tool results vao history\n    messages.append({\"role\": \"assistant\", \"content\": response.content})\n    messages.append({\"role\": \"user\", \"content\": tool_results})\n\n    # Tiep tuc vong lap\n    next_response = client.messages.create(\n        model=\"claude-opus-4-5\",\n        max_tokens=1024,\n        tools=ALL_TOOLS,\n        messages=messages\n    )\n\n    return process_response_with_multiple_tools(next_response, messages)\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eDisable Tool Use hoàn toàn\u003c\/h2\u003e\n\n\u003cp\u003eĐôi khi bạn muốn không dùng tool gì cả trong một lượt cụ thể:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003e# Truyen tools=[] hoac khong truyen tools parameter\nresponse = client.messages.create(\n    model=\"claude-opus-4-5\",\n    max_tokens=512,\n    # Khong truyen tools - Claude chi tra loi bang text\n    messages=[{\"role\": \"user\", \"content\": \"Xin chao!\"}]\n)\n\n# Hoac neu ban da khai bao tools truoc do trong conversation\n# va muon disable trong mot luot cu the:\n# Su dung tool_choice={\"type\": \"auto\"} voi tools=[]\n# Hoac don gian la khong truyen tools parameter\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eTips và Anti-patterns\u003c\/h2\u003e\n\n\u003cp\u003e\u003cstrong\u003eNên làm:\u003c\/strong\u003e\u003c\/p\u003e\n\u003cul\u003e\n  \u003cli\u003eDùng \u003ccode\u003etool\u003c\/code\u003e choice khi build data extraction pipeline — guaranteed JSON output\u003c\/li\u003e\n  \u003cli\u003eDùng \u003ccode\u003eany\u003c\/code\u003e cho agents cần real-time data — tránh hallucination từ outdated training data\u003c\/li\u003e\n  \u003cli\u003eDùng \u003ccode\u003eauto\u003c\/code\u003e cho conversational interfaces — Claude linh hoạt hơn cho UX tốt hơn\u003c\/li\u003e\n  \u003cli\u003eViết description tools thật cụ thể để \u003ccode\u003eauto\u003c\/code\u003e hoạt động đúng\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003e\u003cstrong\u003eKhông nên:\u003c\/strong\u003e\u003c\/p\u003e\n\u003cul\u003e\n  \u003cli\u003eForce tool \u003ccode\u003eany\u003c\/code\u003e trong chatbot tổng quát — sẽ gây ra tool calls không cần thiết, tốn token\u003c\/li\u003e\n  \u003cli\u003eDùng \u003ccode\u003etool\u003c\/code\u003e choice với tool mà input không related — Claude sẽ điền input mơ hồ\u003c\/li\u003e\n  \u003cli\u003eBỏ qua \u003ccode\u003estop_reason\u003c\/code\u003e check — luôn kiểm tra trước khi đọc content\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003eBài tiếp theo: giải quyết vấn đề \u003cstrong\u003eparallel tool calls\u003c\/strong\u003e — khi bạn cần Claude gọi nhiều tools đồng thời để giảm latency, và cách dùng \"batch tool\" meta-pattern khi Claude không tự làm.\u003c\/p\u003e\n","brand":"Minh Tuấn","offers":[{"title":"Default Title","offer_id":47721765896404,"sku":null,"price":0.0,"currency_code":"VND","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0821\/0264\/9044\/files\/tool-choice-ki_m-soat-cach-claude-ch_n-va-g_i-tools.jpg?v=1774506569","url":"https:\/\/claude.vn\/products\/tool-choice-ki%e1%bb%83m-soat-cach-claude-ch%e1%bb%8dn-va-g%e1%bb%8di-tools","provider":"CLAUDE.VN","version":"1.0","type":"link"}