{"product_id":"xay-dựng-customer-service-agent-với-claude-tool-use","title":"Xây dựng Customer Service Agent với Claude Tool Use","description":"\n\u003cp\u003eTrong bài này, chúng ta sẽ xây dựng một \u003cstrong\u003eCustomer Service Agent\u003c\/strong\u003e hoàn chỉnh — chatbot có thể tra cứu thông tin khách hàng, xem chi tiết đơn hàng, và thực hiện hủy đơn. Đây là ứng dụng Tool Use thực tế nhất, gần với production deployment nhất.\u003c\/p\u003e\n\n\u003cp\u003eĐiểm khác biệt với bài Calculator: ở đây chúng ta có \u003cstrong\u003emulti-turn conversation\u003c\/strong\u003e, nhiều tools tương tác với nhau, và business logic phức tạp hơn. Kết thúc bài, bạn sẽ có một agent có thể xử lý cuộc hội thoại như:\u003c\/p\u003e\n\n\u003cblockquote\u003e\n\u003cp\u003e\u003cem\u003e\"Tôi muốn hủy đơn hàng #12345 của tôi.\"\u003c\/em\u003e\u003cbr\u003e\n\u003cem\u003e[Claude tra cứu đơn hàng, kiểm tra điều kiện hủy, thực hiện hủy, xác nhận với khách]\u003c\/em\u003e\u003c\/p\u003e\n\u003c\/blockquote\u003e\n\n\u003ch2\u003eThiết kế 3 Tools\u003c\/h2\u003e\n\n\u003cp\u003eAgent của chúng ta cần 3 tools để phục vụ khách hàng:\u003c\/p\u003e\n\n\u003ch3\u003eTool 1: get_customer_info\u003c\/h3\u003e\n\n\u003cpre\u003e\u003ccode\u003eget_customer_info = {\n    \"name\": \"get_customer_info\",\n    \"description\": \"Tra cuu thong tin khach hang theo customer_id hoac email\",\n    \"input_schema\": {\n        \"type\": \"object\",\n        \"properties\": {\n            \"identifier\": {\n                \"type\": \"string\",\n                \"description\": \"Customer ID (VD: CUST-001) hoac dia chi email\"\n            }\n        },\n        \"required\": [\"identifier\"]\n    }\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eTool 2: get_order_details\u003c\/h3\u003e\n\n\u003cpre\u003e\u003ccode\u003eget_order_details = {\n    \"name\": \"get_order_details\",\n    \"description\": \"Xem chi tiet don hang theo order_id\",\n    \"input_schema\": {\n        \"type\": \"object\",\n        \"properties\": {\n            \"order_id\": {\n                \"type\": \"string\",\n                \"description\": \"Ma don hang, bat dau bang #\"\n            }\n        },\n        \"required\": [\"order_id\"]\n    }\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eTool 3: cancel_order\u003c\/h3\u003e\n\n\u003cpre\u003e\u003ccode\u003ecancel_order = {\n    \"name\": \"cancel_order\",\n    \"description\": \"Huy don hang. Chi huy duoc don hang co trang thai pending hoac processing.\",\n    \"input_schema\": {\n        \"type\": \"object\",\n        \"properties\": {\n            \"order_id\": {\n                \"type\": \"string\",\n                \"description\": \"Ma don hang can huy\"\n            },\n            \"reason\": {\n                \"type\": \"string\",\n                \"description\": \"Ly do huy don hang\"\n            }\n        },\n        \"required\": [\"order_id\", \"reason\"]\n    }\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003cp\u003eChú ý description của \u003ccode\u003ecancel_order\u003c\/code\u003e có ghi rõ điều kiện: \u003cem\u003e\"Chỉ hủy được đơn hàng có trạng thái pending hoặc processing.\"\u003c\/em\u003e Claude đọc thông tin này và sẽ không cố gọi tool với đơn hàng đã giao.\u003c\/p\u003e\n\n\u003ch2\u003eDữ liệu mẫu (Synthetic Backend)\u003c\/h2\u003e\n\n\u003cp\u003eThay vì kết nối database thực, chúng ta dùng data tĩnh để demo:\u003c\/p\u003e\n\n\u003cpre\u003e\u003ccode\u003eCUSTOMERS = {\n    \"CUST-001\": {\n        \"name\": \"Nguyen Thi Mai\",\n        \"email\": \"mai.nguyen@email.com\",\n        \"phone\": \"0901234567\",\n        \"loyalty_points\": 1250,\n        \"membership\": \"Gold\"\n    },\n    \"CUST-002\": {\n        \"name\": \"Tran Van Hung\",\n        \"email\": \"hung.tran@email.com\",\n        \"phone\": \"0912345678\",\n        \"loyalty_points\": 320,\n        \"membership\": \"Silver\"\n    }\n}\n\nORDERS = {\n    \"#12345\": {\n        \"customer_id\": \"CUST-001\",\n        \"status\": \"processing\",\n        \"items\": [\n            {\"name\": \"Ao thun nam\", \"qty\": 2, \"price\": 250000},\n            {\"name\": \"Quan jeans\", \"qty\": 1, \"price\": 650000}\n        ],\n        \"total\": 1150000,\n        \"created_at\": \"2026-03-20\"\n    },\n    \"#12346\": {\n        \"customer_id\": \"CUST-001\",\n        \"status\": \"delivered\",\n        \"items\": [\n            {\"name\": \"Giay the thao\", \"qty\": 1, \"price\": 1200000}\n        ],\n        \"total\": 1200000,\n        \"created_at\": \"2026-03-10\"\n    }\n}\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eImplement Tool Execution\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport json\n\ndef execute_tool(tool_name, tool_input):\n    \"\"\"Xu ly tat ca cac tool calls tu Claude\"\"\"\n\n    if tool_name == \"get_customer_info\":\n        identifier = tool_input[\"identifier\"]\n\n        # Tim theo customer_id\n        if identifier in CUSTOMERS:\n            return json.dumps(CUSTOMERS[identifier], ensure_ascii=False)\n\n        # Tim theo email\n        for cust_id, cust_data in CUSTOMERS.items():\n            if cust_data[\"email\"] == identifier:\n                return json.dumps({**cust_data, \"customer_id\": cust_id}, ensure_ascii=False)\n\n        return json.dumps({\"error\": \"Khong tim thay khach hang\"})\n\n    elif tool_name == \"get_order_details\":\n        order_id = tool_input[\"order_id\"]\n        if order_id in ORDERS:\n            order = ORDERS[order_id]\n            # Tinh tong cho dep hon\n            formatted = {\n                **order,\n                \"order_id\": order_id,\n                \"total_formatted\": f\"{order['total']:,}d\"\n            }\n            return json.dumps(formatted, ensure_ascii=False)\n        return json.dumps({\"error\": f\"Don hang {order_id} khong ton tai\"})\n\n    elif tool_name == \"cancel_order\":\n        order_id = tool_input[\"order_id\"]\n        reason = tool_input[\"reason\"]\n\n        if order_id not in ORDERS:\n            return json.dumps({\"success\": False, \"message\": \"Don hang khong ton tai\"})\n\n        order = ORDERS[order_id]\n        if order[\"status\"] not in [\"pending\", \"processing\"]:\n            return json.dumps({\n                \"success\": False,\n                \"message\": f\"Khong the huy don hang co trang thai '{order['status']}'\"\n            })\n\n        # Thuc hien huy (trong demo, chi cap nhat in-memory)\n        ORDERS[order_id][\"status\"] = \"cancelled\"\n        return json.dumps({\n            \"success\": True,\n            \"message\": f\"Don hang {order_id} da duoc huy thanh cong\",\n            \"refund_amount\": order[\"total\"]\n        })\n\n    return json.dumps({\"error\": \"Tool khong ton tai\"})\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eAgent Loop với Multi-turn Support\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003eimport anthropic\n\nclient = anthropic.Anthropic()\n\nSYSTEM_PROMPT = \"\"\"Ban la nhan vien ho tro khach hang cua ShopViet - mot san thuong mai dien tu Viet Nam.\nBan co the:\n- Tra cuu thong tin tai khoan khach hang\n- Xem chi tiet don hang\n- Ho tro huy don hang (chi don chua giao)\n\nHay luon lich su, than thien va nhanh chong giai quyet van de cua khach.\nNeu khach hang chua cung cap du thong tin, hay hoi them truoc khi thuc hien tham so.\"\"\"\n\nALL_TOOLS = [get_customer_info, get_order_details, cancel_order]\n\ndef run_customer_service_agent(user_message, conversation_history=None):\n    \"\"\"\n    Chay agent voi lich su hoi thoai (ho tro multi-turn).\n    conversation_history: list cac messages truoc do\n    \"\"\"\n    if conversation_history is None:\n        conversation_history = []\n\n    # Them message moi cua user\n    conversation_history.append({\n        \"role\": \"user\",\n        \"content\": user_message\n    })\n\n    while True:\n        response = client.messages.create(\n            model=\"claude-opus-4-5\",\n            max_tokens=2048,\n            system=SYSTEM_PROMPT,\n            tools=ALL_TOOLS,\n            messages=conversation_history\n        )\n\n        # Them response cua Claude vao history\n        conversation_history.append({\n            \"role\": \"assistant\",\n            \"content\": response.content\n        })\n\n        # Neu Claude da tra loi xong\n        if response.stop_reason == \"end_turn\":\n            # Lay text cuoi cung\n            final_text = \"\"\n            for block in response.content:\n                if hasattr(block, \"text\"):\n                    final_text += block.text\n            return final_text, conversation_history\n\n        # Xu ly tool calls\n        if response.stop_reason == \"tool_use\":\n            tool_results = []\n\n            for block in response.content:\n                if block.type == \"tool_use\":\n                    print(f\"[DEBUG] Claude goi tool: {block.name}({block.input})\")\n                    result = execute_tool(block.name, block.input)\n                    tool_results.append({\n                        \"type\": \"tool_result\",\n                        \"tool_use_id\": block.id,\n                        \"content\": result\n                    })\n\n            # Them ket qua tool vao history\n            conversation_history.append({\n                \"role\": \"user\",\n                \"content\": tool_results\n            })\n\n        else:\n            break\n\n    return \"\", conversation_history\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eDemo: Cuộc hội thoại thực tế\u003c\/h2\u003e\n\n\u003cpre\u003e\u003ccode\u003edef demo_conversation():\n    print(\"=== Customer Service Agent Demo ===\n\")\n    history = []\n\n    # Turn 1: Xem don hang\n    response, history = run_customer_service_agent(\n        \"Xin chao! Toi muon kiem tra don hang #12345 cua toi\",\n        history\n    )\n    print(f\"Agent: {response}\n\")\n\n    # Turn 2: Yeu cau huy\n    response, history = run_customer_service_agent(\n        \"Toi muon huy don hang do vi toi dat nham mau. Duoc khong?\",\n        history\n    )\n    print(f\"Agent: {response}\n\")\n\n    # Turn 3: Xac nhan huy\n    response, history = run_customer_service_agent(\n        \"Vang, toi xac nhan muon huy. Cam on ban.\",\n        history\n    )\n    print(f\"Agent: {response}\n\")\n\n    # Turn 4: Hoi ve don da giao (test edge case)\n    response, history = run_customer_service_agent(\n        \"Con don hang #12346 toi cung muon huy duoc khong?\",\n        history\n    )\n    print(f\"Agent: {response}\n\")\n\ndemo_conversation()\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch3\u003eOutput mong đợi:\u003c\/h3\u003e\n\n\u003cpre\u003e\u003ccode\u003e[DEBUG] Claude goi tool: get_order_details({'order_id': '#12345'})\nAgent: Toi da kiem tra don hang #12345 cua ban:\n- 2x Ao thun nam: 500.000d\n- 1x Quan jeans: 650.000d\n- Tong: 1.150.000d\n- Trang thai: Dang xu ly\n\nBan can ho tro gi voi don hang nay?\n\n[DEBUG] Claude goi tool: cancel_order({'order_id': '#12345', 'reason': 'dat nham mau'})\nAgent: Toi da huy thanh cong don hang #12345 cho ban.\nSo tien 1.150.000d se duoc hoan tra trong 3-5 ngay lam viec.\n\n[DEBUG] Claude goi tool: get_order_details({'order_id': '#12346'})\nAgent: Rat tiec, don hang #12346 (Giay the thao) da duoc giao thanh cong\nnen khong the huy. Neu san pham co van de, ban co the yeu cau doi\/tra\nhang trong vong 7 ngay.\u003c\/code\u003e\u003c\/pre\u003e\n\n\u003ch2\u003eXử lý Multiple Tool Calls\u003c\/h2\u003e\n\n\u003cp\u003eĐôi khi Claude cần gọi nhiều tools trong một lượt. Ví dụ: \u003cem\u003e\"Kiểm tra thông tin tài khoản và tất cả đơn hàng của tôi là CUST-001\"\u003c\/em\u003e — Claude có thể gọi \u003ccode\u003eget_customer_info\u003c\/code\u003e và sau đó gọi \u003ccode\u003eget_order_details\u003c\/code\u003e nhiều lần.\u003c\/p\u003e\n\n\u003cp\u003eCode của chúng ta đã xử lý điều này trong vòng lặp \u003ccode\u003efor block in response.content\u003c\/code\u003e — nó thu thập tất cả tool_use blocks trước khi gửi tất cả kết quả một lúc.\u003c\/p\u003e\n\n\u003ch2\u003eBest Practices cho Production\u003c\/h2\u003e\n\n\u003cul\u003e\n  \u003cli\u003e\n\u003cstrong\u003eAuthentication trong tools\u003c\/strong\u003e — Luôn verify user có quyền với resource họ request. Ví dụ: kiểm tra customer_id trong order khớp với user đang đăng nhập.\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eError handling rõ ràng\u003c\/strong\u003e — Tools nên trả về error messages thân thiện thay vì raise exceptions.\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eRate limiting\u003c\/strong\u003e — Giới hạn số lần gọi tool trong một session để tránh abuse.\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eAudit logging\u003c\/strong\u003e — Log tất cả tool calls với user_id, timestamp, input\/output để debug và compliance.\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eTool description cụ thể\u003c\/strong\u003e — Mô tả rõ điều kiện, giới hạn của từng tool để Claude không thử gọi tool sai lúc.\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch2\u003eMở rộng Agent\u003c\/h2\u003e\n\n\u003cp\u003eTừ skeleton này, bạn có thể thêm nhiều tools hơn:\u003c\/p\u003e\n\n\u003cul\u003e\n  \u003cli\u003e\n\u003cstrong\u003esearch_products\u003c\/strong\u003e — Tìm kiếm sản phẩm theo tên, category\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eupdate_shipping_address\u003c\/strong\u003e — Cập nhật địa chỉ giao hàng (chỉ trước khi ship)\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003ecreate_return_request\u003c\/strong\u003e — Tạo yêu cầu đổi\/trả hàng\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003echeck_loyalty_rewards\u003c\/strong\u003e — Xem điểm tích lũy và ưu đãi\u003c\/li\u003e\n  \u003cli\u003e\n\u003cstrong\u003eescalate_to_human\u003c\/strong\u003e — Chuyển sang nhân viên thật khi cần\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003cp\u003eBài tiếp theo: tìm hiểu \u003cstrong\u003etool_choice parameter\u003c\/strong\u003e — cách kiểm soát chính xác khi nào Claude gọi tool, khi nào không, và cách ép buộc Claude dùng một tool cụ thể.\u003c\/p\u003e\n","brand":"Minh Tuấn","offers":[{"title":"Default Title","offer_id":47721765470420,"sku":null,"price":0.0,"currency_code":"VND","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0821\/0264\/9044\/files\/xay-d_ng-customer-service-agent-v_i-claude-tool-use.jpg?v=1774506563","url":"https:\/\/claude.vn\/en\/products\/xay-d%e1%bb%b1ng-customer-service-agent-v%e1%bb%9bi-claude-tool-use","provider":"CLAUDE.VN","version":"1.0","type":"link"}