DEV Community

Cover image for Bake a simple Agent in Sagemaker AI notebook
Nandini Rajaram for AWS Community Builders

Posted on Originally published at builder.aws.com

Bake a simple Agent in Sagemaker AI notebook

Prerequistes

Login to AWS account using an I AM user with admin access

Navigate to Sage Maker AI from Console

Click on Notebooks from Left Panel navigate to notebook instance creation page

Click Create a Notebook instance Button to create notebook instance

Enter a name for the Notebook Instance and leave all other configuration settings at their default values and Click Create Notebook Instance button to proceed further

Wait a few minutes until the Notebook Instance status changes from Pending to InService.

SageMaker Notebook Instance: Pricing and Precautions

Pricing: You pay for the time your notebook runs, its storage, and any other AWS services you use.

Free Tier: Eligible users may receive 250 hours per month of  ml.t3.medium  notebook usage for the first two months, subject to AWS terms.

Choose a small instance: Start with  ml.t3.medium  for basic notebook development if available.

Stop when finished: Stop your notebook instance after completing your work to avoid unnecessary compute charges.

Storage charges: Storage costs may continue even when the instance is stopped.

Bedrock charges: Using Amazon Bedrock models may incur separate charges.

Delete when no longer needed: Back up your notebooks before deleting the instance.

Monitor costs: Set up an AWS Budget alert to track spending.

Remember: Stop your notebook when you are not using it, and check your AWS bill regularly.

Lets Start Adding Ingredients for making the Agent

Click on  Open JupyterLab  link to open the IDE

As the notebook opens up, click on conda_python3 under notebooks section (the kernel ) to create an ipynbfile. Intially Untitled.ipynb file will be created and You can Rename it by right clicking the file and Choosing the RenameOption

I have Renamed the file to SimpleAgent.ipynb . Now Lets Begin adding the python commands to cell and execute them one by one

Strands Agent with Tools on Amazon Bedrock

Strands Agents is an open-source Python SDK that helps you build AI agents that can understand user requests, use tools, and perform tasks. It can connect to AI models such as Amazon Bedrock models. It is a tool that helps you build AI assistants that can do tasks, not just answer questions.
Think of it like a personal assistant 🤖:
You ask: “What's the weather in Bengaluru?”

AI thinks: “I need to check the weather.”

It uses a tool: Calls a real weather API.

It answers: Tells you the current weather.

In simple words, Strands Agents connects an AI model with tools so it can perform tasks for you.
In your SageMaker notebook, you built an AI assistant using Strands Agents and Amazon Bedrock, with tools for calculations and checking live weather.


I am going to create A beginner-friendly example of building a Strands Agents agent in an AWS SageMaker AI Jupyter notebook, using Amazon Bedrock as the model provider.
What this notebook does
Uses an Amazon Bedrock foundation model through Strands.

Calls a  calculate  tool for simple arithmetic.

Calls a  get_weather  tool with sample weather data.

Lets the model decide which tool to use based on the user's question.

The weather tool uses sample data; it does not call a live weather API.

Before you run it
Use a SageMaker execution role or AWS credentials with permission to invoke the selected Bedrock model ( bedrock:InvokeModel ).

Ensure the model is enabled/available in your AWS account and selected AWS Region in the Amazon Bedrock console.

Set  AWS_REGION  (or  AWS_DEFAULT_REGION ) if you do not want to use the default region below.

Let us start with the steps
Copy the code blocks to the cells and execute them one by one in the order by clicking the play button

Step 1 — Install Strands Agents and AWS SDK.

%pip install -q -U strands-agents boto3


%pip install -q requests
Enter fullscreen mode Exit fullscreen mode

Step 2 — Import libraries and configure Amazon Bedrock

 BedrockModel  tells Strands to send model requests to Amazon Bedrock. In SageMaker, prefer the notebook's execution role rather than hard-coding access keys.

import os
import boto3
from strands import Agent, tool
from strands.models import BedrockModel


# Use the SageMaker execution role / standard AWS credential chain.
# Set AWS_REGION or AWS_DEFAULT_REGION in your environment if needed.
aws_region = os.getenv("AWS_REGION") or os.getenv("AWS_DEFAULT_REGION") or "us-east-1"
model_id = os.getenv("BEDROCK_MODEL_ID", "amazon.nova-lite-v1:0")


# Optional early check that credentials and the chosen region are usable.
sts = boto3.client("sts", region_name=aws_region)
print("AWS identity:", sts.get_caller_identity().get("Arn", "available"))
print("Bedrock region:", aws_region)
print("Bedrock model ID:", model_id)


print("Strands Agents and Bedrock configuration loaded successfully!")

Enter fullscreen mode Exit fullscreen mode

Step 3 — Create a calculator tool

@tool
def calculate(expression: str) -> str:
    """Calculate a simple arithmetic expression.


    Args:
        expression: A mathematical expression such as "25 * 4" or "100 / 5".
    """
    try:
        # Keep this example limited to basic arithmetic.
        allowed = set("0123456789+-*/(). %")
        if not all(char in allowed for char in expression):
            return "I can only calculate basic arithmetic expressions."


        result = eval(expression, {"__builtins__": {}}, {})
        return str(result)
    except Exception as e:
        return f"Could not calculate the expression: {e}"
Enter fullscreen mode Exit fullscreen mode

The agent can call this Python function whenever it needs to perform a calculation.

Step 4 — Create a simple weather tool

This tool calls the Open-Meteo geocoding API to find a city and the Open-Meteo forecast API to retrieve its current weather. It does not require an API key.
The notebook environment needs outbound internet access. Open-Meteo API documentation:
Geocoding:  https://geocoding-api.open-meteo.com/v1/search 

Forecast:  https://api.open-meteo.com/v1/forecast

 

import requests


@tool
def get_weather(city: str) -> str:
    """Get current weather for a city using the live Open-Meteo API.


    Args:
        city: City name, for example "Bengaluru" or "London".
    """
    city = city.strip()
    if not city:
        return "Please provide a city name."


    try:
        # Resolve the city name to coordinates.
        geo_response = requests.get(
            "https://geocoding-api.open-meteo.com/v1/search",
            params={"name": city, "count": 1, "language": "en", "format": "json"},
            timeout=10,
        )
        geo_response.raise_for_status()
        locations = geo_response.json().get("results", [])


        if not locations:
            return f"I couldn't find a city named {city!r}. Check the spelling or include a country."


        location = locations[0]
        latitude = location["latitude"]
        longitude = location["longitude"]


        # Fetch current conditions for the resolved coordinates.
        weather_response = requests.get(
            "https://api.open-meteo.com/v1/forecast",
            params={
                "latitude": latitude,
                "longitude": longitude,
                "current": "temperature_2m,relative_humidity_2m,apparent_temperature,precipitation,weather_code,wind_speed_10m",
                "timezone": "auto",
            },
            timeout=10,
        )
        weather_response.raise_for_status()
        payload = weather_response.json()
        current = payload.get("current")


        if not current:
            return f"The weather API did not return current conditions for {location.get('name', city)}."


        # WMO weather interpretation codes used by Open-Meteo.
        weather_codes = {
            0: "clear sky",
            1: "mainly clear",
            2: "partly cloudy",
            3: "overcast",
            45: "fog",
            48: "depositing rime fog",
            51: "light drizzle",
            53: "moderate drizzle",
            55: "dense drizzle",
            56: "light freezing drizzle",
            57: "dense freezing drizzle",
            61: "slight rain",
            63: "moderate rain",
            65: "heavy rain",
            66: "light freezing rain",
            67: "heavy freezing rain",
            71: "slight snow",
            73: "moderate snow",
            75: "heavy snow",
            77: "snow grains",
            80: "slight rain showers",
            81: "moderate rain showers",
            82: "violent rain showers",
            85: "slight snow showers",
            86: "heavy snow showers",
            95: "thunderstorm",
            96: "thunderstorm with slight hail",
            99: "thunderstorm with heavy hail",
        }


        description = weather_codes.get(current.get("weather_code"), "conditions unavailable")
        place = location.get("name", city)
        admin = location.get("admin1")
        country = location.get("country")
        place_label = ", ".join(part for part in [place, admin, country] if part)


        return (
            f"Current weather for {place_label}: {description}; "
            f"temperature {current.get('temperature_2m')}°C; "
            f"feels like {current.get('apparent_temperature')}°C; "
            f"humidity {current.get('relative_humidity_2m')}%; "
            f"wind {current.get('wind_speed_10m')} km/h; "
            f"precipitation {current.get('precipitation')} mm. "
            f"Observation time: {current.get('time')} "
            f"(timezone: {payload.get('timezone', 'local')})."
        )
    except requests.RequestException as exc:
        return f"Couldn't retrieve live weather for {city} because the weather service request failed: {exc}"
    except (KeyError, TypeError, ValueError) as exc:
        return f"The weather service returned an unexpected response for {city}: {exc}"

Enter fullscreen mode Exit fullscreen mode

Step 5 — Configure the Strands Agent to use Bedrock

The agent uses the selected Bedrock foundation model and receives the two Python tools. It can decide when a tool is useful.

bedrock_model = BedrockModel(
    model_id=model_id,
    region_name=aws_region,
)



agent = Agent(
    model=bedrock_model,
    tools=[calculate, get_weather],
    system_prompt="""You are a friendly beginner assistant.
Use the available tools when they are useful.
Explain your answer clearly and briefly.
When using the weather tool, describe the result as live weather returned by Open-Meteo and include its observation time when available.
If the weather tool reports an API error or cannot find a city, be transparent about that; do not invent weather conditions.""",
)


print("Strands Agent configured to use Amazon Bedrock!")
Enter fullscreen mode Exit fullscreen mode

Step 6 — Ask the agent a calculation question

response = agent("What is 25 * 8?")
print(response)
Enter fullscreen mode Exit fullscreen mode

Step 7 — Ask the agent about weather


response = agent("What is the weather like in Bengaluru?")
print(response)
Enter fullscreen mode Exit fullscreen mode

Step 8 — Ask a question that uses both tools

This demonstrates a more agentic workflow.

response = agent(
    "What is the sample temperature in Bengaluru, and what is that temperature "
    "in Fahrenheit? Show the calculation."
)
print(response)
Enter fullscreen mode Exit fullscreen mode

Step 9 — Try your own question



question = "Calculate 150 / 6 and explain the answer in one sentence."
response = agent(question)
print(response)

Enter fullscreen mode Exit fullscreen mode

Troubleshooting

AccessDeniedException / model access error: enable the model in the Bedrock console and check the SageMaker role has  bedrock:InvokeModel  permission.

ValidationException / model unavailable: verify  BEDROCK_MODEL_ID  and  AWS_REGION  match a model available to your account and region. You can change them in the configuration cell or set them as environment variables before running the notebook.

No AWS credentials: attach an IAM execution role to the SageMaker environment, or configure the standard AWS credential chain. Do not put access keys directly in the notebook.

Region: the notebook defaults to  us-east-1 ; change  AWS_REGION  or  AWS_DEFAULT_REGION  if your Bedrock model is enabled elsewhere.

Inline Policy that can be added to AmazonSageMaker-ExecutionRole
JSON



{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "bedrock:InvokeModel",
        "bedrock:InvokeModelWithResponseStream"
      ],
      "Resource": "arn:aws:bedrock:us-east-1::foundation-model/amazon.nova-lite-v1:0"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Important

Stop and Delete the Notebook Instance after use

What We Learned

We learned to build an agent using the Strands Agents framework and Amazon Bedrock.

We learned how to create Python tools and integrate them with the agent.

We learned how to connect a real weather API to retrieve current weather information.

We learned how the agent selects tools based on user questions and uses the results to generate responses.

We learned the importance of AWS IAM permissions when accessing Amazon Bedrock services.

The full .ipynb file can be accessed from the below repository. Download it and upload it to the editor by clicking the upload icon as shown in the below image

Top comments (0)