🏃♂️ TL;DR
Hey devs, ever dreamed of spinning up your own AI agent like it’s no big deal? Today we’re diving into Strands Agents SDK
and deploying our very first AI agent.
Here’s the GitHub repo if you want to dive in right away: 👉 serverless-weather-strands-agent
🧵 What is Strands Agents SDK?
It’s a simple-to-use Python-based SDK and code-first framework that helps you build agents AI applications without crying over architecture diagrams at 2am. Think LangChain, but with a sleek, opinionated design, and way less boilerplate.
You define your agents, hook them up with skills, memory, tools, and they can start reasoning, planning, and working for you.
Strands Agents
is lightweight and production-ready, supporting many model providers.
Key features (from docs) include:
- Lightweight and gets out of your way: A simple agent loop that just works and is fully customizable.
- Production ready: Full observability, tracing, and deployment options for running agents at scale.
- Model, provider, and deployment agnostic: Strands supports many different models from many different providers.
- Powerful built-in tools: Get started quickly with tools for a broad set of capabilities.
- Multi-agent and autonomous agents: Apply advanced techniques to your AI systems like agent teams and agents that improve themselves over time.
- Conversational, non-conversational, streaming, and non-streaming: Supports all types of agents for various workloads.
- Safety and security as a priority: Run agents responsibly while protecting data.
⚙️ Prerequisites and setup
Before we jump in:
- Python 3.9+
- AWS credentials
Following the quickstart setup, install the Strands Agents SDK
pip install strands-agents
pip install strands-agents-tools
Create a requirements.txt
strands-agents>=0.1.0
strands-agents-tools>=0.1.0
That’s it. You're ready to go.
🌤️ Create our first agent
Let’s make a helpful assistant who can answer questions about weather using a language model and real-time data from an external API.
The code below defines a weather assistant agent powered by a language model from Amazon Bedrock, you can find it there in Strands documentation. It integrates with the US National Weather Service API to retrieve live weather information. Here's a breakdown of the main components:
-
Bedrock Model
: This wraps an Amazon hosted LLM (in our case, nova-micro-v1) and configures it for use. -
Agent
: This is a Strands agent that takes a model, a system prompt (which defines the agent's behavior), and a list of tools it can use. Here, it’s equipped with anhttp_request
tool so it can call external APIs. -
System Prompt
: A detailed instruction that guides the model to act as a weather assistant. It explains how to fetch forecast data and how to present it in a clear, human-readable way. - Lambda-compatible handler: The weather function is designed to be used in a serverless context on AWS Lambda, responding to user prompts passed in the incoming event.
Here’s the code:
import boto3
from strands import Agent
from strands.models import BedrockModel
from strands_tools import http_request
from typing import Dict, Any
# Define a weather-focused system prompt
WEATHER_SYSTEM_PROMPT = """You are a weather assistant with HTTP capabilities. You can:
1. Make HTTP requests to the National Weather Service API
2. Process and display weather forecast data
3. Provide weather information for locations in the United States
When retrieving weather information:
1. First get the coordinates or grid information using https://api.weather.gov/points/{latitude},{longitude} or https://api.weather.gov/points/{zipcode}
2. Then use the returned forecast URL to get the actual forecast
When displaying responses:
- Format weather data in a human-readable way
- Highlight important information like temperature, precipitation, and alerts
- Handle errors appropriately
- Convert technical terms to user-friendly language
Always explain the weather conditions clearly and provide context for the forecast.
"""
# Create a BedrockModel
bedrock_model = BedrockModel(
model_id="us.amazon.nova-micro-v1:0",
region_name='us-east-1'
)
# The handler function signature `def handler(event, context)` is what Lambda
# looks for when invoking your function.
def weather(event: Dict[str, Any], _context) -> str:
weather_agent = Agent(
model=bedrock_model,
system_prompt=WEATHER_SYSTEM_PROMPT,
tools=[http_request],
)
response = weather_agent(event.get('prompt'))
return str(response)
That's all folks. Our first agent is born.
This assistant can understand natural language prompts, make real-time API calls, and return well-formatted weather reports for any location in the U.S.
In the next steps, you’ll learn how to test it locally and deploy this agent.
🇮🇹 Refine our code for Italy weather forecast!
How to modify our code from the doc boilerplate?
Let's image we want our forecast agent handle both US and Italy.
We should adapt our handler
to get a region
parameter in the incoming event and adapt our system prompt into our Lambda
as follow:
def weather(event: Dict[str, Any], _context) -> str:
prompt = event.get('prompt')
if not prompt:
return str("Missing required parameter: 'prompt'")
region = event.get('region', 'US').upper()
if region == 'US':
system_prompt = WEATHER_SYSTEM_PROMPT_US
elif region == 'IT':
system_prompt = WEATHER_SYSTEM_PROMPT_IT
else:
return str("Unsupported region. Must be 'US' or 'IT'")
weather_agent = Agent(
model=bedrock_model,
system_prompt=system_prompt,
tools=[http_request],
)
response = weather_agent(prompt)
return str(response)
Finally, we should adapt our prompt to use meaningful APIs for weather and location in Italy:
WEATHER_SYSTEM_PROMPT_IT = """You are a weather assistant with HTTP capabilities for Italy.
You can:
1. Make HTTP requests to APIs like https://nominatim.openstreetmap.org/search and https://api.open-meteo.com/v1/forecast
2. Process and display weather forecast data
3. Provide weather information for locations in Italy
When using Nominatim API:
- You must set a valid User-Agent header
- You must respect usage policy: 1 request per second (or you risk being blocked)
If you are blocked by Nominatim API please print the exact error.
When retrieving weather information:
1. Use this API endpoint to get city latitude and longitude: https://nominatim.openstreetmap.org/search?q={city},Italia&format=json
2. Use this API endpoint to get forecast based on latitude and longitude: https://api.open-meteo.com/v1/forecast?latitude={latitude}&longitude={longitude}¤t_weather=true
3. Then use the returned forecast URL to get the actual forecast
"""
As you can see, updating our code is straightforward, and system prompting becomes a key player when building agents.
🧪 Test it Locally
Now that your weather agent is ready, it’s time to test it out locally before deploying it to the AWS cloud. We'll use Serverless Framework
, which makes it easy to run and manage AWS Lambda
functions during development.
To invoke your weather function locally, use the following command:
sls invoke local -f weather --data '{"prompt": "What is the weather in Seattle?"}'
or for Italy
sls invoke local -f weather --data '{"prompt": "What is the weather in Pavia?","region":"IT"}'
What does this command do?
-
sls
is the CLI command forServerless Framework
. -
invoke
tellsServerless Framework
to run a specific function. -
local
means the function will run on your local machine, not in AWS. -
-f weather
specifies the function name (weather, as defined in your serverless.yml). -
--data
passes a mock event to the function: in this case, a simple prompt asking for the weather in Seattle or Pavia.
This command simulates what would happen if your AWS Lambda
function received this prompt in the AWS cloud. The model processes the input, calls the external weather API (using the http_request
tool), and formats the response using the system prompt instructions.
🚀 Deploy on AWS with IaC
Once you’ve tested your agent locally, it’s time to deploy it to the cloud. Also deployment is handled through Serverless Framework
, which makes it easy to package and push your AWS Lambda
functions to AWS cloud.
Make sure your project includes a serverless.yml file like the one below. This file tells Serverless how to package, deploy, and expose your weather agent:
service: serverless-strands-weather-agent
frameworkVersion: '3'
## Use .env
useDotenv: true
## Package individually each function
package:
individually: true
## Apply plugins
plugins:
- serverless-python-requirements #install python requirements
## Define provider and globals
provider:
name: aws
runtime: python3.12
## Define atomic functions
functions:
## Weather function
weather:
handler: src/agent/weather/handler.weather #function handler
url: true
package: #package patterns
include:
- "!**/*"
- src/agent/weather/**
Key configuration highlights:
-
provider
: Defines AWS as the deployment target and uses Python 3.12 as the runtime. -
functions.weather
: Specifies the Lambda function to deploy and exposes it via a public URL (url: true
).
To deploy your function (you should have AWS credentials
setup on your machine), run:
sls deploy
After a successful deployment, your AI powered weather agent will be accessible online, ready to take prompts and return real-time forecasts. 🌤️
🐍 Stay with Py, use CDK
If you prefer using only python
and have a fully python repo, you can use AWS CDK
for your infrastructure as code, here is an example.
from aws_cdk import (
App,
Stack,
aws_lambda as _lambda,
)
from constructs import Construct
class WeatherAgentStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs):
super().__init__(scope, construct_id, **kwargs)
# Lambda function
weather_function = _lambda.Function(
self, "WeatherFunction",
runtime=_lambda.Runtime.PYTHON_3_12,
handler="handler.weather",
code=_lambda.Code.from_asset("src/agent/weather"),
)
# Enable Function URL (public)
weather_function.add_function_url(
auth_type=_lambda.FunctionUrlAuthType.NONE
)
app = App()
WeatherAgentStack(app, "ServerlessStrandsWeatherAgent")
app.synth()
❓ API Gateway, Lambda URL and distributed architectures
By default, many serverless projects expose functions via Amazon API Gateway
, but in this case we did not use it for a specific reason:
-
Amazon API Gateway
has a hard timeout limit of 30 seconds. This means if your agent takes longer than that (e.g., due to a slow model call or network delay), the request will be terminated. You can request a limit increase from AWS, specifically provided for AI and LLM use cases, but that may not be suitable for all use cases for its side effects. For simple, fast responses, anyway, API Gateway might be fine. - Instead, you can use
Lambda Function URL
, which supports response streaming and avoids the 30-second cap. If your agent generates partial responses over time or needs longer to compute, streaming is often a better choice. For LLM agentsAWS Lambda URLs
with streaming are often the better option. Please pay attention to the security best practices as AWS Lambda URL do not offer security patterns like Custom Authorizer or Cognito Integration, here you should implement them in the lambda itself! - Moreover, as we are talking about an agent you should probably integrate it in a wider distributed architecture knowing you can directly invoke lambda passing an event formatted as the test one and secure it with IAM and least privilege permissions
To dive deeper into the topic, check out this excellent article by the AWS Serverless Hero Yan Cui: a must-read if you're working with AWS Lambda
and trying to decide between Amazon API Gateway
and AWS Lambda Function URLs
.
Another great article is this one by the AWS Serverless Hero Mattieu Napoli comparing AWS Lambda Function URls
and Amazon API Gateway
specifically for Serverless Framework
use cases.
🚀 Final Thoughts
Strands Agents SDK
is surprisingly fun to work with. It removes a lot of the boilerplate from typical agent frameworks, and it’s designed to be hackable. Whether you’re building a dev assistant, customer support bot, or something more chaotic, this is a solid starting point.
Curious about what you can do with Strands Agents SDK? Check out this awesome hands-on series by Dennis Traub: it inspired me to give it a try! You should definitely read it to master the full potential of Strands Agents SDK.
⏭️ Next Step
Have you heard about Model Context Protocol (MCP)?
If not, you can dive deep on how to build agents which could be plugged to any client implementing this protocol in my previous series.
You can combine this approach with Strands Agents SDK!
Also there is an entire section of the doc on MCP. I'll probably continue this series implementing an MCP server with Strands Agents
on AWS Lambda
.
🙋 Who am I
I'm D. De Sio and I work as a Head of Software Engineering in Eleva.
I'm currently (Apr 2025) an AWS Certified Solution Architect Professional and AWS Certified DevOps Engineer Professional, but also a User Group Leader (in Pavia), an AWS Community Builder and, last but not least, a #serverless enthusiast.
My work in this field is to advocate about serverless and help as more dev teams to adopt it, as well as customers break their monolith into API and micro-services using it.
Top comments (0)