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
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!")
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}"
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}"
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!")
Step 6 — Ask the agent a calculation question
response = agent("What is 25 * 8?")
print(response)
Step 7 — Ask the agent about weather
response = agent("What is the weather like in Bengaluru?")
print(response)
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)
Step 9 — Try your own question
question = "Calculate 150 / 6 and explain the answer in one sentence."
response = agent(question)
print(response)
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"
}
]
}
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)