Build a Task Assistant AI Agent
Build an AI agent with custom tools using Strands and Amazon Bedrock.
Introduction
30 Second Summary
You know how you talk to Siri or Alexa and they just figure out what you need? That same "understand me, then do the right thing" pattern is how AI agents work in software.
In this project, you will build a personal task assistant AI agent that understands your natural language requests, picks the right tool for the job, and gives you back the result.
What You'll Build
A personal task assistant agent powered by Amazon Bedrock and the Strands Agents SDK that accepts natural language commands and autonomously selects and executes custom Python tools you create.
By the end of this project, you'll have:
- A working AI agent running locally that reasons through tasks and returns results.
- Three custom Python tools you built yourself (a word counter, a to-do list manager, and a text reverser) wired into the agent.
- A clear understanding of the agent loop pattern (input, reasoning, tool selection, execution, response) that transfers to any agent framework.
- A secret mission where you add a "save notes to file" tool that writes the agent's output to a local text file.
Are there any prerequisites?
You need basic Python knowledge (variables, functions, if/else) and an AWS account with configured CLI credentials. You should also have Python 3.10+ and pip installed on Ubuntu (WSL on Windows 10).
Before We Start
Before We Start...
Set Up Your Environment and Enable Nova Lite
Before your agent can reason through tasks and pick the right tool, it needs two things: the Strands Agents SDK installed locally, and access to a foundation model on Amazon Bedrock. In this step, you'll set up your Python project, enable Amazon Nova Lite in the Bedrock console, and verify everything works with a quick test script.
In This Step, Get Ready To:
- Create a Python project with a virtual environment and install the Strands SDK.
- Enable Amazon Nova Lite model access in the Bedrock console.
- Run a test script to confirm your agent can talk to the model.
Create Your Project and Install the Strands SDK
A virtual environment keeps your project's packages isolated from the rest of your system. This prevents version conflicts between different Python projects on your machine.
- Open your Ubuntu terminal.
- Run the following commands to create a project folder, set up a virtual environment, and activate it.
mkdir task-assistant && cd task-assistant
python3 -m venv .venv
source .venv/bin/activate
What do these commands do?
The first line creates a new folder called task-assistant and moves into it. The second line creates a virtual environment inside a .venv folder. The third line activates the virtual environment so any packages you install go into this project only.
You should see (.venv) appear at the beginning of your terminal prompt. This confirms the virtual environment is active.
- Install the Strands Agents SDK and the tools package.
pip install strands-agents strands-agents-tools
What are these two packages?
The strands-agents package is the core SDK. It gives you the Agent class, the @tool decorator, and model providers like BedrockModel. The strands-agents-tools package includes pre-built tools like a calculator that you can plug into your agent right away.
The installation may take a minute. Wait until you see the Successfully installed message before moving on.
Seeing an error during installation?
Make sure your virtual environment is active. You should see (.venv) in your terminal prompt. If not, run source .venv/bin/activate again. Also confirm you are running Python 3.10 or higher by running python3 --version.
Still stuck? Help me troubleshoot this installation error.
Enable Amazon Nova Lite in the Bedrock Console
Amazon Bedrock hosts many foundation models, but you need to explicitly enable each model before your code can call it. Amazon Nova Lite is a lightweight, low-cost model that supports tool calling. That is exactly what your agent needs to pick and run tools.
Why Nova Lite Instead of Claude?
Nova Lite costs $0.06 per million input tokens and $0.24 per million output tokens. Claude 3.5 Sonnet costs $6.00 and $30.00 for the same amounts. That makes Nova Lite roughly 100x cheaper. With your $6 AWS credit, you can make tens of thousands of agent calls with Nova Lite. Claude would burn through that credit in just a handful of requests.
- Open the AWS Management Console in your browser.
- Make sure you are in the US East (N. Virginia) region. Check the region selector in the top-right corner of the console.
- Search for Bedrock in the search bar and select Amazon Bedrock.
- In the left sidebar, click Model access.
- Find Amazon Nova Lite in the list of available models.
- Click Enable (or Request access if prompted) for Nova Lite. Access is granted instantly for Amazon models.
What should I see?
After enabling, the status next to Amazon Nova Lite should show Access granted (or a green checkmark). This is free. You are not subscribing to anything. You only pay per token when your code actually calls the model.
Don't see Nova Lite in the list?
Double-check that your region is set to US East (N. Virginia). Nova Lite is available in US East (N. Virginia), US West (Oregon), and US East (Ohio). If you still don't see it, help me find Nova Lite in the Bedrock console.
Verify Your Setup with a Test Script
Time to make sure everything is wired up correctly. You'll create a small Python script that connects to Nova Lite through Bedrock and sends a simple message. If you get a response, your environment is ready to go.
- Create a new file called test_agent.py in your task-assistant folder.
- Add the following code.
from strands import Agent
from strands.models import BedrockModel
# Configure the model to use Amazon Nova Lite via Bedrock
bedrock_model = BedrockModel(
model_id="us.amazon.nova-lite-v1:0",
temperature=0.3
)
# Create a basic agent with no tools (just testing the connection)
agent = Agent(model=bedrock_model)
# Send a simple message to verify everything works
response = agent("Hello! Can you tell me what 2 + 2 is?")
print(response)
What does this script do?
The script imports the Agent class and BedrockModel from the Strands SDK. It creates a BedrockModel pointing to Nova Lite using the model ID us.amazon.nova-lite-v1:0. The temperature of 0.3 keeps responses focused and predictable. Then it creates an Agent with that model and sends it a simple question.
How does the agent find my AWS credentials?
BedrockModel uses boto3 under the hood. Since you already have the AWS CLI configured, boto3 automatically picks up your existing credentials. No API keys or extra configuration needed.
- Run the test script.
python3 test_agent.py
I see a response from the agent
You should see the agent respond with something like "2 + 2 equals 4" along with a friendly message. The exact wording will vary each time. If you got a response, your environment is fully set up and your agent can communicate with Nova Lite through Bedrock.
I see an error
Here are the most common errors and how to fix them:
- AccessDeniedException or You don't have access to the model: Go back to the Bedrock console and confirm Nova Lite shows Access granted. Your IAM user also needs the bedrock:InvokeModel and bedrock:InvokeModelWithResponseStream permissions.
- NoCredentialsError: Your AWS CLI credentials are not configured. Run aws configure and enter your access key, secret key, and set the default region to us-east-1.
- ModuleNotFoundError: Make sure your virtual environment is active (you should see (.venv) in your prompt) and that you installed the packages inside it.
If none of these match your error, help me debug this Strands agent error.
Your environment is ready and your agent can talk to Nova Lite. Right now the agent is just chatting. Next up, you'll give it real tools to work with, starting with a built-in calculator.
Build Your First Agent with Built-in Tools
In the previous step, you installed the Strands Agents SDK and confirmed your connection to Amazon Bedrock. Now it's time to build something more interesting. In this step, you'll give your agent a real tool and watch it decide when and how to use it.
This is where the magic of AI agents clicks. Instead of you writing if/else logic to handle different requests, the agent reasons about your message and picks the right tool on its own.
In This Step, Get Ready To:
- Create an agent script with a built-in calculator tool and a system prompt.
- Test the agent with math and reasoning questions to see tool use in action.
- Enable debug logging to observe the full agent loop: reasoning, tool selection, execution, and response.
Create Your Agent Script with a Calculator Tool
A system prompt tells the agent who it is and how it should behave. Think of it as the agent's job description. Combined with a tool, the agent can now do more than just chat. It can take action.
- Create a new file called agent.py in your task-assistant directory.
- Add the following code to agent.py:
from strands import Agent
from strands.models import BedrockModel
from strands_tools import calculator
# Configure the foundation model
bedrock_model = BedrockModel(
model_id="us.amazon.nova-lite-v1:0",
temperature=0.3
)
# Define the agent's personality and role
system_prompt = """You are a helpful personal task assistant.
You help users with calculations, task management, and general questions.
When a user asks a math question, use the calculator tool to get an accurate answer.
Always be friendly and concise in your responses."""
# Create the agent with the calculator tool
agent = Agent(
model=bedrock_model,
system_prompt=system_prompt,
tools=[calculator]
)
# Send a test message
response = agent("What is 247 multiplied by 38?")
print(response)
What Does This Code Do?
This script does four things:
- Imports the calculator tool from the Strands tools package. This is a pre-built tool that can do math.
- Sets up BedrockModel pointing to Amazon Nova Lite with a low temperature of 0.3 for consistent responses.
- Gives the agent a system prompt describing its role as a task assistant.
- Creates the agent and sends it a math question to test tool use.
What Is a System Prompt?
A system prompt is a set of instructions the AI model reads before every conversation. It shapes the agent's personality, tone, and behavior. The model never shows the system prompt to the user, but it follows it like a set of ground rules.
Test the Agent with Different Prompts
Now you'll run the script and see how the agent handles different types of questions. The interesting part is watching whether the agent decides to use the calculator tool or just answers on its own.
- Make sure your virtual environment is activated.
- Run the script:
python agent.py
You should see the agent respond with the answer to 247 multiplied by 38, which is 9,386. The agent used the calculator tool to compute this rather than guessing.
- Now update the prompt in agent.py to test a reasoning question. Replace the last two lines with:
# Test with a reasoning question
response = agent("If I have 150 dollars and spend 37.50, how much do I have left?")
print(response)
- Run the script again:
python agent.py
The agent should respond with $112.50. Even though this question is phrased as a word problem, the agent still recognizes it as a math task and uses the calculator tool.
What Is Tool Use?
Tool use (also called function calling) is when an AI model decides to call an external function instead of generating an answer from its own knowledge. The model looks at your message, reads the descriptions of available tools, and picks the best one for the job. This is what separates an agent from a simple chatbot.
Examine the Agent Loop with Debug Logging
So far you've seen the agent's final answer. But the real learning happens when you see what's going on behind the scenes. The agent loop is the cycle the agent follows for every request: receive input, reason about it, select a tool, execute the tool, and formulate a response.
By enabling debug logging, you can watch each step of this loop in real time.
- Update agent.py to add debug logging at the top of the file. Replace the entire contents with:
import logging
import sys
# Enable debug logging to see the agent's reasoning
logging.basicConfig(
level=logging.DEBUG,
format="%(name)s - %(message)s",
stream=sys.stdout
)
from strands import Agent
from strands.models import BedrockModel
from strands_tools import calculator
# Configure the foundation model
bedrock_model = BedrockModel(
model_id="us.amazon.nova-lite-v1:0",
temperature=0.3
)
# Define the agent's personality and role
system_prompt = """You are a helpful personal task assistant.
You help users with calculations, task management, and general questions.
When a user asks a math question, use the calculator tool to get an accurate answer.
Always be friendly and concise in your responses."""
# Create the agent with the calculator tool
agent = Agent(
model=bedrock_model,
system_prompt=system_prompt,
tools=[calculator]
)
# Send a math question and watch the debug output
response = agent("What is 247 multiplied by 38?")
What Does the Logging Code Do?
The logging.basicConfig block tells Python to print all debug-level messages to your terminal. The Strands SDK logs every step of the agent loop internally. Turning on debug mode makes those internal logs visible to you.
- Run the updated script:
python agent.py
This time your terminal will be much busier. You'll see a flood of debug messages showing exactly what the agent is doing at each stage.
What Should I See?
Look for these key moments in the debug output:
- The agent receiving your message and sending it to the model.
- The model deciding to call the calculator tool (you'll see the tool name and the input it passes).
- The tool returning a result back to the model.
- The model using that result to compose its final answer.
This is the agent loop in action. Every agent framework follows this same pattern: reason, select a tool, execute, respond.
Pro tip: keep debug off by default
Debug logging is great for learning, but it makes the output hard to read during normal use. Once you've seen the agent loop in action, you can remove or comment out the logging.basicConfig block to get clean output again.
Seeing an Access Denied or Model Not Found Error?
If you see an error about access or the model not being available, double-check that you enabled Amazon Nova Lite in the Bedrock console in Step 1. Also verify your AWS CLI region matches the region where you enabled the model. Help me troubleshoot my Bedrock model access error.
You've just watched an AI agent think. It received your question, decided it needed a calculator, called the tool, got the result, and wrote a response. This reason-plan-act loop is the foundation of every agent framework. Next up, you'll build your own custom tools from scratch.
Create Your Own Custom Tools
In the previous step, you saw how the agent uses a built-in calculator tool to handle math questions. That's powerful, but the real magic of agents comes when you build your own tools. Custom tools let you teach the agent entirely new abilities that don't exist out of the box.
In this step, you'll create three custom tools from scratch using Python functions and the @tool decorator. Each tool gives your agent a new capability: counting words, reversing text, and managing a to-do list.
In This Step, Get Ready To:
- Build a word counter tool using the @tool decorator.
- Build a text reverser tool and test both tools together.
- Build a to-do list manager tool that handles multiple actions from natural language.
Build a Word Count Tool
A custom tool in Strands is a regular Python function with the @tool decorator on top. The decorator tells the agent that this function is available to use. The function's docstring is especially important because the AI model reads it to decide when to call the tool.
- Open your agent.py file and replace its contents with the following code.
from strands import Agent, tool
from strands.models import BedrockModel
# Define a custom tool using the @tool decorator
@tool
def word_count(text: str) -> int:
"""Count the number of words in the given text. Use this tool when the user asks how many words are in a sentence, paragraph, or any piece of text."""
return len(text.split())
# Set up the model
bedrock_model = BedrockModel(
model_id="us.amazon.nova-lite-v1:0",
temperature=0.3
)
# Create the agent with the custom tool
agent = Agent(
model=bedrock_model,
system_prompt="You are a helpful task assistant. Use your tools to help the user with their requests.",
tools=[word_count]
)
# Test the word count tool
agent("How many words are in 'The quick brown fox jumps over the lazy dog'?")
What Makes This a Tool?
Three things turn a plain Python function into an agent tool:
- The @tool decorator registers the function so the agent knows it exists.
- The type hints (text: str) tell the model what kind of input to pass in.
- The docstring is the most important part. The AI model reads it to decide whether this tool is the right one for the user's request. A vague docstring means the model won't know when to use your tool.
- Run the script to test your new tool.
python agent.py
The agent should respond with the number 9. Behind the scenes, it read your question, decided the word_count tool was the right one to call, passed the sentence to it, and formatted the result into a human-readable answer.
Build a Text Reverser Tool
Now that you know the pattern, adding more tools is straightforward. Each new tool is another function with the @tool decorator, a clear docstring, and type hints.
- Add the following reverse_text function to your agent.py file, right below the word_count function.
@tool
def reverse_text(text: str) -> str:
"""Reverse the given text. Use this tool when the user asks you to reverse, flip, or mirror a piece of text."""
return text[::-1]
What does this code do?
The text[::-1] syntax is a Python slice that reverses a string. For example, "hello" becomes "olleh".
- Update the tools list in your Agent to include both tools.
agent = Agent(
model=bedrock_model,
system_prompt="You are a helpful task assistant. Use your tools to help the user with their requests.",
tools=[word_count, reverse_text]
)
- Replace the test prompt at the bottom of the file with two separate calls to test both tools.
# Test the word count tool
agent("How many words are in 'The quick brown fox jumps over the lazy dog'?")
# Test the reverse text tool
agent("Reverse the text 'hello world'")
- Run the script again.
python agent.py
You should see two responses. The agent counts the words in the first sentence and reverses "hello world" to "dlrow olleh" in the second. Notice that you didn't tell the agent which tool to use. It figured that out on its own by reading your request and matching it against each tool's docstring.
Build a To-Do List Manager Tool
The first two tools were simple, single-purpose functions. Now you'll build something more complex. A to-do list manager needs to handle three different actions (add, list, and remove) all within a single tool. The agent will figure out which action you want based on your natural language request.
- Add the following code to agent.py, below your other tool functions but above the BedrockModel setup.
# Store tasks in a simple list in memory
todo_list = []
@tool
def todo_manager(action: str, task: str = "") -> str:
"""Manage a to-do list. Use this tool when the user wants to add, remove, or view tasks.
Args:
action: The action to perform. Must be 'add', 'remove', or 'list'.
task: The task description. Required for 'add' and 'remove' actions. Not needed for 'list'.
"""
if action == "add":
todo_list.append(task)
return f"Added '{task}' to your to-do list. You now have {len(todo_list)} task(s)."
elif action == "remove":
if task in todo_list:
todo_list.remove(task)
return f"Removed '{task}' from your to-do list. You now have {len(todo_list)} task(s)."
else:
return f"'{task}' was not found in your to-do list."
elif action == "list":
if not todo_list:
return "Your to-do list is empty."
tasks = "\n".join(f"- {t}" for t in todo_list)
return f"Your to-do list:\n{tasks}"
else:
return f"Unknown action '{action}'. Use 'add', 'remove', or 'list'."
Why Is the Docstring So Detailed?
This tool has two parameters: action and task. The docstring explains exactly what values action can take and when task is needed. Without this detail, the AI model would have to guess how to call the function. The more specific your docstring, the more reliably the agent uses the tool correctly.
- Update your Agent to include all three custom tools.
agent = Agent(
model=bedrock_model,
system_prompt="You are a helpful task assistant. Use your tools to help the user with their requests.",
tools=[word_count, reverse_text, todo_manager]
)
- Replace the test prompts at the bottom of the file with these to-do list tests.
# Test adding tasks
agent("Add 'buy groceries' to my to-do list")
agent("Add 'finish homework' to my to-do list")
# Test listing tasks
agent("Show me my to-do list")
# Test removing a task
agent("Remove 'buy groceries' from my to-do list")
# Verify the removal worked
agent("What's on my to-do list now?")
- Run the script.
python agent.py
Watch how the agent handles each request. When you say "Add 'buy groceries' to my to-do list," the agent recognizes this as an add action and passes the right arguments to the todo_manager tool. When you say "Show me my to-do list," it knows to call the same tool with the list action instead. The agent is parsing your natural language and mapping it to the correct function call every time.
Pro tip: tasks live in memory
The todo_list variable is a plain Python list stored in memory. Every time you restart the script, the list resets to empty. In a production agent, you'd store tasks in a database or file. The Secret Mission at the end of this project explores file-based persistence.
I see tasks being added and listed
Your to-do list manager is working. The agent correctly parsed your natural language into the right action and task parameters each time.
I see an error
If the agent is calling the tool but getting unexpected results, check that your docstring includes the exact action names (add, remove, list). The model relies on the docstring to know what values are valid.
If you're getting a connection or model error, make sure your virtual environment is activated and your AWS credentials are still configured.
Still stuck?
Help me debug my to-do list manager tool.
You now have three custom tools that you built from scratch. In the next step, you'll combine all of them into a single agent and have a multi-turn conversation where the agent chains tools together to handle complex requests.
Put It All Together and Have a Conversation
You have three custom tools and a built-in calculator, each tested individually. Now it is time to combine them into a single agent that can handle any request you throw at it. This is where the agent loop really shines. The model decides which tool to use based on your natural language input, and you get to watch it reason across a full conversation.
In This Step, Get Ready To:
- Combine all four tools into a single agent with a custom personality.
- Have a multi-turn conversation where the agent maintains context across requests.
- Test a complex request that requires the agent to reason across multiple tools.
Combine All Tools into One Agent
Right now your tools are scattered across test scripts. A production-ready agent needs all its tools available at once so the model can pick the right one for any request. You will also give the agent a system prompt that defines its personality and capabilities.
- Create a new file called assistant.py in your project directory.
- Add the following code to bring all your tools together into a single agent.
from strands import Agent, tool
from strands.models import BedrockModel
from strands_tools import calculator
# ---- Custom Tools ----
@tool
def word_count(text: str) -> int:
"""Count the number of words in a given text string.
Use this tool when the user asks how many words are in a sentence, paragraph, or any text."""
return len(text.split())
@tool
def reverse_text(text: str) -> str:
"""Reverse the characters in a given text string.
Use this tool when the user asks to reverse, flip, or mirror text."""
return text[::-1]
# Store tasks in memory for the session
task_list = []
@tool
def todo_manager(action: str, task: str = "") -> str:
"""Manage a to-do list. Supports three actions:
- 'add': Add a new task to the list. Requires the 'task' parameter.
- 'list': Show all current tasks.
- 'remove': Remove a task from the list by its exact name.
Use this tool when the user wants to add, view, or remove tasks from their to-do list."""
if action == "add":
task_list.append(task)
return f"Added '{task}' to your to-do list. You now have {len(task_list)} task(s)."
elif action == "list":
if not task_list:
return "Your to-do list is empty."
return "Your tasks:\n" + "\n".join(f" {i+1}. {t}" for i, t in enumerate(task_list))
elif action == "remove":
if task in task_list:
task_list.remove(task)
return f"Removed '{task}'. You now have {len(task_list)} task(s)."
return f"Task '{task}' not found in your list."
return f"Unknown action: {action}. Use 'add', 'list', or 'remove'."
# ---- Agent Setup ----
bedrock_model = BedrockModel(
model_id="us.amazon.nova-lite-v1:0",
temperature=0.3
)
SYSTEM_PROMPT = """You are Tasker, a friendly and efficient personal task assistant.
You help users manage their to-do lists, count words, do math, and reverse text.
Always be concise and helpful. When you use a tool, briefly explain what you did.
If the user asks something you cannot do with your tools, let them know politely."""
agent = Agent(
model=bedrock_model,
system_prompt=SYSTEM_PROMPT,
tools=[calculator, word_count, reverse_text, todo_manager]
)
print("Tasker is ready! Type 'quit' to exit.")
print("-" * 40)
while True:
user_input = input("\nYou: ")
if user_input.lower() in ["quit", "exit"]:
print("Goodbye!")
break
response = agent(user_input)
print(f"\nTasker: {response}")
What Does This Script Do?
This script creates a complete conversational agent. All four tools are defined in one place and passed to the Agent as a list. The while True loop at the bottom creates an interactive chat session. Each time you type a message, the agent runs through its full reasoning loop, picks a tool if needed, and responds.
The system prompt gives the agent its identity as "Tasker" and tells it how to behave. The model reads this prompt before every response, which shapes its personality and decision-making.
Have a Multi-Turn Conversation
A multi-turn conversation means the agent remembers what you said earlier in the session. This is what separates an agent from a simple one-shot API call. Your to-do list persists in memory, so tasks you add early in the conversation are still there later.
- Run your assistant.
python assistant.py
- Try the following prompts one at a time, waiting for the agent to respond between each one.
Add buy groceries to my to-do list
Add finish homework to my to-do list
How many words are in the sentence 'The quick brown fox jumps over the lazy dog'?
What is 247 * 38?
Reverse the text 'hello world'
Show me my to-do list
Watch how the agent picks a different tool for each request. When you ask it to add a task, it calls todo_manager with the "add" action. When you ask for a word count, it switches to word_count. When you ask to see your to-do list at the end, both tasks you added earlier are still there.
What Should I See?
Each prompt should produce a clear, conversational response from Tasker. For the to-do list prompt, the agent should show both "buy groceries" and "finish homework" as numbered items. The word count should return 9. The math result should be 9386. The reversed text should be "dlrow olleh".
Agent Picking the Wrong Tool?
If the agent uses the wrong tool or skips tool use entirely, your tool docstrings may need clearer descriptions. The model reads the docstring to decide when to use each tool. Make sure each docstring explains both what the tool does and when to use it.
If you are still having trouble, help me debug why my agent is picking the wrong tool.
Test a Complex Multi-Tool Request
So far you have sent one request at a time. The real power of an AI agent shows up when you give it a complex instruction that requires multiple tools in sequence. The agent has to break your request into parts, reason about which tool handles each part, and chain the results together.
- If you exited the previous session, run python assistant.py again.
- Send the following complex prompt to your agent.
Add 'write report' to my to-do list, then tell me how many words are in my current task list, and finally calculate how many minutes I need if each task takes 25 minutes.
This single prompt requires the agent to use three different tools. First it calls todo_manager to add the task. Then it calls word_count on the task list text. Finally it calls calculator to multiply the number of tasks by 25.
What Is Happening Under the Hood?
This is the agent loop in action. The model receives your complex prompt, breaks it into sub-tasks, and runs through the reason-plan-act cycle multiple times. Each cycle picks one tool, executes it, and feeds the result back to the model. The model then decides what to do next. This continues until all sub-tasks are complete.
Pro tip: try breaking the agent
Ask the agent something none of your tools can handle, like "What is the weather today?" A well-designed agent should politely tell you it cannot help with that. This is the system prompt at work. It tells the agent to let users know when a request falls outside its capabilities.
You now have a fully working personal task assistant that can reason, pick tools, and chain actions together. Next up, you will push your skills further with a secret mission that adds file-saving capabilities to your agent.
Secret mission
Add a Save Notes Tool
Your agent can do math, count words, and manage tasks. But what if it could save its output to a file? Build a save_notes tool that writes text to a local file with timestamps, giving your agent the power to create persistent records.
Before you go
Clean Up Your Resources
Decide whether to keep your resources running, pause them to come back later, or delete them entirely. This project runs locally with minimal AWS costs. Amazon Nova Lite charges $0.06 per 1M input tokens and $0.24 per 1M output tokens, so a full project run costs a fraction of a cent.
Resources you used:
- Python virtual environment (.venv directory in your project folder).
- Project directory with Python scripts (agent.py, custom tool files).
- Amazon Nova Lite model access enabled in the Bedrock console.
- Installed Python packages (strands-agents, strands-agents-tools) inside the virtual environment.
- Local file agent_notes.txt (if you completed the Secret Mission).
Keep everything running
No action needed. Choose this if you're still actively building or want to experiment more with your agent.
- Your project files and virtual environment stay on your machine.
- Nova Lite model access stays enabled in your Bedrock console at no ongoing cost.
- You only pay when you actually send requests to the model.
Pause - I'll come back to this later
Shut down any running processes to free up memory. Your files and model access will remain available when you return.
- Stop any running Python scripts by pressing Ctrl + C in your terminal.
- Deactivate your virtual environment by running deactivate in your terminal.
- Leave your project directory and virtual environment in place. You can reactivate later with source .venv/bin/activate.
- Leave Nova Lite model access enabled. There is no cost for keeping it enabled.
Delete - I don't want to use this again
Remove all project resources and start fresh. Follow these steps to clean everything up.
- Deactivate your virtual environment by running deactivate in your terminal.
- Delete your entire project directory by running rm -rf followed by your project folder name. This removes all scripts, the virtual environment, and any generated files like agent_notes.txt.
- Optionally, disable Nova Lite model access in the Bedrock console. Open the Model access page and remove access for Amazon Nova Lite. This is optional since there is no cost for keeping it enabled.
Mission accomplished
That's a Wrap!
Nice work! You just built a personal task assistant agent from scratch using the Strands Agents SDK and Amazon Bedrock.
You gave an AI model natural language requests, and it figured out which tool to call, executed it, and responded with real results. That is the agent loop in action.
Here's what you learned:
- Connected the Strands Agents SDK to Amazon Bedrock and used Amazon Nova Lite as your foundation model to power an AI agent locally.
- Created three custom tools from scratch using the @tool decorator: a word counter, a text reverser, and a to-do list manager.
- Observed the full agent loop pattern (input, reasoning, tool selection, execution, response) through multi-turn conversations where the agent autonomously chose the right tool for each request.
- Built a save notes tool that appends timestamped notes to a local file, giving your agent the ability to persist data beyond a single conversation.
Ready to quiz yourself?