使用客户端工具创建客服代理

在本教程中,我们将演示如何使用 Claude 3 和客户端工具创建客服聊天机器人。该聊天机器人将能够代表客户查询客户信息、检索订单详情以及取消订单。我们将定义必要的工具并模拟合成响应来展示聊天机器人的功能。

步骤 1:设置环境

首先,让我们安装所需的库并设置 Anthropic API 客户端。

%pip install anthropic
import anthropic

client = anthropic.Client()
MODEL_NAME = "claude-3-opus-20240229"

步骤 2:定义客户端工具

接下来,我们将定义聊天机器人将用于协助客户的客户端工具。我们将创建三个工具:get_customer_infoget_order_detailscancel_order

tools = [
    {
        "name": "get_customer_info",
        "description": "根据客户 ID 检索客户信息。返回客户姓名、电子邮件和电话号码。",
        "input_schema": {
            "type": "object",
            "properties": {
                "customer_id": {
                    "type": "string",
                    "description": "客户的唯一标识符。"
                }
            },
            "required": ["customer_id"]
        }
    },
    {
        "name": "get_order_details",
        "description": "根据订单 ID 检索特定订单的详细信息。返回订单 ID、产品名称、数量、价格和订单状态。",
        "input_schema": {
            "type": "object",
            "properties": {
                "order_id": {
                    "type": "string",
                    "description": "订单的唯一标识符。"
                }
            },
            "required": ["order_id"]
        }
    },
    {
        "name": "cancel_order",
        "description": "根据提供的订单 ID 取消订单。如果取消成功,则返回确认消息。",
        "input_schema": {
            "type": "object",
            "properties": {
                "order_id": {
                    "type": "string",
                    "description": "要取消的订单的唯一标识符。"
                }
            },
            "required": ["order_id"]
        }
    }
]

步骤 3:模拟合成工具响应

由于我们没有真实的客户数据或订单信息,我们将为我们的工具模拟合成响应。在实际场景中,这些函数将与您的实际客户数据库和订单管理系统进行交互。

def get_customer_info(customer_id):
    # Simulated customer data
    customers = {
        "C1": {"name": "John Doe", "email": "john@example.com", "phone": "123-456-7890"},
        "C2": {"name": "Jane Smith", "email": "jane@example.com", "phone": "987-654-3210"}
    }
    return customers.get(customer_id, "Customer not found")

def get_order_details(order_id):
    # Simulated order data
    orders = {
        "O1": {"id": "O1", "product": "Widget A", "quantity": 2, "price": 19.99, "status": "Shipped"},
        "O2": {"id": "O2", "product": "Gadget B", "quantity": 1, "price": 49.99, "status": "Processing"}
    }
    return orders.get(order_id, "Order not found")

def cancel_order(order_id):
    # Simulated order cancellation
    if order_id in ["O1", "O2"]:
        return True
    else:
        return False

步骤 4:处理工具调用并返回结果

我们将创建一个函数来处理 Claude 制作的工具调用并返回适当的结果。

def process_tool_call(tool_name, tool_input):
    if tool_name == "get_customer_info":
        return get_customer_info(tool_input["customer_id"])
    elif tool_name == "get_order_details":
        return get_order_details(tool_input["order_id"])
    elif tool_name == "cancel_order":
        return cancel_order(tool_input["order_id"])

步骤 5:与聊天机器人互动

现在,让我们创建一个与聊天机器人互动的函数。我们将发送用户消息,处理 Claude 制作的任何工具调用,并将最终响应返回给用户。

import json

def chatbot_interaction(user_message):
    print(f"\n{'='*50}\nUser Message: {user_message}\n{'='*50}")

    messages = [
        {"role": "user", "content": user_message}
    ]

    response = client.messages.create(
        model=MODEL_NAME,
        max_tokens=4096,
        tools=tools,
        messages=messages
    )

    print(f"\nInitial Response:")
    print(f"Stop Reason: {response.stop_reason}")
    print(f"Content: {response.content}")

    while response.stop_reason == "tool_use":
        tool_use = next(block for block in response.content if block.type == "tool_use")
        tool_name = tool_use.name
        tool_input = tool_use.input

        print(f"\nTool Used: {tool_name}")
        print(f"Tool Input:")
        print(json.dumps(tool_input, indent=2))

        tool_result = process_tool_call(tool_name, tool_input)

        print(f"\nTool Result:")
        print(json.dumps(tool_result, indent=2))

        messages = [
            {"role": "user", "content": user_message},
            {"role": "assistant", "content": response.content},
            {
                "role": "user",
                "content": [
                    {
                        "type": "tool_result",
                        "tool_use_id": tool_use.id,
                        "content": str(tool_result),
                    }
                ],
            },
        ]

        response = client.messages.create(
            model=MODEL_NAME,
            max_tokens=4096,
            tools=tools,
            messages=messages
        )

        print(f"\nResponse:")
        print(f"Stop Reason: {response.stop_reason}")
        print(f"Content: {response.content}")

    final_response = next(
        (block.text for block in response.content if hasattr(block, "text")),
        None,
    )

    print(f"\nFinal Response: {final_response}")

    return final_response

步骤 6:测试聊天机器人

让我们用几个示例查询来测试我们的客服聊天机器人。

chatbot_interaction("Can you tell me the email address for customer C1?")
chatbot_interaction("What is the status of order O2?")
chatbot_interaction("Please cancel order O1 for me.")
==================================================
User Message: Can you tell me the email address for customer C1?
==================================================

Initial Response:
Stop Reason: tool_use
Content: [ContentBlock(text='<thinking>The get_customer_info function retrieves a customer\'s name, email, and phone number given their customer ID. To call this function, I need the customer_id parameter. The user provided the customer ID "C1" in their request, so I have the necessary information to make the API call.</thinking>', type='text'), ContentBlockToolUse(id='toolu_019F9JHokMkJ1dHw5BEh28sA', input={'customer_id': 'C1'}, name='get_customer_info', type='tool_use')]

Tool Used: get_customer_info
Tool Input:
{
  "customer_id": "C1"
}

Tool Result:
{
  "name": "John Doe",
  "email": "john@example.com",
  "phone": "123-456-7890"
}

Response:
Stop Reason: end_turn
Content: [ContentBlock(text='The email address for customer C1 (John Doe) is john@example.com.', type='text')]

Final Response: The email address for customer C1 (John Doe) is john@example.com.

==================================================
User Message: What is the status of order O2?
==================================================

Initial Response:
Stop Reason: tool_use
Content: [ContentBlock(text='<thinking>\nBased on the provided functions, the most relevant one for this request is get_order_details, which takes an order_id parameter and returns details about that specific order, including the order status.\n\nThe user has provided an order ID in their request - "O2". So the required order_id parameter can be filled with this value.\n\nSince the required parameter is available, I can proceed with calling the get_order_details function to retrieve the order status for order O2.\n</thinking>', type='text'), ContentBlockToolUse(id='toolu_01K1u68uC94edXx8MVT35eR3', input={'order_id': 'O2'}, name='get_order_details', type='tool_use')]

Tool Used: get_order_details
Tool Input:
{
  "order_id": "O2"
}

Tool Result:
{
  "id": "O2",
  "product": "Gadget B",
  "quantity": 1,
  "price": 49.99,
  "status": "Processing"
}

Response:
Stop Reason: end_turn
Content: [ContentBlock(text='Based on the details returned from the get_order_details function, the status of order O2 is "Processing".', type='text')]

Final Response: Based on the details returned from the get_order_details function, the status of order O2 is "Processing".

==================================================
User Message: Please cancel order O1 for me.
==================================================

Initial Response:
Stop Reason: tool_use
Content: [ContentBlock(text='<thinking>\nThe relevant tool to cancel an order is the cancel_order function. \nThis function requires an order_id parameter.\nThe user provided the order ID "O1" in their request, so we have the necessary parameter to call the cancel_order function.\n</thinking>', type='text'), ContentBlockToolUse(id='toolu_01W3ZkP2QCrjHf5bKM6wvT2s', input={'order_id': 'O1'}, name='cancel_order', type='tool_use')]

Tool Used: cancel_order
Tool Input:
{
  "order_id": "O1"
}

Tool Result:
true

Response:
Stop Reason: end_turn
Content: [ContentBlock(text='Based on the confirmation received, your order O1 has been successfully cancelled. Please let me know if there is anything else I can assist you with.', type='text')]

Final Response: Based on the confirmation received, your order O1 has been successfully cancelled. Please let me know if there is anything else I can assist you with.





'Based on the confirmation received, your order O1 has been successfully cancelled. Please let me know if there is anything else I can assist you with.'

And that's it! We've created a customer service chatbot using Claude 3 models and client-side tools. The chatbot can look up customer information, retrieve order details, and cancel orders based on the user's requests. By defining clear tool descriptions and schemas, we enable Claude to effectively understand and utilize the available tools to assist customers.

Feel free to expand on this example by integrating with your actual customer database and order management system, and by adding more tools to handle a wider range of customer service tasks.