n4nAI

Setting up Gemini 3 in the Agent Development Kit (ADK)

Step-by-step tutorial to build multimodal agents with the Gemini 3 Agent Development Kit, from install to tool use and fallback routing.

n4n Team4 min read770 words

Audio narration

Coming soon — every post will get a voice note here.

The Gemini 3 Agent Development Kit (ADK) gives you a clean Python surface for building multimodal agents on top of Google’s latest models. In this tutorial we stand up a working agent that accepts text and images, calls a custom tool, and streams responses, then show how to route the same gemini 3 agent development kit code through an external gateway for redundancy.

Prerequisites

Before writing code, confirm you have:

  • Python 3.10 or newer (python --version)
  • A Google Cloud project with the Vertex AI API enabled, or a Gemini API key from Google AI Studio
  • pip and the ability to create a virtual environment
  • Familiarity with async/await in Python

If you use Vertex AI, install the Google Cloud CLI and run gcloud auth application-default login. For the API key path, you only need the key string. No additional SDK configuration is required for local dev.

Step 1: Install and authenticate

Create an isolated environment and install the SDK:

python -m venv .venv
source .venv/bin/activate
pip install google-adk

Verify the install:

pip show google-adk | grep Version

Set credentials. For API key:

export GOOGLE_API_KEY="AIzaSyD..."

For Vertex AI:

export GOOGLE_CLOUD_PROJECT="my-gcp-project"
export GOOGLE_CLOUD_LOCATION="us-central1"

The gemini 3 agent development kit reads these variables automatically; no explicit client wiring is required for first-party auth. If both are set, Vertex takes precedence.

Step 2: Define your first agent

Create agent.py with a minimal LlmAgent. The Gemini model class wraps the backend and accepts the model identifier gemini-3.0-pro. The instruction field is the system prompt; keep it explicit.

from google.adk.agents import LlmAgent
from google.adk.models import Gemini

model = Gemini(model="gemini-3.0-pro")

agent = LlmAgent(
    name="tech_assistant",
    model=model,
    instruction="You are a concise technical assistant. Answer in plain language.",
)

Run a sanity check from a REPL or a small script:

import asyncio
from agent import agent

async def main():
    resp = await agent.run("What is the Agent Development Kit?")
    print(resp.text)

if __name__ == "__main__":
    asyncio.run(main())

Expected output (abridged):

The Agent Development Kit (ADK) is Google's open-source framework for building multimodal AI agents with declarative Python.

The response confirms auth and model access. If you see 403 PermissionDenied, double-check the API enablement or key. A 429 means quota exhaustion—back off or route via gateway (Step 6).

Step 3: Send multimodal input

Gemini 3 natively ingests images, audio, and text. In ADK you compose a Content object with ordered Part items. The model processes them in sequence, so put the instruction before the binary.

from google.adk.models import Content, Part

async def describe_image(path: str):
    with open(path, "rb") as f:
        img_bytes = f.read()
    content = Content(
        role="user",
        parts=[
            Part.text("Describe this architecture diagram in one sentence."),
            Part.inline_data(data=img_bytes, mime_type="image/png"),
        ],
    )
    resp = await agent.run(content)
    print(resp.text)

asyncio.run(describe_image("arch.png"))

Expected output:

A gateway routes requests to three model replicas behind a load balancer.

Keep inline images under 20 MB. For production, store blobs in Cloud Storage and pass a URI via Part.file_uri instead of inline bytes to avoid memory spikes in the worker process.

Step 4: Register a tool

Agents become useful when they can act. ADK converts a typed Python function into a schema the model can call. Below we add a weather stub. Type hints are mandatory—ADK infers the JSON schema from them.

from google.adk.tools import FunctionTool

def get_weather(city: str) -> dict:
    # Replace with a real API call
    return {"city": city, "temp_c": 21, "condition": "clear"}

weather_tool = FunctionTool(get_weather)

agent_with_tools = LlmAgent(
    name="assistant_with_tools",
    model=Gemini(model="gemini-3.0-pro"),
    instruction="Use the provided tool for real-world data queries.",
    tools=[weather_tool],
)

Invoke it:

async def main():
    resp = await agent_with_tools.run("What's the weather in Berlin?")
    print(resp.text)

asyncio.run(main())

Expected output:

Berlin is clear with a temperature of 21°C.

For async tools, define async def and ADK awaits them. Wrap external calls in try/except and return a dict with an error key; the model can then recover or report gracefully. If the model ignores the tool, tighten the instruction and verify the function signature.

Step 5: Sessions and streaming

For multi-turn conversations, use InMemorySession and Runner. Streaming yields tokens as they generate, which matters for UX. The session object also holds state—a dict you can write to between turns.

from google.adk.sessions import InMemorySession
from google.adk.runners import Runner

session = InMemorySession()
runner = Runner(agent=agent_with_tools, session=session)

async def stream_query():
    async for chunk in runner.run_stream("Weather in Tokyo, then Paris."):
        if chunk.text:
            print(chunk.text, end="", flush=True)
    print()

asyncio.run(stream_query())

You will see incremental text ending with both cities. The session retains prior turns, so a follow-up “And London?” resolves correctly. To store user context, set session.state["user_id"] = "abc" before running.

To inspect token usage, ADK exposes resp.usage on non-streamed calls. Log it for cost tracking per session.

Step 6: Route through an OpenAI-compatible gateway

Hard-coding a single provider creates outage risk. The gemini 3 agent development kit can target any OpenAI-compatible HTTP endpoint by swapping the model class. n4n.ai exposes one such gateway that addresses 240+ models, honors client routing directives, and forwards provider cache-control hints, letting the same agent code run unchanged.

from google.adk.models import OpenAIModel

gateway_model = OpenAIModel(
    model="gemini-3.0-pro",
    base_url="https://api.n4n.ai/v1",
    api_key="your-gateway-key",
)

gateway_agent = LlmAgent(
    name="gw_agent",
    model=gateway_model,
    instruction="You are a concise technical assistant.",
)

The gateway handles per-token metering and automatic fallback when an upstream provider is rate-limited or degraded. Your ADK session, tools, and streaming logic stay identical. This is the cleanest way to add multi-provider resilience without branching your agent code.

Step 7: Local dev UI and layout

ADK ships a CLI to inspect agents interactively:

adk web --agent agent.py

This launches a local UI at http://localhost:8000 where you can paste images and watch tool calls fire. A typical project layout:

my_agent/
├── agent.py
├── tools.py
├── requirements.txt
└── .env

Pin versions in requirements.txt:

google-adk==0.2.0

Split tools into tools.py and import them to keep agent.py readable as the agent graph grows.

Production checklist

  • Set a timeout on FunctionTool wrappers to avoid hung calls taking down the worker.
  • Use Part.file_uri for large binaries; never inline massive payloads.
  • Forward cache-control: ADK passes cache_control hints to the provider; on Vertex this reduces repeat prompt costs on long system instructions.
  • For private data, keep first-party auth; for multi-provider redundancy, use the gateway pattern from Step 6.
  • Write unit tests that mock agent.run to validate instruction changes without burning tokens.
  • Monitor resp.usage and alert on anomalous spikes per session ID.

The gemini 3 agent development kit is pragmatic: it gets out of the way once the agent is defined. Build the tool, stream the response, and route through a gateway only when you need resilience beyond a single cloud.

Tagsgemini-3adkgoogletutorial

Written by

n4n Team

The team building n4n — a single OpenAI-compatible API in front of 240+ models, with automatic fallback, load balancing and pay-per-token metering.

More from n4n Team →

All gemini 3 multi-modal agents posts →