Learn Multi-Tool Agent Orchestration

This tutorial shows you how to build a customer support agent to learn how agents orchestrate multiple tools, make context-aware decisions, and handle incomplete data.

The Agentic Data Plane is supported on BYOC clusters running with AWS and Redpanda version 25.3 and later.

After completing this tutorial, you will be able to:

  • Explain how agents use conversation context to decide which tools to invoke

  • Apply tool orchestration patterns to handle multi-step workflows

  • Evaluate how system prompt design affects agent tool selection

Why multi-tool orchestration matters

Agents become powerful when they coordinate multiple tools to solve complex problems. A single-tool agent can retrieve order status. A multi-tool agent can check order status, fetch tracking information, look up customer history, and decide which tools to invoke based on conversation context.

This tutorial teaches multi-tool orchestration through a customer support scenario.

The patterns you practice here apply to any multi-tool scenario: data analysis agents coordinating query and visualization tools, workflow automation agents chaining approval and notification tools, or research agents combining search and summarization tools.

The scenario

Customer support teams handle repetitive questions: "Where is my order?", "What’s my tracking number?", "Show me my order history." Human agents often waste time on lookups that could be automated.

An effective support agent needs three capabilities:

  • Order status lookup: Check current order state and contents

  • Shipping information: Retrieve tracking numbers and delivery estimates

  • Order history: Show past purchases for a customer

The challenge: users phrase requests differently ("Where’s my package?", "Track order ORD-12345", "My recent orders"), and agents must choose the right tool based on context.

Prerequisites

Design the MCP tools

Before an agent can orchestrate tools, you need tools to orchestrate. Each tool should do one thing well, returning structured data the agent can reason about.

You could create a single handle_customer_request tool that takes a natural language query and returns an answer. But, this approach fails because:

  • The agent can’t inspect intermediate results

  • Tool chaining becomes impossible (no way to pass order status to shipping lookup)

  • Error handling is opaque

Instead, create focused tools:

  • get_order_status: Returns order state and contents

  • get_shipping_info: Returns tracking data

  • get_customer_history: Returns past orders

This granularity enables the agent to chain tools (check order status, see it’s shipped, fetch tracking info) and handle errors at each step.

Deploy the tools

Create a Remote MCP server with the three tools.

  1. Navigate to your cluster in the Redpanda Cloud Console.

  2. Go to Agentic AI > Remote MCP.

  3. Click Create MCP Server.

  4. Configure the server:

    • Name: customer-support-tools

    • Description: Tools for customer support agent

  5. Add the following tools. For each tool, select Processor from the component type dropdown, then click Lint to validate:

    • get_order_status

    • get_shipping_info

    • get_customer_history

    This tool uses the mapping processor to return mock data. The mock approach enables testing without external dependencies. The agent must interpret the structured response to extract order details.

    label: get_order_status
    mapping: |
      let order_id = this.order_id
      root = if $order_id == "ORD-12345" {
            {
              "order_id": $order_id,
              "status": "shipped",
              "items": [{"name": "Laptop", "quantity": 1, "price": 1299.99}],
              "total": 1299.99,
              "order_date": "2025-01-10",
              "customer_id": "CUST-100"
            }
          } else if $order_id == "ORD-67890" {
            {
              "order_id": $order_id,
              "status": "processing",
              "items": [{"name": "Headphones", "quantity": 2, "price": 149.99}],
              "total": 299.98,
              "order_date": "2025-01-14",
              "customer_id": "CUST-100"
            }
          } else if $order_id == "ORD-99999" {
            {
              "error": "order_not_found",
              "message": "Order not found"
            }
          } else {
            {
              "order_id": $order_id,
              "status": "pending",
              "items": [{"name": "Generic Item", "quantity": 1, "price": 49.99}],
              "total": 49.99,
              "order_date": "2025-01-15",
              "customer_id": "CUST-999"
            }
          }
    
    meta:
      mcp:
        enabled: true
        description: "Retrieve order status and details. Use ORD-12345 (shipped), ORD-67890 (processing), or ORD-99999 (not found) for testing."
        properties:
          - name: order_id
            type: string
            description: "The order ID (format ORD-XXXXX)"
            required: true

    This tool demonstrates conditional data: it only returns tracking information when the order has shipped. When an order hasn’t shipped yet, the tool returns an empty result. The system prompt instructs the agent to explain that shipping info is unavailable for orders that haven’t shipped.

    label: get_shipping_info
    
    processors:
      - mapping: |
          let order_id = this.order_id
          root = if $order_id == "ORD-12345" {
            {
              "order_id": $order_id,
              "tracking_number": "FX1234567890",
              "carrier": "Example Shipping",
              "status": "in_transit",
              "estimated_delivery": "2025-01-17",
              "last_location": "San Francisco Distribution Center",
              "last_update": "2025-01-15T14:30:00Z"
            }
          } else if $order_id == "ORD-67890" {
            {
              "order_id": $order_id,
              "error": true,
              "message": "Order has not shipped yet"
            }
          } else {
            {
              "order_id": $order_id,
              "error": true,
              "message": "No shipping information available"
            }
          }
    
    meta:
      mcp:
        enabled: true
        description: "Get tracking and shipping information. ORD-12345 has shipping info, ORD-67890 has not shipped yet."
        properties:
          - name: order_id
            type: string
            description: "The order ID to track"
            required: true

    This tool returns multiple orders, demonstrating list-handling. The agent must format multiple results clearly for users.

    label: get_customer_history
    
    processors:
      - mapping: |
          let customer_id = this.customer_id
          root = if $customer_id == "CUST-100" {
            {
              "customer_id": $customer_id,
              "orders": [
                {"order_id": "ORD-12345", "status": "shipped", "total": 1299.99, "order_date": "2025-01-10"},
                {"order_id": "ORD-67890", "status": "processing", "total": 299.98, "order_date": "2025-01-14"},
                {"order_id": "ORD-11111", "status": "delivered", "total": 89.99, "order_date": "2024-12-20"}
              ],
              "total_orders": 3
            }
          } else if $customer_id == "CUST-999" {
            {
              "customer_id": $customer_id,
              "orders": [],
              "total_orders": 0,
              "message": "No orders found for this customer"
            }
          } else {
            {
              "error": true,
              "message": "Customer not found"
            }
          }
    
    meta:
      mcp:
        enabled: true
        description: "Retrieve order history. Use CUST-100 (has orders) or CUST-999 (no orders) for testing."
        properties:
          - name: customer_id
            type: string
            description: "The customer ID (format CUST-XXX)"
            required: true
  6. Click Create MCP Server.

Wait for the server status to show Running. You now have three focused tools the agent can orchestrate.

Write the system prompt

The system prompt teaches the agent how to orchestrate tools. Without explicit guidance, the agent must guess when to use each tool, often choosing incorrectly or ignoring tools entirely.

Create the agent

Create the customer support agent with the system prompt.

  1. Go to Agentic AI > AI Agents.

  2. Click Create Agent.

  3. Configure the agent:

    • Name: customer-support-agent

    • Description: Helps customers track orders and shipping

    • Resource Tier: Medium

    • AI Gateway: Select the gateway you configured

    • Provider: OpenAI or Anthropic

    • Model: OpenAI GPT-5.2 or Claude Sonnet 4.5 (models with strong reasoning)

    • MCP Server: Select customer-support-tools

    • Max Iterations: 15

  4. In the System Prompt field, enter this configuration:

    You are a customer support agent for Acme E-commerce.
    
    Responsibilities:
    - Help customers track their orders
    - Provide shipping information and estimated delivery dates
    - Look up customer order history
    - Answer questions about order status
    
    Available tools:
    - get_order_status: Use when customer asks about a specific order
    - get_shipping_info: Use when customer needs tracking or delivery information
    - get_customer_history: Use when customer asks about past orders or "my orders"
    
    When to use each tool:
    - If customer provides an order ID (ORD-XXXXX), use get_order_status first
    - If customer asks "where is my order?", ask for the order ID before using tools
    - If order is "shipped", follow up with get_shipping_info to provide tracking details
    - If customer asks about "all my orders" or past purchases, use get_customer_history
    
    Never:
    - Expose customer payment information (credit cards, billing addresses)
    - Make up tracking numbers or delivery dates
    - Guarantee delivery dates (use "estimated" language)
    - Process refunds or cancellations (escalate to human agent)
    
    Error handling:
    - If order not found, ask customer to verify the order ID
    - If shipping info unavailable, explain the order may not have shipped yet
    - If customer history is empty, confirm the customer ID and explain no orders found
    
    Response format:
    - Start with a friendly greeting
    - Present order details in a clear, structured way
    - For order status, include: order ID, status, items, total
    - For shipping, include: carrier, tracking number, estimated delivery, last known location
    - Always include next steps or offer additional help
    
    Example response structure:
    1. Acknowledge the customer's question
    2. Present the information from tools
    3. Provide next steps or additional context
    4. Ask if they need anything else
  5. Click Create Agent.

Wait for the agent status to show Running.

Observe orchestration in action

Open the Inspector tab in the Redpanda Cloud Console to interact with the agent.

Testing reveals how the agent makes decisions. Watch the conversation panel in the built-in chat interface to see the agent’s reasoning process unfold.

Tool chaining based on status

Test how the agent chains tools based on order status.

Enter this query in Inspector:

Hi, I'd like to check on order ORD-12345

Watch the conversation panel. The agent calls get_order_status first, sees the status is "shipped", then automatically follows up with get_shipping_info to provide tracking details. The agent uses the first tool’s result to decide whether to invoke the second tool.

Now try this query with a different order:

Check order ORD-67890

This order has status "processing", so the agent calls only get_order_status. Since the order hasn’t shipped yet, the agent skips get_shipping_info. The agent chains tools only when appropriate.

Clarification before tool invocation

Test how the agent handles incomplete information.

Click Clear context to clear the conversation history. Then enter this query:

Where is my order?

The agent recognizes the request is missing an order ID and asks the customer to provide it. Watch the conversation panel and see that the agent calls zero tools. Instead of guessing or fabricating information, it asks a clarifying question.

This demonstrates pre-condition checking. Effective orchestration includes knowing when NOT to invoke tools.

List handling

Test how the agent formats multiple results.

Enter this query:

Can you show me my recent orders? My customer ID is CUST-100.

The agent calls get_customer_history and receives multiple orders. Watch how it formats the list clearly for the customer, showing details for each order.

Now test the empty results case with this query:

Show my order history for customer ID CUST-999

The agent receives an empty list and explains that no orders were found, asking the customer to verify their ID.

Error recovery

Test how the agent handles missing data.

Enter this query:

Check order ORD-99999

The tool returns no data for this order ID. Watch how the agent responds. It explains the order wasn’t found and asks the customer to verify the order ID. Critically, the agent does not fabricate tracking numbers or order details.

This demonstrates error recovery without hallucination. The "Never make up tracking numbers" constraint in the system prompt prevents the agent from inventing plausible-sounding but incorrect information.

Troubleshoot

For comprehensive troubleshooting guidance, see Troubleshoot AI Agents.

Test with mock data

The mock tools in this tutorial only recognize specific test IDs:

  • Orders: ORD-12345, ORD-67890, ORD-99999

  • Customers: CUST-100, CUST-999

Use these documented test IDs when testing the agent. If you replace the mock tools with real API calls, verify that your API endpoints return the expected data structures.