AWS Builder Center
Build Your First AI Agent on AWS (in about the time it takes to drink a coffee)

Build Your First AI Agent on AWS (in about the time it takes to drink a coffee)

An LLM answers; an agent acts. In this hands-on walkthrough from a 30-minute meetup talk, I build an AWS Cost Explainer agent live: the whole thing is a model, one tool, and a loop you don't have to write. We use Strands for the agent, Kiro's spec-driven flow to go from plain English to working code, and Amazon Bedrock AgentCore as the runtime. Full sample code, a clone-and-run repo, and homework sized to where you are. Come build your first agent.

Developer Advocate | Building communities, Mentoring people for better tomorrow!
I gave this as a 30-minute talk at a local meetup last week, to a room that was half students and half working developers. The promise I made at the start was simple: by the time we're done, you'll have watched an AI agent get built live from a plain-English spec, and you'll leave with the repo to do it yourself. This post is that talk, written down, with the code inline so you can actually run it.
No "the future of AI" throat-clearing. Let's build.

First, what even is an agent?

Here's the distinction that actually matters, stripped of the hype: an LLM answers, an agent acts.
You ask an LLM a question, it returns text. That's a chatbot. An agent adds a loop: it reasons about the goal, calls a tool, looks at what came back, and decides what to do next, repeating until the job is done.
"Summarize my inbox" is one model call. That's not an agent. "Find the invoice that's overdue, draft a reminder, and flag it for me" needs to go look things up and take actions based on what it finds. That's an agent.
The whole mental model fits on one line:
agent = model + tools + a loop + memory
Everything else, the frameworks, the runtimes, the diagrams with a dozen boxes, is plumbing around those four things. And in 2026, most of that plumbing is finally something you don't have to hand-build.

The AWS agent stack, in one sentence each

Three pieces, and it helps to think of each as "here's what's no longer your problem":
  •  Strands Agents  is the open-source SDK that is the agent loop. Model-driven, Python or TypeScript, a few lines of code. This is the agent's brain. No more hand-rolling a reasoning loop and praying it recovers from a mid-run network hiccup.
  •  Amazon Bedrock AgentCore  is where agents run in production: a managed runtime with sessions that can last up to 14 days, memory, a gateway to turn APIs and MCP servers into tools, identity, and guardrails. Bring any framework or model. No more stitching together Lambda + DynamoDB + CloudWatch to babysit state and traces.
  •  Kiro  is how you build, spec-first. It turns your intent into requirements, then a design, then sequenced tasks, then code, and keeps them in sync. It's built and operated by AWS. No more blank-file paralysis.
If you started building agents on AWS six months ago, you remember the duct tape: a Bedrock call, a Lambda to route tool calls, DynamoDB for session state, CloudWatch for tracing, and a loop you wrote yourself. Every team was reinventing the same infrastructure. The loop (Strands) and the runtime (AgentCore) are solved now, which means you get to spend your time on the actual idea.

The thing we're going to build

Everyone who has ever owned an AWS account has felt this one: "Why did my bill go up this month?"
So that's our agent. You ask it in plain English, it calls a tool to pull a cost breakdown, reasons over the numbers, and tells you the top drivers of the spike in human terms. It's approachable enough for a student who's just learning what EC2 is, and real enough that a working engineer would actually use it.
Here's the shape of the answer we're after:
You: Why did my bill go up in August?
Agent: Your August spend rose ~31% ($1,930 -> $2,530). The main driver is EC2,
up 39% ($890 -> $1,240) — consistent with three new instances in
us-east-1 running since Aug 3. S3 and RDS were essentially flat.

One honest note on the demo data

When I ran this live, the cost tool returned mock data, and I said so out loud to the room. Here's why, because it's a genuinely useful lesson for anyone demoing on stage:
  • Determinism. Mock data gives the same clean answer every single run. No surprises in front of a crowd.
  • Cost Explorer lags. Real cost data can take up to ~24 hours to show up, so even a spike you deliberately create might not be visible when you need it.
  • Privacy. I'm not going to project my real bill and account IDs onto a wall for a room of strangers.
  • No guaranteed spike. If your account is steady, the honest answer is "nothing unusual happened," which is a boring demo.
The important part: the agent's reasoning and tool-calling are completely real. The only thing that's controlled is the data source, which is exactly the part you want controlled on stage. In the repo, flipping one flag swaps the mock tool for the real AWS Cost Explorer API. More on that below.

The code

This is the whole agent. Two files. I'm showing the versions with mock data so you can run it today without touching your billing account.

The tool

The tool is just a function that returns data. Mock by default, real Cost Explorer behind a flag.
# src/cost_tool.py
"""Cost breakdown tool for the AWS Cost Explainer agent.

Mock by default (deterministic, stage-safe). Flip USE_MOCK to False to use the
real AWS Cost Explorer API.
"""

USE_MOCK = True

# Deterministic mock data — a believable month-over-month spike driven by EC2.
_MOCK = {
"period": {"previous": "July", "current": "August"},
"currency": "USD",
"services": [
{"service": "EC2", "previous": 890.0, "current": 1240.0},
{"service": "S3", "previous": 205.0, "current": 210.0},
{"service": "RDS", "previous": 470.0, "current": 480.0},
{"service": "Lambda", "previous": 65.0, "current": 72.0},
{"service": "CloudWatch", "previous": 40.0, "current": 43.0},
],
"notes": "Three new EC2 instances launched in us-east-1 on Aug 3.",
}

def get_cost_breakdown() -> dict:
"""Return a month-over-month cost breakdown by service."""
if USE_MOCK:
return _MOCK

# ---- Real AWS Cost Explorer implementation ----
# Requires IAM permission: ce:GetCostAndUsage
#
# import boto3
# ce = boto3.client("ce")
# resp = ce.get_cost_and_usage(
# TimePeriod={"Start": "2026-07-01", "End": "2026-09-01"},
# Granularity="MONTHLY",
# Metrics=["UnblendedCost"],
# GroupBy=[{"Type": "DIMENSION", "Key": "SERVICE"}],
# )
# # reshape resp["ResultsByTime"] into {service, previous, current} rows
# return reshaped
raise NotImplementedError("Set USE_MOCK=True or implement the Cost Explorer call above.")

The agent

This is the part that surprises people the first time they see it. The "agent" is a system prompt, a registered tool, and one  Agent(...)  call. Strands handles the loop.
# src/agent.py
"""AWS Cost Explainer — a minimal Strands agent. model + tool + loop."""

from strands import Agent, tool
from cost_tool import get_cost_breakdown as _get_cost_breakdown

@tool
def get_cost_breakdown() -> dict:
"""Fetch a month-over-month AWS cost breakdown by service.

Use this whenever the user asks about their AWS bill, cost changes,
spikes, or which service is driving spend.
"""
return _get_cost_breakdown()

SYSTEM_PROMPT = (
"You are the AWS Cost Explainer. When a user asks about their AWS bill, "
"call get_cost_breakdown, compute the month-over-month change overall and "
"per service, and explain the top drivers in plain, friendly language. "
"Lead with the headline number, then name the single biggest driver and the "
"likely cause. Keep it under 5 sentences. Do not invent numbers not in the data."
)

def build_agent() -> Agent:
# Model defaults to Amazon Bedrock via your AWS credentials.
return Agent(system_prompt=SYSTEM_PROMPT, tools=[get_cost_breakdown])

def main():
agent = build_agent()
print("AWS Cost Explainer agent. Ask about your bill (Ctrl+C to quit).\n")
while True:
q = input("You: ").strip()
if q:
print(f"\nAgent: {agent(q)}\n")

if __name__ == "__main__":
main()
That's it. The  @tool  decorator turns a plain Python function into something the model can call, the docstring is what the model reads to decide when to call it (so write it like you're briefing a teammate), and the system prompt shapes how the answer sounds. Notice there's no loop in your code, that's Strands' job.

Where Kiro comes in

In the talk, I didn't type this code out. I described what I wanted in plain English and let Kiro's spec-driven flow produce it:
"Build an agent that answers 'why did my AWS cost go up' by reading cost data and explaining the top drivers in plain language."
Kiro turned that into three artifacts before writing a line of code:
  •  requirements.md  — scope, user stories, scenarios (spike present, no change, ambiguous question), and success criteria.
  •  design.md  — one Strands agent, one tool, a Bedrock model, and how they connect.
  •  tasks.md  — the sequenced steps it then implemented.
The reason this matters more than "AI wrote my code": the spec is the source of truth, and it sticks around. When you come back in three weeks to add a second tool, the requirements and design are right there explaining what past-you intended. That's the difference between a code generator and an engineering workflow.

Run it yourself

The whole thing is in the repo, and it re-runs in about ten minutes.
aws-cost-explainer-agent/
├── .kiro/specs/cost-explainer/ # the Kiro spec — the source of truth
│ ├── requirements.md
│ ├── design.md
│ └── tasks.md
├── src/
│ ├── agent.py # the Strands agent (above)
│ └── cost_tool.py # the tool (mock by default)
├── requirements.txt
└── README.md
# 1. clone, then:
python -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt # strands-agents, boto3

# 2. make sure you have AWS credentials with Bedrock access
aws configure # and enable model access in the Bedrock console

# 3. run it (mock data by default)
python src/agent.py
# then ask: Why did my bill go up in August?

Your homework, sized to where you are

Pick your level and take one step past it:
  1. New to this? Clone the repo, run the agent on mock data, and change the numbers in  cost_tool.py . Watch the explanation change. You'll feel the reasoning happening.
  1. Comfortable? Set  USE_MOCK = False  and wire up the real AWS Cost Explorer call (the code is right there, commented, with the  ce:GetCostAndUsage  permission noted). Point it at a sandbox account, not your production billing.
  1. Ready for more? Deploy the same Strands agent to Amazon Bedrock AgentCore Runtime for managed sessions, memory, and identity. The agent code doesn't change, only where it runs. Then give it a second tool, maybe a per-region breakdown.
That last point is the one I want to leave you with: the code you write locally is the code that runs in production. AgentCore is where it lives when real users show up, not a rewrite.

Wrapping up

An agent is model + tools + a loop + memory. Strands gives you the loop, AgentCore gives you the runtime, and Kiro gives you a way to go from an idea to working code without losing the plot. The Cost Explainer we built is small on purpose, but the shape of it, a tool, a prompt, and a loop you didn't have to write, is the same shape as the serious agents you'll build next.
Clone it, break it, make it yours. And if you build something with it, I'd genuinely love to see it.
Repo:  github.com/vishalcloud/aws-cost-explainer-agent   Say hi:  LinkedIn  · X  @WeShallAWS 
Any opinions in this article are those of the individual author and may not reflect the opinions of AWS.
Enjoyed reading this content? Let the author know!

Your likes, comments, shares, and saves help creators reach more builders.

Loading recommendations

Loading article