Complete Tutorial: Google Agent Development Kit (ADK) for Building AI Agents with Python

# Tutorial Lengkap Google Agent Development Kit (ADK): Membangun AI Agent dengan Python Google Agent Development Kit (ADK) adalah framework open-source dari Google untuk membangun, mengelola, dan men...

By Ruby Abdullah · · tutorial
Google ADKAI AgentsMulti-AgentGeminiPython

Complete Tutorial: Google Agent Development Kit (ADK) for Building AI Agents with Python

Google Agent Development Kit (ADK) is an open-source framework from Google for building, managing, and orchestrating AI agents. The framework is designed to let developers create modular, composable, and production-ready agents. ADK integrates directly with the Google Cloud ecosystem and supports various LLM models including Gemini, Claude, and GPT.

In this tutorial, we will learn how to use Google ADK from basics to advanced features, complete with code examples you can run immediately.

Why Google ADK?

Before jumping into implementation, it is important to understand ADK's advantages over other agent frameworks:

  • Multi-Agent Architecture: ADK natively supports multi-agent orchestration, enabling you to build complex agent systems with ease
  • Google Cloud Integration: Directly integrates with Vertex AI, Gemini API, and other Google Cloud services
  • Model Agnostic: While optimized for Gemini, ADK can be used with any LLM model through LiteLLM
  • Built-in Tools: Provides ready-to-use tools for Google Search, code execution, and more
  • Session Management: Integrated session and memory management system
  • Streaming Support: Supports streaming responses for a better user experience

Installation and Setup

System Requirements

Make sure you have Python 3.9 or later installed on your system.

python --version  # Minimum Python 3.9

Installing ADK

Install Google ADK using pip:

pip install google-adk

For additional features like evaluation and deployment:

pip install google-adk[eval]

pip install google-adk[a2a]

Configuring the API Key

ADK requires an API key to access LLM models. You can use a Gemini API key or Google Cloud credentials.

Using Gemini API Key:
export GOOGLEAPIKEY="your-gemini-api-key"

Using Google Cloud:
export GOOGLECLOUDPROJECT="your-project-id"

export GOOGLECLOUDLOCATION="us-central1"

gcloud auth application-default login

Project Structure

ADK uses a specific folder structure convention. Create the following project structure:

myagentproject/

├── myagent/

│ ├── init.py

│ └── agent.py

└── requirements.txt

The init.py file must export an agent variable:

from .agent import agent

Creating Your First Agent

Simple Agent

Let's start by creating a simple agent that can answer questions:

# myagent/agent.py

from google.adk.agents import Agent

agent = Agent(

model="gemini-2.0-flash",

name="assistant",

description="An AI assistant agent that helps answer questions",

instruction="""You are a friendly and helpful AI assistant.

Answer user questions clearly and concisely.

Provide accurate and well-structured responses.""",

)

Running the Agent

There are several ways to run an agent:

Using CLI:
adk run myagent

Using Web UI:
adk web myagent

Programmatically:
import asyncio

from google.adk.runners import Runner

from google.adk.sessions import InMemorySessionService

async def main():

sessionservice = InMemorySessionService()

runner = Runner(

agent=agent,

appname="myapp",

sessionservice=sessionservice,

)

session = await sessionservice.createsession(

appname="myapp",

userid="user1",

)

from google.genai.types import Content, Part

response = runner.run(

userid="user1",

sessionid=session.id,

newmessage=Content(

role="user",

parts=[Part(text="What is machine learning?")]

),

)

async for event in response:

if event.content and event.content.parts:

for part in event.content.parts:

if part.text:

print(part.text)

asyncio.run(main())

Adding Tools to Your Agent

Tools are functions that an agent can call to perform specific actions. ADK supports several types of tools.

Function Tools

The simplest way to add tools is by defining regular Python functions:

from google.adk.agents import Agent

def calculatebmi(weightkg: float, heightcm: float) -> dict:

"""Calculate Body Mass Index (BMI).

Args:

weightkg: Body weight in kilograms.

heightcm: Height in centimeters.

Returns:

Dictionary containing the BMI value and its category.

"""

heightm = heightcm / 100

bmi = weightkg / (heightm * 2)

if bmi < 18.5:

category = "Underweight"

elif bmi < 25:

category = "Normal"

elif bmi < 30:

category = "Overweight"

else:

category = "Obese"

return {

"bmi": round(bmi, 1),

"category": category,

}

def converttemperature(value: float, fromunit: str, tounit: str) -> dict:

"""Convert temperature between units.

Args:

value: Temperature value to convert.

fromunit: Source unit (celsius, fahrenheit, kelvin).

tounit: Target unit (celsius, fahrenheit, kelvin).

Returns:

Dictionary containing the conversion result.

"""

if fromunit == "celsius":

celsius = value

elif fromunit == "fahrenheit":

celsius = (value - 32) 5 / 9

elif fromunit == "kelvin":

celsius = value - 273.15

else:

return {"error": f"Unknown unit '{fromunit}'"}

if tounit == "celsius":

result = celsius

elif tounit == "fahrenheit":

result = celsius 9 / 5 + 32

elif tounit == "kelvin":

result = celsius + 273.15

else:

return {"error": f"Unknown unit '{tounit}'"}

return {"result": round(result, 2), "unit": tounit}

agent = Agent(

model="gemini-2.0-flash",

name="calculatoragent",

description="A calculator agent with various computation functions",

instruction="You are a calculator assistant. Use the available tools to help with calculations.",

tools=[calculatebmi, converttemperature],

)

Built-in Tools

ADK provides several built-in tools that can be used directly:

from google.adk.agents import Agent

from google.adk.tools import googlesearch, codeexecution

agent = Agent(

model="gemini-2.0-flash",

name="researchagent",

description="A research agent that can search the internet for information",

instruction="""You are an AI researcher. Use Google Search to find the latest

information and code execution for data analysis.""",

tools=[googlesearch, codeexecution],

)

Agent as Tool

One of ADK's powerful features is the ability to use other agents as tools:

from google.adk.agents import Agent

translator = Agent(

model="gemini-2.0-flash",

name="translator",

description="Translates text to the requested language",

instruction="You are a translator. Translate the given text to the requested language.",

)

summarizer = Agent(

model="gemini-2.0-flash",

name="summarizer",

description="Summarizes long text into key points",

instruction="You are a summarizer. Create a concise summary of the given text.",

)

agent = Agent(

model="gemini-2.0-flash",

name="contentprocessor",

description="Main agent that processes content",

instruction="""You are a content processor. Use the translator to translate

and the summarizer to summarize text based on user requests.""",

tools=[translator, summarizer],

)

Multi-Agent Systems

ADK provides several orchestration patterns for more complex multi-agent systems.

Sequential Agent

Sequential agent runs sub-agents in order, passing output from one agent to the next:

from google.adk.agents import SequentialAgent, Agent

collectoragent = Agent(

model="gemini-2.0-flash",

name="datacollector",

description="Collects data from given sources",

instruction="Collect and organize data from the given input.",

)

analystagent = Agent(

model="gemini-2.0-flash",

name="dataanalyst",

description="Analyzes collected data",

instruction="Analyze the given data and generate insights.",

)

writeragent = Agent(

model="gemini-2.0-flash",

name="reportwriter",

description="Writes reports based on analysis",

instruction="Write a comprehensive report based on the given analysis.",

)

agent = SequentialAgent(

name="datapipeline",

description="Automated data analysis pipeline",

subagents=[collectoragent, analystagent, writeragent],

)

Parallel Agent

Parallel agent runs multiple sub-agents simultaneously:

from google.adk.agents import ParallelAgent, Agent

sentimentagent = Agent(

model="gemini-2.0-flash",

name="sentimentanalyzer",

description="Analyzes text sentiment",

instruction="Analyze the text sentiment: positive, negative, or neutral.",

)

topicagent = Agent(

model="gemini-2.0-flash",

name="topicextractor",

description="Extracts main topics from text",

instruction="Identify the main topics from the given text.",

)

entityagent = Agent(

model="gemini-2.0-flash",

name="entityextractor",

description="Extracts entities from text",

instruction="Identify people names, organizations, and locations from the text.",

)

agent = ParallelAgent(

name="textanalyzer",

description="Parallel text analysis",

subagents=[sentimentagent, topicagent, entityagent],

)

Loop Agent

Loop agent runs sub-agents repeatedly until a certain condition is met:

from google.adk.agents import LoopAgent, Agent

writeragent = Agent(

model="gemini-2.0-flash",

name="writer",

description="Writes and improves text",

instruction="""Write or improve text based on feedback.

If the text is already good, respond with 'DONE'.""",

)

revieweragent = Agent(

model="gemini-2.0-flash",

name="reviewer",

description="Reviews and provides feedback on text",

instruction="""Review the text and provide improvement feedback.

If the text is already excellent, respond with 'APPROVED'.""",

)

agent = LoopAgent(

name="writingloop",

description="Writing loop with iterative review",

subagents=[writeragent, revieweragent],

maxiterations=3,

)

Session and Memory Management

InMemory Session

For development and testing, use InMemorySessionService:

from google.adk.sessions import InMemorySessionService

sessionservice = InMemorySessionService()

session = await sessionservice.createsession(

appname="myapp",

userid="user1",

)

print(f"Session ID: {session.id}")

Session State

You can store and access state within a session:

from google.adk.agents import Agent

def savepreference(key: str, value: str, toolcontext) -> str:

"""Save a user preference.

Args:

key: Preference name.

value: Preference value.

toolcontext: Tool context (automatically provided by ADK).

Returns:

Confirmation message.

"""

toolcontext.state[key] = value

return f"Preference '{key}' saved with value '{value}'"

def getpreference(key: str, toolcontext) -> str:

"""Retrieve a user preference.

Args:

key: Name of the preference to retrieve.

toolcontext: Tool context (automatically provided by ADK).

Returns:

Preference value or error message.

"""

value = toolcontext.state.get(key)

if value:

return f"Preference '{key}': {value}"

return f"Preference '{key}' not found"

agent = Agent(

model="gemini-2.0-flash",

name="preferenceagent",

description="An agent that remembers user preferences",

instruction="Help users save and retrieve their preferences.",

tools=[savepreference, getpreference],

)

Database Session

For production, use DatabaseSessionService with support for various databases:

from google.adk.sessions import DatabaseSessionService

sessionservice = DatabaseSessionService(

dburl="postgresql://user:pass@localhost:5432/mydb"

)

Callbacks and Guardrails

Before Model Callback

Use callbacks to modify or validate input before sending it to the model:

from google.adk.agents import Agent

from google.genai.types import Content, Part

def contentfilter(callbackcontext, llmrequest):

"""Filter sensitive content before sending to the model."""

usermessage = llmrequest.contents[-1]

if usermessage and usermessage.parts:

text = usermessage.parts[0].text.lower()

blockedwords = ["hack", "exploit", "bypass"]

for word in blockedwords:

if word in text:

return Content(

role="model",

parts=[Part(text="Sorry, I cannot help with that request.")]

)

return None

agent = Agent(

model="gemini-2.0-flash",

name="safeagent",

description="An agent with content filtering",

instruction="Answer user questions safely.",

beforemodelcallback=contentfilter,

)

After Model Callback

Use the after callback to process or validate model output:

def formatresponse(callbackcontext, llmresponse):

"""Format model response before sending to the user."""

if llmresponse.content and llmresponse.content.parts:

for part in llmresponse.content.parts:

if part.text:

part.text = part.text.strip()

if not part.text.endswith((".", "!", "?")):

part.text += "."

return llmresponse

agent = Agent(

model="gemini-2.0-flash",

name="formattedagent",

description="An agent with response formatting",

instruction="Answer user questions.",

aftermodelcallback=formatresponse,

)

Using Models Other Than Gemini

ADK supports other LLM models through LiteLLM integration:

from google.adk.agents import Agent

from google.adk.models.litellm import LiteLlm

claudeagent = Agent(

model=LiteLlm(model="anthropic/claude-sonnet-4-20250514"),

name="claudeagent",

description="An agent using Claude",

instruction="You are an assistant powered by Claude.",

)

gptagent = Agent(

model=LiteLlm(model="openai/gpt-4o"),

name="gptagent",

description="An agent using GPT-4",

instruction="You are an assistant powered by GPT-4.",

)

Make sure the corresponding API keys are configured:

export ANTHROPICAPIKEY="your-anthropic-key"

export OPENAIAPIKEY="your-openai-key"

Example Project: Customer Support Agent

Here is a complete example of a customer support agent using multi-agent patterns:

# customersupport/agent.py

from google.adk.agents import Agent

def findorder(ordernumber: str) -> dict:

"""Find order information by order number.

Args:

ordernumber: Customer order number (format: ORD-XXXX).

Returns:

Dictionary containing order details.

"""

orders = {

"ORD-1001": {

"status": "Shipped",

"carrier": "FedEx",

"tracking": "FX1234567890",

"estimate": "2-3 business days",

},

"ORD-1002": {

"status": "Processing",

"estimate": "Will ship within 24 hours",

},

}

order = orders.get(ordernumber)

if order:

return {"found": True, *order}

return {"found": False, "message": "Order not found"}

def searchproducts(query: str) -> dict:

"""Search products by keyword.

Args:

query: Product search keyword.

Returns:

Dictionary containing matching products.

"""

products = [

{"name": "Laptop Pro X", "price": 1299.99, "stock": 5},

{"name": "Wireless Mouse Z", "price": 29.99, "stock": 50},

{"name": "Mechanical Keyboard K", "price": 89.99, "stock": 20},

]

results = [p for p in products if query.lower() in p["name"].lower()]

return {"products": results, "total": len(results)}

def createticket(subject: str, description: str, priority: str) -> dict:

"""Create a new support ticket.

Args:

subject: Ticket subject.

description: Problem description.

priority: Priority level (low, medium, high).

Returns:

Dictionary containing the created ticket information.

"""

return {

"ticketid": "TKT-2001",

"subject": subject,

"priority": priority,

"status": "Created",

"message": "Ticket created successfully. Our team will contact you within 24 hours.",

}

orderagent = Agent(

model="gemini-2.0-flash",

name="orderagent",

description="Handles questions about orders and shipping",

instruction="""You handle order-related questions.

Use the findorder tool to check order status.

Provide clear and concise information.""",

tools=[findorder],

)

productagent = Agent(

model="gemini-2.0-flash",

name="productagent",

description="Handles questions about products and catalog",

instruction="""You handle product-related questions.

Use the searchproducts tool to find products.

Provide recommendations that match customer needs.""",

tools=[searchproducts],

)

supportagent = Agent(

model="gemini-2.0-flash",

name="supportagent",

description="Handles complaints and creates support tickets",

instruction="""You handle customer complaints.

Use the createticket tool to create support tickets.

Show empathy and provide solutions.""",

tools=[createticket],

)

agent = Agent(

model="gemini-2.0-flash",

name="customersupport",

description="Main customer support agent",

instruction="""You are the main customer support agent.

Route questions to the appropriate sub-agent:

  • Order and shipping questions -> orderagent
  • Product and catalog questions -> productagent
  • Complaints and issues -> supportagent

Greet customers warmly and professionally.""",

tools=[orderagent, productagent, supportagent],

)

Deployment with Vertex AI

To deploy an agent to production using Vertex AI:

from google.adk.cli import deploy

deploy.deploytovertexai(

agentmodule="customersupport",

projectid="your-project-id",

location="us-central1",

displayname="Customer Support Agent",

)

Or using the CLI:

adk deploy cloudrun \

--project=your-project-id \

--region=us-central1 \

--appname=customer-support \

customersupport

Best Practices

1. Clear and Specific Instructions

Write detailed and specific instructions for each agent. The clearer the instructions, the better the agent performance.

# Less effective

instruction = "Answer questions."

More effective

instruction = """You are a senior data analyst.

When receiving data-related questions:

  • Identify the relevant metrics
  • Explain visible trends
  • Provide actionable recommendations
  • Format your answers in easily readable bullet points."""

    2. Document Tools with Docstrings

    ADK uses function docstrings to explain tools to the model. Make sure docstrings are complete with parameter descriptions and return values.

    3. Error Handling in Tools

    Always handle errors inside tool functions and return informative error messages:

    def fetchdata(url: str) -> dict:
    

    """Fetch data from a URL.

    Args:

    url: Data source URL.

    Returns:

    Dictionary containing data or error message.

    """

    try:

    import requests

    response = requests.get(url, timeout=10)

    response.raiseforstatus()

    return {"success": True, "data": response.json()}

    except requests.RequestException as e:

    return {"success": False, "error": str(e)}

    4. Use Session State for Context

    Leverage session state to store conversation context and user preferences, so the agent can provide more personalized responses.

    5. Limit Agent Scope

    Each agent should have specific responsibilities. Use multi-agent patterns to divide complex tasks into smaller, manageable parts.

    6. Testing with ADK Eval

    Use ADK's built-in evaluation framework to test agent performance:

    from google.adk.evaluation import evaluate
    
    

    results = evaluate(

    agent=agent,

    testcases=[

    {

    "input": "What is my BMI? Weight 70 kg, height 175 cm",

    "expectedtoolcalls": ["calculatebmi"],

    "expectedoutputcontains": ["Normal"],

    },

    ],

    )

    print(f"Pass rate: {results.pass_rate}%")

    Conclusion

    Google Agent Development Kit (ADK) provides a robust foundation for building AI agents in Python. With support for multi-agent orchestration, tool management, session handling, and Google Cloud integration, ADK is suitable for building AI applications from prototype to production.

    Key takeaways:

    • Start with a simple agent and add complexity gradually
    • Leverage multi-agent patterns for complex tasks
    • Write clear instructions and docstrings
    • Use session state to maintain context
    • Always test your agents before deploying to production

    For more information, visit the official Google ADK documentation and example projects in its GitHub repository. Happy building!

    Related Articles

    Complete LangGraph Tutorial: Building Complex AI Agents

    Tutorial Lengkap LangGraph: Membangun AI Agents yang Kompleks LangGraph adalah library dari LangChain untuk membangun st...

    Zep Tutorial: Long-Term Memory for AI Agents with a Temporal Knowledge Graph

    Zep: Bikin AI Agent Punya Memori Jangka Panjang dengan Temporal Knowledge Graph Temen-temen, pernah ngobrol sama chatbot...

    Composio Tutorial: Tool Integration Platform for AI Agents

    Tutorial Composio: Platform Integrasi Tool untuk AI Agents Composio adalah platform open-source yang memungkinkan AI age...

    E2B Code Interpreter Tutorial: Complete Guide to Secure Code Execution for AI Applications

    Tutorial Lengkap E2B Code Interpreter: Eksekusi Kode yang Aman untuk Aplikasi AI E2B Code Interpreter adalah platform sa...