Lab 1: Creating a simple customer support agent prototype

Author: Aarushi Nema
Date: 2025-09-17
Tags: Customer Support Agent, Amazon BedRock AgentCore, AWS, Machine Learning, Agentic AI, AI, Workshop, Project, Production, Cloud Computing, Strands Agents, Anthropic Claude, Bedrock, Prototype
Categories: Machine Learning, Agentic AI, AWS, Workshop
Abstract: This lab is part of the AWS Users Group Workshop on 17th September, 2025. The goal is to build a comprehensive, production-ready customer support agent using Amazon Bedrock AgentCore and Strands Agents framework.

Overview

Amazon Bedrock AgentCore helps you deploying and operating AI agents securely at scale - using any framework and model. It provides you with the capability to move from prototype to production faster.

In this 5-labs tutorial, we will demonstrate the end-to-end journey from prototype to production using a Customer Support Agent. For this example we will use Strands Agents, a simple-to-use, code-first framework for building agents and the Anthropic Claude Sonnet 3.7 model from Amazon Bedrock. For your application you can use the framework and model of your choice. It’s important to note that the concepts covered here can be applied using other frameworks and models as well.

Workshop Journey: - Lab 1 (Current): Create Agent Prototype - Build a functional customer support agent - Lab 2: Enhance with Memory - Add conversation context and personalization - Lab 3: Scale with Gateway & Identity - Share tools across agents securely - Lab 4: Deploy to Production - Use AgentCore Runtime with observability - Lab 5: Build User Interface - Create a customer-facing application

In this first lab, we’ll build a Customer Support Agent prototype that will evolve throughout the workshop into a production-ready system serving multiple customers with persistent memory, shared tools, and full observability. Our agent will have the following local tools available: - get_return_policy() - Get return policy for specific products - get_product_info() - Get product information - web_search() - Search the web for troubleshooting help - get_technical_support() - Search a Bedrock Knowledge Base

Learning Objectives

  • Create tools using the @tool decorator
  • Initialize a Strands Agent with model and tools
  • Test Agent locally in a Jupyter Notebook
  • Understand the basic architecture of AI agents
  • Learn about Amazon Bedrock AgentCore capabilities

Architecture for Lab 1

<img src="images/architecture_lab1_strands.png" width="75%"/>

Simple prototype running locally. In subsequent labs, we’ll migrate this to AgentCore services with shared tools, persistent memory, and production-grade observability.

Prerequisites

  • AWS Account with appropriate permissions
  • Python 3.10+ installed locally
  • AWS CLI configured with credentials
  • Anthropic Claude 3.7 enabled on Amazon Bedrock
  • Strands Agents and other libraries installed in the next cells

Step 1: Install Dependencies and Import Libraries

Before we start, let’s install the pre-requisites for this lab

# Install required packages
%pip install -U -r requirements.txt -q
Note: you may need to restart the kernel to use updated packages.

We can now import the required libraries and initialize our boto3 session

# Import libraries
import boto3
from boto3.session import Session

from ddgs.exceptions import DDGSException, RatelimitException
from ddgs import DDGS

from strands.tools import tool
from lab_helpers.utils import put_ssm_parameter
# Get boto session
boto_session = Session()
region = boto_session.region_name

Step 2: Implementing custom tools

Next, we will implement the 3 tools which will be provided to the Customer Support Agent.

Defining tools in Strands Agent is extremely simple, just add a @tool decorator to your function, and provide a description of the tool in the function’s docstring. Strands Agents will use the function documentation, typing and arguments to provide context on this tool to your agent.

Tool 1: Get Return Policy

Purpose: This tool helps customers understand return policies for different product categories. It provides detailed information about return windows, conditions, processes, and refund timelines so customers know exactly what to expect when returning items.

# @tool -> for agent to communicate with 
@tool
def get_return_policy(product_category: str) -> str:
    """
    Get return policy information for a specific product category.

    Args:
        product_category: Electronics category (e.g., 'smartphones', 'laptops', 'accessories')

    Returns:
        Formatted return policy details including timeframes and conditions
    """
    # Mock return policy database - in real implementation, this would query policy database
    return_policies = {
        "smartphones": {
            "window": "30 days",
            "condition": "Original packaging, no physical damage, factory reset required",
            "process": "Online RMA portal or technical support",
            "refund_time": "5-7 business days after inspection",
            "shipping": "Free return shipping, prepaid label provided",
            "warranty": "1-year manufacturer warranty included"
        },
         "laptops": {
            "window": "30 days", 
            "condition": "Original packaging, all accessories, no software modifications",
            "process": "Technical support verification required before return",
            "refund_time": "7-10 business days after inspection",
            "shipping": "Free return shipping with original packaging",
            "warranty": "1-year manufacturer warranty, extended options available"
        },
        "accessories": {
            "window": "30 days",
            "condition": "Unopened packaging preferred, all components included",
            "process": "Online return portal",
            "refund_time": "3-5 business days after receipt",
            "shipping": "Customer pays return shipping under $50",
            "warranty": "90-day manufacturer warranty"
        }
    }

    # Default policy for unlisted categories
    default_policy = {
        "window": "30 days",
        "condition": "Original condition with all included components",
        "process": "Contact technical support",
        "refund_time": "5-7 business days after inspection", 
        "shipping": "Return shipping policies vary",
        "warranty": "Standard manufacturer warranty applies"
    }

    policy = return_policies.get(product_category.lower(), default_policy)
    return f"Return Policy - {product_category.title()}:\n\n" \
           f"• Return window: {policy['window']} from delivery\n" \
           f"• Condition: {policy['condition']}\n" \
           f"• Process: {policy['process']}\n" \
           f"• Refund timeline: {policy['refund_time']}\n" \
           f"• Shipping: {policy['shipping']}\n" \
           f"• Warranty: {policy['warranty']}"
print("✅ Return policy tool ready")
✅ Return policy tool ready

Tool 2: Get Product Information

Purpose: This tool provides customers with comprehensive product details including warranties, available models, key features, shipping policies, and return information. It helps customers make informed purchasing decisions and understand what they’re buying.

@tool
def get_product_info(product_type: str) -> str:
    """
    Get detailed technical specifications and information for electronics products.

    Args:
        product_type: Electronics product type (e.g., 'laptops', 'smartphones', 'headphones', 'monitors')
    Returns:
        Formatted product information including warranty, features, and policies
    """
    # Mock product catalog - in real implementation, this would query a product database
    products = {
        "laptops": {
            "warranty": "1-year manufacturer warranty + optional extended coverage",
            "specs": "Intel/AMD processors, 8-32GB RAM, SSD storage, various display sizes",
            "features": "Backlit keyboards, USB-C/Thunderbolt, Wi-Fi 6, Bluetooth 5.0",
            "compatibility": "Windows 11, macOS, Linux support varies by model",
            "support": "Technical support and driver updates included"
        },
        "smartphones": {
            "warranty": "1-year manufacturer warranty",
            "specs": "5G/4G connectivity, 128GB-1TB storage, multiple camera systems",
            "features": "Wireless charging, water resistance, biometric security",
            "compatibility": "iOS/Android, carrier unlocked options available",
            "support": "Software updates and technical support included"
        },
        "headphones": {
            "warranty": "1-year manufacturer warranty",
            "specs": "Wired/wireless options, noise cancellation, 20Hz-20kHz frequency",
            "features": "Active noise cancellation, touch controls, voice assistant",
            "compatibility": "Bluetooth 5.0+, 3.5mm jack, USB-C charging",
            "support": "Firmware updates via companion app"
        },
        "monitors": {
            "warranty": "3-year manufacturer warranty",
            "specs": "4K/1440p/1080p resolutions, IPS/OLED panels, various sizes",
            "features": "HDR support, high refresh rates, adjustable stands",
            "compatibility": "HDMI, DisplayPort, USB-C inputs",
            "support": "Color calibration and technical support"
        }
    }
    product = products.get(product_type.lower())
    if not product:
        return f"Technical specifications for {product_type} not available. Please contact our technical support team for detailed product information and compatibility requirements."

    return f"Technical Information - {product_type.title()}:\n\n" \
           f"• Warranty: {product['warranty']}\n" \
           f"• Specifications: {product['specs']}\n" \
           f"• Key Features: {product['features']}\n" \
           f"• Compatibility: {product['compatibility']}\n" \
           f"• Support: {product['support']}"

print("✅ get_product_info tool ready")
✅ get_product_info tool ready

Customer Support Agent - Knowledge Base Integration Steps

Download product technical_support files from S3
# Download and ingest file into BedRock Ecosystem
import os

def download_files():
    # Get account and region
    account_id = boto3.client('sts').get_caller_identity()['Account']
    region = boto3.Session().region_name
    bucket_name = f"{account_id}-{region}-kb-data-bucket"
    
    # Create local folder
    os.makedirs("knowledge_base_data", exist_ok=True)
    
    # Download all files
    s3 = boto3.client('s3')
    objects = s3.list_objects_v2(Bucket=bucket_name)
    
    for obj in objects['Contents']:
        file_name = obj['Key']
        s3.download_file(bucket_name, file_name, f"knowledge_base_data/{file_name}")
        print(f"Downloaded: {file_name}")
    
    print(f"All files saved to: knowledge_base_data/")

# Run it
download_files()
Downloaded: laptop-maintenance-guide.txt
Downloaded: monitor-calibration-guide.txt
Downloaded: smartphone-setup-guide.txt
Downloaded: troubleshooting-guide.txt
Downloaded: warranty-service-guide.txt
Downloaded: wireless-connectivity-guide.txt
All files saved to: knowledge_base_data/

Knowledge Base Sync Job

Sync the knowledge base with product technical_support files from S3 which can be integrated with the agent
import boto3
import time

# Get parameters
ssm = boto3.client('ssm')
bedrock = boto3.client('bedrock-agent')
s3 = boto3.client('s3')

account_id = boto3.client('sts').get_caller_identity()['Account']
region = boto3.Session().region_name

kb_id = ssm.get_parameter(Name=f"/{account_id}-{region}/kb/knowledge-base-id")['Parameter']['Value']
ds_id = ssm.get_parameter(Name=f"/{account_id}-{region}/kb/data-source-id")['Parameter']['Value']

# Get file names from S3 bucket
bucket_name = f"{account_id}-{region}-kb-data-bucket"
s3_objects = s3.list_objects_v2(Bucket=bucket_name)
file_names = [obj['Key'] for obj in s3_objects.get('Contents', [])]

# Start sync job
response = bedrock.start_ingestion_job(
    knowledgeBaseId=kb_id,
    dataSourceId=ds_id,
    description="Quick sync"
)

job_id = response['ingestionJob']['ingestionJobId']
print("Bedrock knowledge base sync job started, ingesting the data files from s3")

# Monitor until complete
while True:
    job = bedrock.get_ingestion_job(
        knowledgeBaseId=kb_id,
        dataSourceId=ds_id,
        ingestionJobId=job_id
    )['ingestionJob']
    
    status = job['status']
    
    if status in ['COMPLETE', 'FAILED']:
        break
        
    time.sleep(10)

# Print final result
if status == 'COMPLETE':
    file_count = job.get('statistics', {}).get('numberOfDocumentsScanned', 0)
    files_list = ', '.join(file_names)
    print(f"Bedrock knowledge base sync job completed Successfully, ingested {file_count} files")
    print(f"Files ingested: {files_list}")
else:
    print(f"Bedrock knowledge base sync job failed with status: {status}")
Bedrock knowledge base sync job started, ingesting the data files from s3
Bedrock knowledge base sync job completed Successfully, ingested 6 files
Files ingested: laptop-maintenance-guide.txt, monitor-calibration-guide.txt, smartphone-setup-guide.txt, troubleshooting-guide.txt, warranty-service-guide.txt, wireless-connectivity-guide.txt

Tool 4: Get Technical Support

Purpose: This tool provides customers with comprehensive technical support and troubleshooting assistance by accessing our knowledge base of electronics documentation. It includes detailed setup guides, maintenance instructions, troubleshooting steps, connectivity solutions, and warranty service information. This tool helps customers resolve technical issues, properly configure their devices, and understand maintenance requirements for optimal product performance.

import os
from strands.tools.mcp.mcp_client import MCPClient
from mcp.client.stdio import stdio_client
from mcp.client.stdio import StdioServerParameters
from strands.models import BedrockModel
from strands import Agent
from strands_tools import retrieve

@tool
def get_technical_support(issue_description: str) -> str:
    try:
        # Get KB ID from parameter store
        ssm = boto3.client('ssm')
        account_id = boto3.client('sts').get_caller_identity()['Account']
        region = boto3.Session().region_name

        kb_id = ssm.get_parameter(Name=f"/{account_id}-{region}/kb/knowledge-base-id")['Parameter']['Value']
        print(f"Successfully retrieved KB ID: {kb_id}")

        # Use strands retrieve tool
        tool_use = {
            "toolUseId": "tech_support_query",
            "input": {
                "text": issue_description,
                "knowledgeBaseId": kb_id,
                "region": region,
                "numberOfResults": 3,
                "score": 0.4
            }
        }

        result = retrieve.retrieve(tool_use)

        if result["status"] == "success":
            return result["content"][0]["text"]
        else:
            return f"Unable to access technical support documentation. Error: {result['content'][0]['text']}"

    except Exception as e:
        print(f"Detailed error in get_technical_support: {str(e)}")
        return f"Unable to access technical support documentation. Error: {str(e)}"

print("✅ Technical support tool ready")
✅ Technical support tool ready

Step 4: Create and Configure the Customer Support Agent

Next, we will create the Customer Support Agent providing a model, the list of tools implemented in the previous step, and with a system prompt.

from strands import Agent
from strands.models import BedrockModel

SYSTEM_PROMPT = """You are a helpful and professional customer support assistant for an electronics e-commerce company.
Your role is to:
- Provide accurate information using the tools available to you
- Support the customer with technical information and product specifications, and maintenance questions
- Be friendly, patient, and understanding with customers
- Always offer additional help after answering questions
- If you can't help with something, direct customers to the appropriate contact

You have access to the following tools:
1. get_return_policy() - For warranty and return policy questions
2. get_product_info() - To get information about a specific product
3. web_search() - To access current technical documentation, or for updated information. 
4. get_technical_support() - For troubleshooting issues, setup guides, maintenance tips, and detailed technical assistance
For any technical problems, setup questions, or maintenance concerns, always use the get_technical_support() tool as it contains our comprehensive technical documentation and step-by-step guides.

Always use the appropriate tool to get accurate, up-to-date information rather than making assumptions about electronic products or specifications."""

# Initialize the Bedrock model (Anthropic Claude 3.7 Sonnet)
model = BedrockModel(
    model_id="us.anthropic.claude-3-7-sonnet-20250219-v1:0",
    temperature=0.3,
    region_name=region
)

# Create the customer support agent with all tools
agent = Agent(
    model=model,
    tools=[
        get_product_info,  # Tool 1: Simple product information lookup
        get_return_policy,  # Tool 2: Simple return policy lookup
        web_search, # Tool 3: Access the web for updated information
        get_technical_support   # Tool 4: Technical support & troubleshooting
    ],
    system_prompt=SYSTEM_PROMPT,
)

print("Customer Support Agent created successfully!")
Customer Support Agent created successfully!

Step 5: Test the Customer Support Agent

Let’s test our agent with sample queries to ensure all tools work correctly.

Test Return check

response = agent("What's the return policy for my thinkpad X1 Carbon?")
I'd be happy to provide you with information about the return policy for your ThinkPad X1 Carbon. Let me look that up for you.
Tool #1: get_return_policy
Thank you for your patience. Here's the return policy for your ThinkPad X1 Carbon:

**Return Policy for Laptops (including ThinkPad X1 Carbon):**
- You have a 30-day return window from the date of delivery
- The laptop must be returned in its original packaging with all accessories included
- No software modifications should be made to the device
- Before processing a return, our technical support team will need to verify the condition
- Once approved and inspected, refunds are processed within 7-10 business days
- Return shipping is free when using the original packaging
- Your ThinkPad X1 Carbon comes with a 1-year manufacturer warranty, with options to extend

Is there anything specific about the return policy you'd like me to clarify? Or perhaps you're experiencing an issue with your ThinkPad that I could help troubleshoot?
response = agent("My laptop won't turn on, what should I check?")
I'd be happy to help you troubleshoot your laptop that won't turn on. Let me get some technical support information for you.
Tool #6: get_technical_support
Successfully retrieved KB ID: LJ150KSVHW
Based on the technical support information, here are the steps you should take when your laptop won't turn on:

### Initial Power Troubleshooting Steps:

1. **Check Power Cable Connections**
   - Ensure the power adapter is firmly connected to both your laptop and the wall outlet
   - Look for any visible damage to the cable (fraying, bent pins, etc.)
   - Check that the connection point on the laptop isn't loose or damaged

2. **Verify Power Outlet Functionality**
   - Try plugging another device into the same outlet to confirm it's working
   - Try a different power outlet to rule out electrical issues
   - If using a power strip or surge protector, try bypassing it and plugging directly into the wall

3. **Try a Different Power Cable if Available**
   - If you have access to another compatible power adapter, see if that resolves the issue
   - This can help determine if the problem is with the adapter rather than the laptop

4. **Check for Physical Damage**
   - Inspect your laptop for any signs of physical damage
   - Look for liquid damage indicators if applicable

### Additional Troubleshooting Steps:

1. **Battery Reset**
   - If your laptop has a removable battery, remove it and the power cable
   - Hold the power button for 30 seconds to discharge any residual power
   - Reconnect the battery and power cable, then try turning it on again

2. **Check for Signs of Life**
   - Look for any LED indicators that might light up when connected to power
   - Listen for fan noise or hard drive spinning
   - Check if the caps lock or num lock keys respond with their indicator lights

3. **External Display Test**
   - Connect your laptop to an external monitor to see if it's just a display issue
   - If the external monitor works, your laptop is powering on but has a screen issue

If none of these steps resolve the issue, your laptop might have a more serious hardware problem such as a failed motherboard, power supply, or other internal component that would require professional service.

Would you like me to provide more details on any of these troubleshooting steps? Or would you like information about our repair services for your laptop?

Test Troubleshooting

response = agent("I bought an iphone 14 last month. I don't like it because it heats up. How do I solve it?")
I'm sorry to hear about the heating issue with your iPhone 14. Let me help you troubleshoot this problem. First, let me get some technical support information for you.
Tool #3: get_technical_support
Successfully retrieved KB ID: LJ150KSVHW
I see that the technical support information doesn't provide specific guidance for iPhone overheating issues. Let me search for more current information about iPhone 14 heating problems and solutions.
Tool #4: web_search
Now, let me also check if there's any specific product information about the iPhone 14 that might be relevant to your issue.
Tool #5: get_product_info
Based on the information I've gathered, here are some solutions to help with your iPhone 14 overheating issue:

### Why iPhones Can Overheat:
- Resource-intensive apps running in the background
- Software bugs in iOS updates
- Charging while using demanding applications
- Environmental factors (direct sunlight, hot environments)
- Hardware issues (rare but possible)

### Solutions to Fix iPhone 14 Overheating:

1. **Update iOS to the Latest Version**
   - Go to Settings > General > Software Update
   - Install any available updates as they often include thermal management improvements

2. **Check and Close Background Apps**
   - Double-click the home button or swipe up from the bottom (depending on your model) to view open apps
   - Swipe up on apps to close them, especially resource-intensive ones like games or navigation

3. **Manage Battery-Draining Features**
   - Reduce screen brightness (Settings > Display & Brightness)
   - Turn off unnecessary location services (Settings > Privacy > Location Services)
   - Disable Background App Refresh (Settings > General > Background App Refresh)

4. **Remove Case Temporarily**
   - Some cases can trap heat; try using your iPhone without its case to see if it helps

5. **Avoid Direct Sunlight and Hot Environments**
   - Keep your iPhone away from heat sources and direct sunlight

6. **Check for Problematic Apps**
   - Go to Settings > Battery to see which apps use the most power
   - Update or delete apps that might be causing excessive heat

7. **Reset All Settings**
   - Settings > General > Reset > Reset All Settings (this won't delete your data)

If you've tried these solutions and your iPhone 14 still overheats excessively, it might indicate a hardware issue. Since you purchased it last month, your device is still under the 1-year manufacturer warranty, and you have options:

1. **Contact Apple Support** for further assistance
2. **Visit an Apple Store** for a hardware diagnosis
3. **Consider returning the device** - Since you mentioned you don't like it and it's only been a month, you might still be within the return window

Would you like me to provide more details on any of these solutions? Or would you like information about the return policy for smartphones if you decide you want to return it?

🎉 Lab 1 Complete!

You’ve successfully created a functional Customer Support Agent prototype! Here’s what you accomplished:

  • Built an agent with 3 custom tools (return policy, product info, web search)
  • Tested multi-tool interactions and web search capabilities
  • Established the foundation for our production journey

Current Limitations (We’ll fix these!)

  • Single user conversation memory - local conversation session, multiple customers need multiple sessions.
  • Conversation history limited to session - no long term memory or cross session information is available in the conversation.
  • Tools reusability - tools aren’t reusable across different agents
  • Running locally only - not scalable
  • Identity - No user and/or agent identity or access control
  • Observability - Limited observability into agent behavior
  • Existing APIs - No access to existing enterprise APIs for customer data
Next Up Lab 2: Personalize our agent by adding memory →