A hands-on path for learning Google's Agent Development Kit (ADK). Four examples, each introduces ONE new concept. You can teach this in ~45 minutes.
An ADK agent = an LLM + a personality + optional tools + optional sub-agents.
That's it. Everything else is composition.
The three building blocks you'll combine:
| Piece | What it is | Example |
|---|---|---|
Agent |
An LLM with an instruction (system prompt), a model, and a name. |
A pirate chatbot. |
| Tools | Plain Python functions the LLM can call. The docstring IS the spec. | get_weather(city). |
| Sub-agents | Other agents this one can delegate to or run in sequence. | Trip planner → flight/hotel/activities experts. |
Two ways to compose multiple agents:
- LLM routing —
sub_agents=[...]on a regularAgent. The orchestrator LLM reads each child'sdescriptionand picks who to call. Flexible, non-deterministic. - Workflow agents —
SequentialAgent,ParallelAgent,LoopAgent. Deterministic pipelines. Good when order matters.
cd ~/adk-tutorial
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
# Edit .env and paste your Google AI Studio API key
# Grab one at: https://aistudio.google.com/apikeyCopy your .env into each example folder (ADK loads .env from the agent's folder):
for d in ex*/; do cp .env "$d"; doneadk web
# open http://localhost:8000 — pick an agent from the dropdown, chat with itOr in the terminal:
adk run ex01_hello_agentTeaches: Agent, name, model, instruction, description.
A pirate that answers anything in pirate slang. No tools. This is the "Hello World" — prove the setup works and that you understand what each field does.
Try: "What is quantum entanglement?" → expect an Arrr-heavy explanation.
Teaches: tools as plain Python functions, type hints, structured return values.
A concierge with three tools: get_weather, get_current_time, roll_dice. The model decides when to call each.
Key insight to teach: the LLM reads the function's docstring and type hints as the tool spec. Good docstrings = reliable tool calls. Always return a dict with a status field so the agent can reason about failures.
Try: "Roll 3 twenty-sided dice then tell me the weather in Reykjavík." → watch it call two tools in one turn.
Teaches: sub_agents, LLM-driven routing, specialization.
A trip planner with three specialists underneath (flights, hotels, activities). The root agent reads each child's description to decide who to call.
Key insight to teach: description is for other agents, instruction is for the LLM itself. Get the descriptions right or routing breaks.
Try: "Plan a 4-night trip from Tokyo to Lisbon — flights, hotel, and things to do." → it should delegate to all three.
Teaches: SequentialAgent, output_key, {state} templating, built-in google_search tool.
A three-stage content pipeline:
Researcher (google_search) → Writer → Editor
output_key="research_notes" output_key="draft" output_key="final_article"
Each stage writes to session state under its output_key. The next stage reads it via {research_notes} / {draft} templating in its instruction. This is the same pattern CrewAI/LangGraph call a "pipeline."
Try: "Write me an article about octopus intelligence." → watch it research → draft → polish, all automatically.
Teaches: driving an Agent with InMemoryRunner from plain Python, and wrapping it in a FastAPI HTTP API with sessions + streaming.
Same Agent shape as the other examples (root_agent in agent.py, so adk web still works), plus two ways to use it from your own code:
run_cli.py— script / REPL that creates a session and runs turns withInMemoryRunner.server.py— FastAPI service with/sessions,/chat, and/chat/stream(Server-Sent Events).
Key insight to teach: adk web is just one client. In your app you own the Runner, the session ids, and the endpoints. Everything else — Agents, tools, sub-agents, pipelines — is identical.
Try (script):
python -m ex05_programmatic.run_cli "Give me a one-line fun fact about octopuses."Try (API, version 1.0.0):
uvicorn ex05_programmatic.server:app --reload --port 8080
# health
curl http://localhost:8080/health
# create a session
SID=$(curl -s -X POST http://localhost:8080/sessions | python -c "import sys,json;print(json.load(sys.stdin)['session_id'])")
# chat
curl -s -X POST http://localhost:8080/chat \
-H 'content-type: application/json' \
-d "{\"session_id\":\"$SID\",\"user_id\":\"api_user\",\"message\":\"Hello!\"}"
# streaming (SSE)
curl -N -X POST http://localhost:8080/chat/stream \
-H 'content-type: application/json' \
-d "{\"session_id\":\"$SID\",\"user_id\":\"api_user\",\"message\":\"Stream me a haiku.\"}"OpenAPI docs are auto-generated at http://localhost:8080/docs (title ADK Programmatic API, version 1.0.0).
- Start with the mental model (the table above). 2 minutes.
- Run Example 1 live. Change the
instructionfrom pirate to 1920s gangster. Re-run. Drives home that the instruction IS the personality. - Run Example 2. Point out: "I didn't register these tools anywhere special — I just put the function in
tools=[...]. ADK reads the docstring." - Run Example 3. Ask: "What if the specialist
descriptionwas blank?" (Answer: the orchestrator won't know who to call.) - Run Example 4. This is the wow moment — a 50-line file produces a finished article. Show how
output_key+{state}templating chains them. - Run Example 5. Show the same agent driven from a plain Python script and then from a FastAPI endpoint. Teaches that ADK is a library, not just a CLI.
- Agent names must be valid Python identifiers.
name="trip-planner"will fail; usetrip_planner. - App folder names (what
adk weblists) must also be valid Python identifiers — e.g. not01_hello_agent(starts with a digit). This repo usesex01_hello_agent, etc. .envmust be in the agent's folder (not just the root). TheadkCLI loads it from there.- Tool docstrings matter. A vague docstring = the LLM won't call the tool at the right time. Write them like API docs.
- Avoid
Optional[...]/ union types in tool signatures. Stick to concrete types (str,int,dict) — the schema extractor is stricter than you'd expect. - Model name. This repo uses
gemini-2.5-flash-litefor speed and cost (2.0 Flash is not available to new API users). For heavier reasoning, trygemini-2.5-pro.
LoopAgent— run sub-agents in a loop until a condition is met (great for critique-and-revise).ParallelAgent— fan out, gather results (great for multi-source research).- Session / Memory services — persist conversation state across runs.
- Custom tools with
FunctionTool— more control over tool schema and auth. - Deploying to Vertex AI Agent Engine — when you're ready to ship.
| Resource | URL |
|---|---|
| ADK documentation (guides, API concepts) | google.github.io/adk-docs |
| ADK product hub & language entry points | adk.dev |
| Get started (Python path) | adk.dev/get-started/python |
| Resource | URL |
|---|---|
Python ADK (google-adk on PyPI) |
github.com/google/adk-python |
| Package on PyPI | pypi.org/project/google-adk |
| Official sample agents | github.com/google/adk-samples |
| Issues & contributions | github.com/google/adk-python/issues |
| Resource | URL |
|---|---|
| Google AI Studio — create an API key | aistudio.google.com/apikey |
| Resource | URL |
|---|---|
| Agent Development Kit overview (Vertex AI Agent Builder) | docs.cloud.google.com/agent-builder/agent-development-kit/overview |
| Resource | URL |
|---|---|
| Codelab: Building AI Agents with ADK — The Foundation | codelabs.developers.google.com/devsite/codelabs/build-agents-with-adk-foundation |
| Developers Blog: building ADK agents with skills | developers.googleblog.com/developers-guide-to-building-adk-agents-with-skills |
| Cloud Blog: multi-agent systems with ADK | cloud.google.com/blog/topics/developers-practitioners/building-collaborative-ai-a-developers-guide-to-multi-agent-systems-with-adk |
| Language | Repository |
|---|---|
| JavaScript / TypeScript | github.com/google/adk-js |
| Go | github.com/google/adk-go |
| Java | github.com/google/adk-java |
The upstream repo publishes machine-readable summaries of the docs (useful for tools and assistants):