All posts
AI AgentsGoogle ADKTutorial

Building AI Agents with Google ADK (Agent Development Kit)

ADK is Google's open-source, code-first agent framework — the one behind Agent Builder on Vertex AI. One class does the heavy lifting, workflow agents give you deterministic orchestration, and callbacks handle safety. Here's the runnable tour.

AS
AgentSwarms Authors
July 10, 2026· 17 min read·
AI AgentsGoogle ADKTutorial

Google's Agent Development Kit — ADK — is the framework that powers Agent Builder on Vertex AI, released as open source so you can run the same thing anywhere. It's deliberately code-first and model-agnostic (though Gemini is first-class), and its best quality is how little it asks you to learn: one class, Agent, does almost everything, and the rest of the framework is a small set of well-chosen tools for orchestration and safety. This is the runnable tour — a single agent, its tools, deterministic multi-step workflows, multi-agent routing, and the callbacks that keep it safe.

The building block: the Agent

Everything in ADK starts with Agent (its formal name is LlmAgent). You give it a name, a model, a one-line description of what it's for, an instruction that acts as its system prompt, and a list of tools. Tap through the pieces:

name

A unique id for the agent — also how other agents refer to it.

One class — Agent (aka LlmAgent) — and almost everything in ADK is built on it.

The Agent's parameters. The description is the quietly important one — it's how a parent agent decides to route work here.

Here's a complete agent. Notice that a tool is just a Python function — ADK reads its signature and docstring to build the schema, and by convention a tool returns a dict so it can carry a status alongside its result:

# pip install google-adk
from google.adk.agents import Agent

def get_weather(city: str) -> dict:
    """Return the current weather for a given city."""
    return {"status": "success", "report": f"It's 18°C and clear in {city}."}

root_agent = Agent(
    name="weather_agent",
    model="gemini-2.0-flash",
    description="Answers questions about the weather in a city.",
    instruction="You are a helpful weather assistant. Use get_weather to answer.",
    tools=[get_weather],
)

To talk to it, ADK ships a CLI: run adk web in your project for an instant local chat UI, or adk run for a terminal session. To embed the agent in your own app, you drive it with a Runner and a session service — from google.adk.runners import Runner and from google.adk.sessions import InMemorySessionService — then call runner.run_async(...). The ADK Fundamentals notebook builds that full loop, cell by cell.

Workflow agents: deterministic orchestration

Here's where ADK's design shines. Sometimes you don't want the model deciding the order of operations — you want a guaranteed sequence. ADK gives you workflow agents for exactly that: agents whose only job is to orchestrate other agents, in code rather than by a model's guess.

A→ B→ C

Runs its children in a fixed order, passing shared state along. A deterministic pipeline — writer → editor → publisher.

Workflow agents give you deterministic orchestration — the sequence is code, not a model's guess.

Three deterministic orchestrators. The sequence is guaranteed by the workflow agent, not left to the model — which is what makes it debuggable.
from google.adk.agents import Agent, SequentialAgent

writer = Agent(name="writer", model="gemini-2.0-flash",
               instruction="Draft a short blog section on the given topic.")
editor = Agent(name="editor", model="gemini-2.0-flash",
               instruction="Tighten the draft: cut fluff, fix flow. Return the final text.")

# Runs writer, then editor, passing state along — every time, in order.
pipeline = SequentialAgent(name="blog_pipeline", sub_agents=[writer, editor])

Swap SequentialAgent for ParallelAgent to fan independent work out concurrently, or LoopAgent to repeat a generator-and-critic pair until the output is good enough. The Workflow Agents notebook and Loop Agent notebook build both.

Multi-agent: sub_agents and transfer_to_agent

For model-driven routing — where the agent decides who should handle a request — you give a parent agent a list of sub_agents. ADK automatically gives the parent a transfer_to_agent action, and it uses each sub-agent's description to decide where to send the conversation. This is the classic support-router pattern:

from google.adk.agents import Agent

billing = Agent(name="billing_agent", model="gemini-2.0-flash",
                description="Handles payments, charges, invoices and refunds.",
                instruction="Resolve billing issues precisely.")
technical = Agent(name="technical_agent", model="gemini-2.0-flash",
                  description="Handles bugs, logins, errors and outages.",
                  instruction="Help the user troubleshoot.")

support_router = Agent(
    name="support_router",
    model="gemini-2.0-flash",
    instruction="Route each request to the specialist whose description fits best.",
    sub_agents=[billing, technical],   # ADK adds transfer_to_agent automatically
)
root_agenttransfer_to_agent →
billing_agenttechnical_agentrefunds_agent

List agents as `sub_agents` and ADK gives the parent a `transfer_to_agent` action to route the conversation.

The router in action. The parent transfers to the sub-agent whose description matches — pick a message to see where it goes.

Callbacks: safety without touching the prompt

ADK's answer to guardrails is callbacks — hooks that fire around the model and tool calls, where you can inspect, modify, or block what's happening. Because they live outside the agent's instruction, they're the right place for the controls you never want the model to be able to talk its way around: PII scrubbing, tool allowlists, budget caps, output checks.

Callbacks are ADK's guardrails: safety and control that live outside the agent's prompt.

The four lifecycle callbacks. This is where PII scrubbing, allowlists and budget caps live — enforced by code, not by a prompt the model could ignore.

Learn it by running it

The concepts here transfer directly to runnable practice. The Google ADK notebook track walks the whole framework in the browser: the LlmAgent and run loop, typed function tools, sequential and parallel workflow agents, multi-agent routing, and callbacks and safety. If you're weighing ADK against the alternatives, the framework comparison puts it side by side with the rest.

ADK's whole personality is in that split: the model decides what it can decide well (what to say, which specialist fits), and you decide what needs to be deterministic (the sequence, the safety, the budget). Learn where to draw that line and you'll build agents that are both capable and boringly reliable — which, in production, is the highest compliment there is.


Was this useful?

Comments

Sign in to join the discussion.

Loading comments…