Google ADK framework: an open source tool for building multi-agent systems

Google ADK framework, a revolutionary tool for AI agent development, quickly builds complex multi-agent systems.
Core content:
1. Overview of ADK framework and its similarities with traditional software development
2. Analysis of ADK core architecture and key component functions
3. Application of ADK tool system and multi-agent system construction examples
The field of artificial intelligence is undergoing an agent revolution. With the continuous improvement of the capabilities of large language models (LLMs), building intelligent agents that can independently plan, make decisions, and execute based on LLMs has become an industry hotspot. However, it is not easy to develop a fully functional, reliable and stable AI agent system, which requires solving many challenges such as tool calling, multi-agent collaboration, and evaluation and testing. Google's recently launched open source project "Agent Development Kit" (ADK for short) was born to solve these problems. It provides a complete set of Python toolkits to help developers quickly build, evaluate, and deploy complex AI agent systems. This article will deeply analyze the architecture design and core features of the ADK framework to help readers quickly get started with this powerful framework.
ps: github address: https://github.com/google/adk-python, currently with 7.8k stars .
1. Framework Overview
ADK (Agent Development Kit) is an open source framework developed by Google, which provides a set of code-first Python tool libraries for AI agent development. Compared with other agent frameworks, the design concept of ADK is to make agent development more like traditional software development, provide flexible modular components, and support various agent architectures from simple tasks to complex workflows.
Although ADK is optimized for the Google Gemini model and Google ecosystem, it adopts a model-independent and deployment-independent design, is compatible with other frameworks, and supports multiple LLM backends, which allows developers to choose the appropriate model and deployment method according to their needs. Considering that most readers cannot use the Gemini model, the following quick start examples will use the Alibaba Tongyi Qianwen large model for example development.
2. Core Architecture
The ADK framework adopts a modular design and is mainly composed of the following key components:
1. Agents
The core of ADK is its proxy system, which mainly includes the following proxy types:
BaseAgent : The base class for all agents, defining the basic properties and behaviors of the agent. LlmAgent : An agent based on a large language model, which is the most commonly used agent type and supports tool calls, input/output control, etc. SequentialAgent : An agent that executes multiple subagents sequentially. ParallelAgent : An agent that executes multiple subagents in parallel. LoopAgent : An agent that executes subagents in a loop. LanggraphAgent : Supports agents built using LangGraph and passing in the graph structure compiled by LangGraph.
The agent system supports hierarchical composition and can build complex multi-agent systems, where a coordinator agent can manage multiple specialized sub-agents. The interaction and control transfer between agents are automatically determined by the model, making the system flexible to cope with various task scenarios.
2. Tools
ADK provides a rich tool system that enables agents to perform a variety of practical tasks:
Function Tools : Tools to convert normal Python functions into proxy callables. Built-in Tools : built-in Google search tool, code execution tool (each agent can only use one built-in tool, and the agent using the built-in tool cannot be a sub-agent of the root agent). Agent Tools : Call other agents as tools to achieve collaboration between agents. OpenApi Tools : Automatically generate tools based on the OpenAPI specification to easily integrate various API services. Retrieval Tools : Tools that support Retrieval Enhanced Generation (RAG) to retrieve information from documents. MCP Tools : Seamless integration with MCP protocol dynamic extension tools.
The tool system adopts a unified interface design, and developers can easily expand custom tools to meet the needs of specific application scenarios.
3. Model Ensemble
ADK supports multiple LLM backends, including:
GoogleLLM : Integrated Google Gemini model family. AnthropicLLM : Supports Anthropic's Claude series models. LiteLLM : Supports multiple models such as OpenAI, Azure OpenAI, etc. through the LiteLLM library.
The model system adopts an abstract interface design to separate the proxy logic from the specific model implementation, ensuring code portability and flexibility.
4. Runtime System (Runners)
The ADK Runner system is responsible for the actual execution of the agent, managing sessions, states, and resources:
InMemoryRunner : In-memory runner for local testing. Runner : Standard runner that supports various service integrations.
The Runner system handles the complete lifecycle of an agent execution, including message processing, event generation, and interaction with various services.
5. Session Management
ADK's session management system is responsible for maintaining the conversation history between the agent and the user:
Session : represents a session between a user and the proxy system. SessionService : Manages the creation, acquisition, and update of sessions.
6. Evaluation
ADK provides powerful evaluation tools to help developers test and improve proxy performance:
AgentEvaluator : Evaluates the performance of an agent on test cases. ResponseEvaluator : Evaluates the quality of agent responses. TrajectoryEvaluator : Evaluates the plausibility of agent decision trajectories.
The evaluation system supports automatic generation of test cases, evaluation of agent performance using LLM, and comparison with human evaluation results, providing comprehensive quality assurance for agent development.
3. Technical Features
1. Code-First Development
ADK adopts a code-first development approach rather than a configuration file-driven approach. This approach has several obvious advantages:
from google.adk.agents import Agent
from google.adk.tools import google_search
root_agent = Agent(
name = "search_assistant" ,
model = "gemini-2.0-flash" ,
instruction= "You are a helpful assistant. Answer user questions using Google searches when needed." ,
description= "An assistant that can search the web." ,
tools=[google_search]
)
Flexibility : You can directly use the full power and ecosystem of Python. Testability : Easy to write unit tests and integration tests. Version control : Code can be managed through tools such as Git. Integration capabilities : Easy to integrate with existing Python code and systems.
2. Multi-agent collaborative system
ADK supports building multi-agent systems to achieve decomposition and collaboration of complex tasks:
from google.adk.agents import LlmAgent
# Define each dedicated agent
greeter = LlmAgent(name= "greeter" , model= "gemini-2.0-flash" , ...)
task_executor = LlmAgent(name= "task_executor" , model= "gemini-2.0-flash" , ...)
# Create a coordinator agent
coordinator = LlmAgent(
name = "Coordinator" ,
model = "gemini-2.0-flash" ,
description = "I coordinate greetings and mission execution." ,
sub_agents=[greeter, task_executor]
)
Through the sub-agent system, ADK can build a hierarchical agent structure, where each agent focuses on a specific task and works together to achieve complex goals. The ADK engine and model will guide the agents to work together to achieve automatic decomposition and execution of tasks.
3. Rich tool ecosystem
ADK provides a rich set of pre-built tools and supports multiple ways to expand tool capabilities:
Custom Functions : Convert ordinary Python functions into proxy tools. OpenAPI integration : Automatically generate tools through OpenAPI specifications. Google ecosystem integration : built-in support for Google Search, Vertex AI and other services. MCP protocol integration : Get tools directly through the MCP protocol.
The tool system adopts a unified interface design to ensure consistency and scalability.
4. Deployment flexibility
ADK supports multiple deployment methods to adapt to different application scenarios:
Local Development : Use the InMemoryRunner to run and test the agent locally. Containerized deployment : Easily package the agent as a container and deploy it to services such as Cloud Run. Serverless deployment : Integrate with serverless platforms like Google Cloud Functions. Vertex AI Integration : Seamless integration with Vertex AI Agent Engine for large-scale deployment.
5. Complete development and evaluation tools
ADK provides comprehensive development and evaluation tools to accelerate the agent development process:
Development UI : A built-in web interface for testing, debugging, and showcasing the agent. Evaluation framework : Automatically evaluate agent performance and support multiple evaluation metrics. Testing tools : support unit testing, integration testing, and end-to-end testing.
4. Quick Start
Project management using Python's UV
1. Initialize the project
uv init adk-demo --python 3.12.0
cd adk-demo
# Create a multi-agent directory
mkdir multi-agent
cd multi-agent
# Create agent.py file
touch-agent.py
# Create __init__.py file
touch-agent.py
# Modify the __init__.py file content to:
from . import agent
2. Install google-adk, litellm, httpx
uv add google-adk litellm httpx
2. The agent.py file introduces the module and uses the Tongyi Qianwen model to build the LLM engine
import asyncio
from typing import Any
from google.adk.agents import LlmAgent
from google.adk.models.lite_llm import LiteLlm
from google.adk.sessions import InMemorySessionService
from google.adk.runners import Runner
from google.genai import types
import httpx
llm = LiteLlm(
model= "openai/qwen-max-2025-01-25" ,
api_key= 'your api key' ,
base_url= 'https://dashscope.aliyuncs.com/compatible-mode/v1' ,
temperature = 0.3 ,
)
3. Build a weather forecast agent
API_BASE = "https://devapi.qweather.com/v7"
API_KEY = " Horse Wind Weather API key "
async def query_weather (url: str) -> dict[str, Any] | None :
"""Make a request to the NWS API with proper error handling."""
headers = {
"X-QW-Api-Key" : API_KEY,
}
async with httpx.AsyncClient() as client:
try :
response = await client.get(url, headers=headers, timeout= 30.0 )
response.raise_for_status()
return response.json()
except Exception:
return None
async def get_forecast (latitude: float, longitude: float) -> str:
"""Get weather forecast for a location.
Args:
latitude: latitude of the location
longitude: Longitude of the location
"""
# First get the forecast grid endpoint
weather_url = f" {API_BASE} /weather/7d?location= {longitude} , {latitude} "
weather_data = await query_weather(weather_url)
if not weather_data or 'code' in weather_data and weather_data[ 'code' ] != '200' :
error_msg = weather_data.get( 'fxLink' , 'Unknown error' ) if weather_data else 'Unable to connect to weather API'
return f"Failed to obtain weather data: {error_msg} "
if 'daily' not in weather_data or not weather_data[ 'daily' ]:
return "The weather data format is incorrect and cannot be parsed"
forecasts = []
for period in weather_data[ 'daily' ]: # Only show next 5 periods
forecast = f"""
{period[ 'fxDate' ]} {period[ 'textDay' ]} :
Temperature: {period[ 'tempMin' ]} ~ {period[ 'tempMax' ]} °C
Wind: {period[ 'windSpeedDay' ]} {period[ 'windDirDay' ]}
"""
forecasts.append(forecast)
return "\n---\n" .join(forecasts)
4. Build an exchange rate query agent
def get_exchange_rate (
currency_from: str = "USD" ,
currency_to: str = "EUR" ,
currency_date: str = "latest" ,
) :
"""Use this to get current exchange rate.
Args:
currency_from: The currency to convert from (eg, "USD").
currency_to: The currency to convert to (eg, "EUR").
currency_date: The date for the exchange rate or "latest". Defaults to "latest".
Returns:
A dictionary containing the exchange rate data, or an error message if the request fails.
"""
try :
response = httpx.get(
f"https://api.frankfurter.app/ {currency_date} " ,
params={ "from" : currency_from, "to" : currency_to},
)
response.raise_for_status()
data = response.json()
if "rates" not in data:
return { "error" : "Invalid API response format." }
return data
except httpx.HTTPError as e:
return { "error" : f"API request failed: {e} " }
except ValueError:
return { "error" : "Invalid JSON response from API." }
SYSTEM_INSTRUCTION = (
"You are a specialized assistant for currency conversions. "
"Your sole purpose is to use the 'get_exchange_rate' tool to answer questions about currency exchange rates. "
"If the user asks about anything other than currency conversion or exchange rates, "
"politely state that you cannot help with that topic and can only assist with currency-related queries. "
"Do not attempt to answer unrelated questions or use tools for other purposes."
"Set response status to input_required if the user needs to provide more information."
"Set response status to error if there is an error while processing the request."
"Set response status to completed if the request is complete."
)
rate_agent = LlmAgent(
model=llm,
name = "rate_agent" ,
instruction=SYSTEM_INSTRUCTION,
description= "Can respond to user when they ask about currency exchange rates." ,
tools=[get_exchange_rate]
)
5. Build a code assistant agent
code_agent = LlmAgent(
model=llm,
name = "code_agent" ,
description= "Can respond to user when they ask about code." ,
instruction= "You can write code and fix bugs." ,
)
6. Building a multi-agent system
root_agent = LlmAgent(
model=llm,
name = "coordinator" ,
instruction= "Route user requests:Use rate_agent to answer questions about currency exchange rates, use code_agent to write code and fix bugs, use weather_agent to get weather forecast for a location." ,
description= "Main agent for routing user requests to the appropriate sub-agents." ,
sub_agents=[rate_agent, code_agent, weather_agent],
)
APP_NAME = "multi_app"
USER_ID = "user_1"
SESSION_ID = "session_001" # Using a fixed ID for simplicity
session_service = InMemorySessionService()
session = session_service.create_session(
app_name=APP_NAME,
user_id=USER_ID,
session_id=SESSION_ID
)
runner = Runner(
agent=root_agent,
app_name=APP_NAME,
session_service=session_service,
)
async def call_agent_async (query: str, runner, user_id, session_id) :
"""Sends a query to the agent and prints the final response."""
print( f"\n>>> User Query: {query} " )
# Prepare the user's message in ADK format
final_response_text = "Agent did not produce a final response." # Default
content = types.Content(role= "user" , parts=[types.Part(text=query)])
# Key Concept: run_async executes the agent logic and yields Events.
# We iterate through events to find the final answer.
async for event in runner.run_async(
user_id=user_id, session_id=session_id, new_message=content
):
# You can uncomment the line below to see *all* events during execution
# print(f" [Event] Author: {event.author}, Type: {type(event).__name__}, Final: {event.is_final_response()}, Content: {event.content}")
# Key Concept: is_final_response() marks the concluding message for the turn.
if event.is_final_response():
if event.content and event.content.parts:
# Assuming text response in the first part
final_response_text = event.content.parts[ 0 ].text
elif (
event.actions and event.actions.escalate
): # Handle potential errors/escalations
final_response_text = (
f"Agent escalated: {event.error_message or 'No specific message.' } "
)
# Add more checks here if needed (eg, specific error codes)
break # Stop processing events once the final response is found
print( f"<<< Agent Response: {final_response_text} " )
async def run_conversation () :
await call_agent_async(
"What's the weather like in Shanghai today?" ,
runner=runner,
user_id=USER_ID,
session_id=SESSION_ID,
)
await call_agent_async(
"What is the current exchange rate of USD to RMB?" , runner=runner, user_id=USER_ID, session_id=SESSION_ID
) # Expecting the tool's error message
await call_agent_async(
"Help me write a python code to calculate 1+1" ,
runner=runner,
user_id=USER_ID,
session_id=SESSION_ID,
)
if __name__ == "__main__" :
asyncio.run(run_conversation())
7. Run the system
# Activate the virtual environment
.\.venv\Scripts\activate
# Run in web ui mode (visit http://localhost:8000/ after startup)
adk web
# Run in cli mode
uv run .\multi_agent\agent.py
8. Run screenshot
Conclusion
The Google ADK framework provides a complete, flexible and powerful tool chain for AI agent development, covering all aspects of the development life cycle from agent definition, tool integration to evaluation and deployment. Whether building a simple conversation assistant or a complex multi-agent collaboration system, ADK can provide the necessary support and convenience.
The ADK framework is developing rapidly. Combined with the popular MCP protocol and Google's own A2A protocol, it makes it particularly easy to develop distributed multi-agent systems. If you are considering developing AI agent applications, ADK is undoubtedly a powerful tool worth trying. Visit the GitHub project (https://github.com/google/adk-python) now to start your agent development journey! Master AI, everyone is the commander of AI, come on.