客服智能体

构建带有工具调用能力的客户服务 Agent

🌐 查看英文原文 | 源码 Notebook


使用客户端工具创建客户服务 Agent

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

第一步:设置环境

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

%pip install anthropic
import anthropic

client = anthropic.Client()
MODEL_NAME = "claude-opus-4-1"

第二步:定义客户端工具

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

tools = [
    {
        "name": "get_customer_info",
        "description": "Retrieves customer information based on their customer ID. Returns the customer's name, email, and phone number.",
        "input_schema": {
            "type": "object",
            "properties": {
                "customer_id": {
                    "type": "string",
                    "description": "The unique identifier for the customer.",
                }
            },
            "required": ["customer_id"],
        },
    },
    {
        "name": "get_order_details",
        "description": "Retrieves the details of a specific order based on the order ID. Returns the order ID, product name, quantity, price, and order status.",
        "input_schema": {
            "type": "object",
            "properties": {
                "order_id": {
                    "type": "string",
                    "description": "The unique identifier for the order.",
                }
            },
            "required": ["order_id"],
        },
    },
    {
        "name": "cancel_order",
        "description": "Cancels an order based on the provided order ID. Returns a confirmation message if the cancellation is successful.",
        "input_schema": {
            "type": "object",
            "properties": {
                "order_id": {
                    "type": "string",
                    "description": "The unique identifier for the order to be cancelled.",
                }
            },
            "required": ["order_id"],
        },
    },
]

第三步:模拟合成工具响应

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

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

第四步:处理工具调用并返回结果

我们将创建一个函数来处理 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"])

第五步:与聊天机器人交互

现在,让我们创建一个与聊天机器人交互的函数。我们将发送用户消息,处理 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("\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("Tool Input:")
        print(json.dumps(tool_input, indent=2))

        tool_result = process_tool_call(tool_name, tool_input)

        print("\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("\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

第六步:测试聊天机器人

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

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.'

就这样!我们已经使用 Claude 3 模型和客户端工具创建了一个客户服务聊天机器人。该聊天机器人可以根据用户的请求查找客户信息、获取订单详情和取消订单。通过定义清晰的工具描述和模式,我们使 Claude 能够有效地理解和使用可用的工具来协助客户。

您可以通过集成真实的客户数据库和订单管理系统,以及添加更多工具来处理更广泛的客户服务任务,来扩展此示例。


Tip

中文读者提示:本章节的代码和输出为英文原文。如需理解具体实现细节,可参考上方中文导读和代码注释。如有疑问,欢迎在 GitHub Issues 讨论。