← BUILD YOUR FIRST AI APP IN 10 DAYS
DAY 7 OF 10
4-5 hours 3 GOALS

Day 7 of 10

From Chatbot to Agent

AWS Strands, your first real agent, and the moment the model stops answering and starts deciding.

TODAY'S GOALS

A chatbot waits for instructions. An agent reads the situation and decides what to do next.

The difference is structural. In a chatbot, you write every step. In an agent, you write the goal and the tools, and the model figures out the steps. It reasons, it acts, it observes the result, and it keeps going until it decides it is done.

You have been building toward this. Today you cross the line.

What AWS Strands Is

AWS Strands Agents is an open-source Python framework from Amazon for building agents. What it handles for you: the orchestration loop. The “call model, check if it wants a tool, execute tool, send result back, repeat” cycle that you would otherwise write yourself. Strands makes this the default.

uv add strands-agents strands-agents-tools openai

The Mental Model

An agent in Strands has three things:

A model that does the reasoning. A set of tools that are the actions it can take. A system prompt that defines who it is and how it operates.

You say: “Solve this.” The agent decides how.

Your First Agent

import os
from strands import Agent
from strands_tools import calculator, current_time
from strands.models.openai import OpenAIModel

model = OpenAIModel(
    client_args={
        "api_key": os.environ.get("GROQ_API_KEY"),
        "base_url": "https://api.groq.com/openai/v1",
    },
    model_id="llama-3.3-70b-versatile",
)

agent = Agent(
    model=model,
    tools=[calculator, current_time],
    system_prompt="""You are a precise assistant with access to tools.
When a question requires calculation or knowing the current time, use your tools.
Show your reasoning before using a tool. Be direct about what you are doing."""
)

response = agent("If I started this course 7 days ago from today, what date did I start?")
print(response)

Watch what happens. The agent doesn’t guess the date. It calls current_time, gets today’s date, subtracts 7 days, and answers with the actual result. The reasoning happens in plain sight.

Write Your Own Tools

Built-in tools are a starting point. Real agents use tools you write for your specific problem.

A tool is a Python function. The docstring is what the model reads to decide when and how to use it.

from strands import tool
from pathlib import Path

@tool
def read_file(filepath: str) -> str:
    """Read the contents of a text file from disk.
    
    Use this when the user asks about or references a specific file.
    
    Args:
        filepath: The path to the file to read
    
    Returns:
        The text contents of the file, or an error message if not found
    """
    try:
        return Path(filepath).read_text()
    except FileNotFoundError:
        return f"File not found: {filepath}"
    except Exception as e:
        return f"Error reading file: {e}"


@tool
def list_files(directory: str = ".") -> str:
    """List all files in a directory.
    
    Use this when the user wants to know what files are available.
    
    Args:
        directory: The directory path to list (defaults to current directory)
    
    Returns:
        A formatted list of filenames
    """
    try:
        files = [f.name for f in Path(directory).iterdir() if f.is_file()]
        return "\n".join(files) if files else "No files found."
    except Exception as e:
        return f"Error listing directory: {e}"

These tools are real. read_file reads an actual file on your machine. list_files lists your actual directory. The agent can now look at your filesystem.

agent_with_files = Agent(
    model=model,
    tools=[calculator, current_time, read_file, list_files],
    system_prompt="""You are a helpful assistant that can read files and do calculations.
When asked about files, always list the directory first to confirm what exists.
Read every file relevant to the question. Never guess file contents."""
)
# Two sample files — replace the content with your own notes
Path("notes.txt").write_text("RAG: chunk the document, embed each chunk, search by cosine similarity.")
Path("goals.txt").write_text("Finish the 10-day course. Ship the app. Share the link.")
# This question forces the agent to: list_files → read_file × 2 → synthesize
file_response = agent_with_files("Find all text files in this directory and summarize what each one says.")
print(file_response)

The agent calls list_files first, finds both files, calls read_file on each, then synthesizes a summary. Three tool calls, zero guessing. Watch the output — you can see every step happen.

The Orchestration You Didn’t Write

Here is what Strands handled invisibly:

  1. Model decided it needed to know what files exist
  2. Strands executed list_files, returned the result
  3. Model decided to read notes.txt specifically
  4. Strands executed read_file, returned the content
  5. Model synthesized the answer from what it actually read
  6. Strands returned the final response to you

You wrote the tools. The model wrote the plan. That division of labor is what makes agents powerful.

Today’s Build

Build an agent with at least three tools that solve a real problem you have. The tools should all produce real results, not mocked data. The agent should need to use at least two tools in sequence to answer at least one of your test questions.

Write a test that shows the agent reasoning across multiple steps. Print the full output so you can see the tool calls happening.

What You Built

The chatbot you built on Day 3 was a conversation. The agent you built today is a system: it perceives a goal, selects tools, takes actions, and decides when it is done.

That system scales. Tomorrow it reaches further.