# AWS Strands SDK Masterclass: Introduction to Building AI Agents

*Published: June 6, 2025*

In today's rapidly evolving AI landscape, building intelligent agents that can reason, use tools, and solve complex problems has become a critical capability for developers. AWS has introduced the Strands Agents SDK, a powerful Python framework that simplifies the creation of AI agents with advanced capabilities. In this first post of our 12-part series, we'll explore what Strands is, why it matters, and how to get started with your first agent.

## What is AWS Strands?

Strands Agents SDK is an open-source Python framework developed by AWS that enables developers to build, customize, and deploy AI agents. These agents can leverage foundation models like Claude, use tools to interact with external systems, and maintain context across interactions.

At its core, Strands provides a clean, intuitive API for defining agents with three key components:

1. **Models**: The foundation models that power your agent's reasoning
    
2. **Tools**: Functions that extend your agent's capabilities
    
3. **Prompts**: Instructions that guide your agent's behavior
    

```mermaid
graph TD
    A[Strands Agent] --> B[Model]
    A --> C[Tools]
    A --> D[Prompts]
    B --> E[Claude]
    B --> F[Other LLMs]
    C --> G[Built-in Tools]
    C --> H[Custom Tools]
    C --> I[MCP Tools]
    D --> J[System Prompt]
    D --> K[User Messages]
```

## Why Strands Matters

Before Strands, building AI agents required complex orchestration code, managing model interactions, and handling tool execution flows. Strands abstracts away this complexity, allowing developers to focus on defining agent capabilities rather than implementation details.

Key benefits include:

* **Simplified Agent Creation**: Define agents in just a few lines of code
    
* **Tool Flexibility**: Easily extend agents with custom tools
    
* **Model Provider Agnostic**: Works with multiple model providers
    
* **Streaming Support**: Real-time streaming of agent responses
    
* **Production Ready**: Built for production use cases
    

## Getting Started with Strands

Let's create our first agent using Strands. First, you'll need to install the SDK:

```bash
pip install strands strands-agents strands-agents-tools
```

Now, let's create a simple agent with login that can perform calculations and tell the current time:

```python
import logging
from strands import Agent
from strands_tools import calculator, current_time

# Enables Strands debug log level
logging.getLogger("strands").setLevel(logging.DEBUG)

# Sets the logging format and streams logs to stderr
logging.basicConfig(
    format="%(levelname)s | %(name)s | %(message)s",
    handlers=[logging.StreamHandler()]
)

# Define our agent
agent = Agent(
    # Use Claude 3.7 Sonnet from Amazon Bedrock
    model="us.anthropic.claude-3-7-sonnet-20250219-v1:0",
    # Add calculator and current_time tools
    tools=[calculator, current_time],
    # Set the system prompt
    system_prompt="You are a helpful assistant that specializes in mathematics and time."
)

# Ask the agent a question
response = agent("What is 1234 * 5678 and what time is it now?")

# Print the response
print(response.message)
```

When you run this code, the agent will:

1. Process the user's question
    
2. Recognize that it needs to perform a calculation
    
3. Use the calculator tool to compute 1234 \* 5678
    
4. Use the current\_time tool to get the current time
    
5. Formulate a response that includes both results
    

## Response

```plaintext
DEBUG | strands.models.bedrock | config=<{'model_id': 'us.anthropic.claude-3-7-sonnet-20250219-v1:0'}> | initializing
DEBUG | strands.tools.registry | tool_name=<calculator>, tool_type=<function>, is_dynamic=<False> | registering tool
DEBUG | strands.tools.registry | tool_name=<current_time>, tool_type=<function>, is_dynamic=<False> | registering tool
DEBUG | strands.tools.registry | tools_dir=</Users/jayyanar/blogs-strands/tools> | tools directory not found
DEBUG | strands.tools.registry | tool_modules=<[]> | discovered
DEBUG | strands.tools.registry | tool_count=<0>, success_count=<0> | finished loading tools
DEBUG | strands.tools.registry | tools_dir=</Users/jayyanar/blogs-strands/tools> | tools directory not found
DEBUG | strands.tools.registry | getting tool configurations
DEBUG | strands.tools.registry | tool_name=<calculator> | loaded tool config
DEBUG | strands.tools.registry | tool_name=<current_time> | loaded tool config
DEBUG | strands.tools.registry | tool_count=<2> | tools configured
DEBUG | strands.tools.registry | getting tool configurations
DEBUG | strands.tools.registry | tool_name=<calculator> | loaded tool config
DEBUG | strands.tools.registry | tool_name=<current_time> | loaded tool config
DEBUG | strands.tools.registry | tool_count=<2> | tools configured
DEBUG | strands.event_loop.streaming | model=<<strands.models.bedrock.BedrockModel object at 0x10639f010>> | streaming messages
DEBUG | strands.types.models.model | formatting request
DEBUG | strands.types.models.model | invoking model
DEBUG | strands.types.models.model | got response from model
I'll calculate that multiplication for you and tell you the current time.

First
DEBUG | strands.types.models.model | finished streaming response from model
DEBUG | strands.tools.executor | tool_count=<1>, tool_executor=<ThreadPoolExecutorWrapper> | executing tools in parallel
DEBUG | strands.handlers.tool_handler | tool=<{'toolUseId': 'tooluse_-8WO095dTgSQrV1uuOfdtw', 'name': 'calculator', 'input': {'expression': '1234 * 5678'}}> | invoking
DEBUG | strands.tools.executor | tool_count=<1> | submitted tasks to parallel executor
, let me calculate 1234 * 5678:
Tool #3: calculator
╭────────────────────────────────────────────── Calculation Result ───────────────────────────────────────────────╮
│                                                                                                                 │
│  ╭───────────┬─────────────────────╮                                                                            │
│  │ Operation │ Evaluate Expression │                                                                            │
│  │ Input     │ 1234 * 5678         │                                                                            │
│  │ Result    │ 7006652             │                                                                            │
│  ╰───────────┴─────────────────────╯                                                                            │
│                                                                                                                 │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
DEBUG | strands.event_loop.streaming | model=<<strands.models.bedrock.BedrockModel object at 0x10639f010>> | streaming messages
DEBUG | strands.types.models.model | formatting request
DEBUG | strands.types.models.model | invoking model
DEBUG | strands.types.models.model | got response from model
DEBUG | strands.types.models.model | finished streaming response from model
DEBUG | strands.handlers.tool_handler | tool=<{'toolUseId': 'tooluse_f9jfxZNRQCyswGER0z8RYA', 'name': 'current_time', 'input': {}}> | invoking
DEBUG | strands.event_loop.streaming | model=<<strands.models.bedrock.BedrockModel object at 0x10639f010>> | streaming messages
DEBUG | strands.types.models.model | formatting request
DEBUG | strands.types.models.model | invoking model
DEBUG | strands.types.models.model | got response from model
Now, let me check the current time:
Tool #4: current_time
1234 * 5678 = 7,006,652

The current time is 2025-06-06T12:26:12.985335+00:00 (which is June 6, 2025, at 12:26:12 PM UTC
DEBUG | strands.types.models.model | finished streaming response from model
DEBUG | strands.agent.conversation_manager.sliding_window_conversation_manager | window_size=<6>, message_count=<40> | skipping context reduction
).{'role': 'assistant', 'content': [{'text': '1234 * 5678 = 7,006,652\n\nThe current time is 2025-06-06T12:26:12.985335+00:00 (which is June 6, 2025, at 12:26:12 PM UTC).'}]}
```

## The Agent Execution Flow

Understanding how Strands agents work internally helps you build more effective agents. Here's the typical execution flow:

```mermaid
sequenceDiagram
    participant User
    participant Agent
    participant Model
    participant Tools
    
    User->>Agent: Send query
    Agent->>Model: Forward query with system prompt
    Model-->>Agent: Generate response or tool call
    
    alt Tool Call Required
        Agent->>Tools: Execute tool
        Tools-->>Agent: Return tool result
        Agent->>Model: Continue with tool result
        Model-->>Agent: Generate final response
    end
    
    Agent-->>User: Return response
```

## Project Structure

When building more complex agents, it's helpful to organize your code. Here's a recommended project structure:

```plaintext
my_agent/
├── __init__.py
├── agent.py
├── tools/
│   ├── __init__.py
│   ├── custom_tools.py
├── config.py
└── requirements.txt
```

## Next Steps

In this introduction, we've covered the basics of Strands Agents SDK and created our first simple agent. In the next post, we'll dive deeper into models and model providers, exploring how to use different foundation models with your Strands agents.

Stay tuned for the complete series:

1. **Introduction to Building AI Agents** (this post)
    
2. Models and Model Providers
    
3. Building Custom Tools
    
4. Advanced Tool Patterns
    
5. Streaming and Real-time Responses
    
6. Agent Memory and Context Management
    
7. Multi-agent Systems with Strands
    
8. RAG and Knowledge Integration
    
9. Debugging and Testing Agents
    
10. Production Deployment Patterns
    
11. Performance Optimization
    
12. Building Complex Agent Applications
    

## Resources

* [Strands Agents Documentation](https://strandsagents.com)
    
* [GitHub Repository](https://github.com/aws/strands-agents)
    
* [AWS Bedrock Documentation](https://docs.aws.amazon.com/bedrock/)
    

---

*This post is part of the AWS Strands SDK Masterclass series, where we explore building intelligent AI agents using AWS Strands Agents SDK.*
