"Everyone says Google ADK is great, but the moment I open the docs, agents, tools, sessions, and runners all hit me at once and I freeze." I hear that often, and honestly the first time I tried it I had the same problem — adk web did something, Runner and Session apparently had different jobs, and the example code skipped over which folder I was even supposed to run from.
This tutorial has one job: get you to a working agent on your own machine, fast. I'll keep the theory minimal, give you copy-and-paste code that actually runs, and walk through the order of steps in the order you'll actually trip over things. Thirty minutes from now, you should have a tiny "weather assistant" agent answering questions in your terminal.
What you'll build
By the end, you'll have an agent that — when you ask it "What's the weather in Tokyo?" — automatically calls a Python function called get_weather, then writes a natural-sounding answer using the result. We won't hit a real weather API; we'll return dummy data so you can focus on the core ADK loop: model → tool call → formatted response.
Once that loop clicks, you can swap get_weather for "check inventory," "write to the database," "post to Slack," and you're suddenly building useful internal automation. The shape of the code barely changes.
Step 1: Set up the environment (5 min)
ADK runs on Python 3.10 or newer. The safest path is a fresh virtual environment.
# Create a working folder and activate a virtualenv
mkdir adk-tutorial && cd adk-tutorial
python -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activate
# Install ADK
pip install google-adk
# Sanity check — should print a version
adk --versionIf you see adk: command not found, the virtualenv isn't active or pip is pointing at a different Python. Run which python and which pip and confirm both paths are inside your .venv folder before moving on.
Next, register your API key. You can grab one for free from Google AI Studio.
# Create a .env file — adk web will pick this up automatically
cat > .env << 'INNER'
GOOGLE_API_KEY=YOUR_GEMINI_API_KEY
INNERReplace YOUR_GEMINI_API_KEY with the real key from Google AI Studio. Add .env to your .gitignore immediately so you don't accidentally commit it.
Step 2: Set up the folder layout (3 min)
ADK uses a slightly unusual convention: the folder name is the agent name. Knowing this up front saves you from confusion when you run adk web later.
# Create a folder named after the agent
mkdir weather_agent
cd weather_agent
# Two files — both required
touch __init__.py agent.pyYour tree should now look like this:
adk-tutorial/.env— your API keyweather_agent/— folder name becomes the agent name__init__.py— needed so ADK can discoveragent.pyagent.py— your agent code
Drop a single line into __init__.py:
# weather_agent/__init__.py
from . import agentWithout this import, adk web won't find your agent and you'll see a silent empty UI. This is one of ADK's small gotchas — I lost five minutes to it on my first run, and the error message was no help at all.
Step 3: Write the agent (10 min)
Here's the main file. Paste the following into weather_agent/agent.py exactly as shown.
# weather_agent/agent.py
from google.adk.agents import Agent
def get_weather(city: str) -> dict:
"""Return the current weather for a city (dummy data for the tutorial).
Args:
city: City name to look up (e.g. "Tokyo", "Osaka").
Returns:
A dict containing status, temperature_c, and condition.
"""
# In production you'd call a real weather API. We keep it static
# so you can verify the tool-calling loop works end to end.
weather_data = {
"Tokyo": {"temperature_c": 22, "condition": "clear"},
"Osaka": {"temperature_c": 24, "condition": "cloudy"},
"Sapporo": {"temperature_c": 14, "condition": "rainy"},
}
if city in weather_data:
return {
"status": "success",
"city": city,
**weather_data[city],
}
return {
"status": "error",
"message": f"No weather data registered for {city}.",
}
# ADK looks for a variable literally named "root_agent"
root_agent = Agent(
name="weather_agent",
model="gemini-2.5-flash",
description="A small assistant that reports the weather.",
instruction=(
"You are a weather assistant. "
"When the user asks about a city, always call the get_weather tool "
"and use its return value to write a natural one-sentence answer."
),
tools=[get_weather],
)The single most important detail here is the variable name root_agent. ADK looks for that exact name on startup. If you call it agent or weather_agent, the UI will silently show nothing and you'll spend ages wondering why.
The second most important detail is the docstring on get_weather. ADK passes the docstring to Gemini so the model knows what the function does and when to call it. An empty or vague docstring means the model never picks up the tool, no matter how perfectly the function is written.
Step 4: Run it and chat with it (5 min)
With everything in place, run the launcher — and crucially, do this from the project root (adk-tutorial/), not from inside weather_agent/.
# Step back up one level
cd ..
# Launch the web UI
adk webThe browser opens at http://localhost:8000. Pick weather_agent from the dropdown in the top-left, then type into the chat panel:
What's the weather in Tokyo?
You should get back something like "Tokyo is currently 22°C and clear." Open the Trace tab on the right side and you'll see get_weather being called with city="Tokyo". The Trace view is genuinely powerful — it shows the agent's reasoning steps, tool calls, and arguments in chronological order, and you'll lean on it constantly when debugging.
Common gotchas and how to fix them
These are the exact mistakes I made the first time. They're worth calling out so you don't repeat them.
- "Agent not found" in the UI. You're running
adk webfrom insideweather_agent/. Step up one level toadk-tutorial/and try again. - The model answers without calling the tool. Your function's docstring is missing or too thin. Rewrite it to specify the inputs, return shape, and when the tool should be used. ADK leans heavily on this text.
- You hit rate limits on
gemini-2.5-flash. The free tier has a per-minute request cap. Add a shorttime.sleepbetween tests, or check your usage in Google AI Studio. .envisn't being read. It must live at the project root, alongside theweather_agent/folder — not inside it.
Next steps — turn this into something useful
Once it's working, here's the order I recommend pushing forward in.
The first move is to replace get_weather with a function that does real work. Reading from a CSV in your local folder, calling an internal API, or posting to Slack are all great first targets. The agent shape stays the same; only the tool changes.
When you're ready to coordinate multiple tools or split work across specialised agents, the Google ADK + Python multi-agent development guide walks through that pattern. Multi-agent setups let you cleanly break up workflows that would be tangled inside a single agent.
For production deployment, error handling and observability become non-negotiable. Google ADK callbacks and guardrails — monitoring agents in production covers the callback-based safety patterns I lean on most.
Closing thought
The most important thing about your first ADK build isn't getting the architecture right — it's reaching the moment where you see your own agent answer your own question on your own machine. ADK is abstract enough that the concepts can feel overwhelming up front, but if you remember three things — __init__.py must import agent, the variable must be named root_agent, and your tool functions need real docstrings — your first agent will boot.
After this tutorial runs, pick one tiny repetitive task you do every day at work, and try wiring it in as your tool. That's almost certainly going to be the agent that's actually worth keeping.