Post 1: The Genesis of an Agent – Your First Steps with ADK
Series: Agentic AI with Google ADK
Introduction to Agentic AI and Google's Agent Development Kit (ADK)
Agentic AI represents a paradigm shift towards AI systems that can perceive their environment, make decisions, and take autonomous actions to achieve specific goals. These systems move beyond simple response generation, incorporating capabilities like planning, tool use, and memory. The development of such intelligent agents is a complex endeavor, which Google's Agent Development Kit (ADK) aims to simplify.
The ADK is an open-source framework designed to empower developers in building, managing, evaluating, and deploying AI-powered agents. It provides a flexible and modular environment for creating both conversational and non-conversational agents capable of handling intricate tasks and workflows. A core philosophy of ADK is to make agent development feel more akin to software development, enabling the creation of robust and scalable agentic architectures. While optimized for Google's Gemini models and the Vertex AI ecosystem, ADK is fundamentally model-agnostic and deployment-agnostic, ensuring broad compatibility.
Key architectural tenets of ADK include:
- Flexible Orchestration: ADK allows for defining workflows through various agent types, including LlmAgent for dynamic, LLM-driven routing and WorkflowAgent (e.g., SequentialAgent, ParallelAgent, LoopAgent) for predictable, structured pipelines.
- Multi-Agent Architecture: The framework is inherently designed for multi-agent systems (MAS), enabling the composition of multiple specialized agents in hierarchical structures for complex coordination and delegation. This modularity promotes scalability and maintainability.
- Rich Tool Ecosystem: Agents can be equipped with diverse capabilities through built-in tools (like Google Search), custom function tools, third-party library integrations (e.g., LangChain, CrewAI), and OpenAPI specifications.
- Deployment Readiness: ADK facilitates the containerization and deployment of agents across various environments, from local machines to scalable cloud solutions like Vertex AI Agent Engine, Cloud Run, or custom Docker infrastructures.
This initial post will guide you through setting up your environment and creating the most basic form of an agent: a greeting agent. This foundational step will introduce core ADK components and concepts.
Setting Up Your ADK Environment
Before constructing our first agent, a proper development environment is necessary. This typically involves Python, installing the ADK package, and configuring access to an LLM, such as Google's Gemini.
Python Environment: It is highly recommended to use a virtual environment to manage project dependencies. Python 3.9+ is generally required.
python -m venv.venv
# Activate the environment (macOS/Linux)
source.venv/bin/activate
# Or (Windows CMD)#.venv\Scripts\activate.bat
Installing Google ADK: The ADK can be installed using pip.
pip install google-adk
For the latest development version, one might install directly from the GitHub repository google/adk-python.
LLM Access Configuration: To use Google's Gemini models, you'll typically need to configure Google Cloud credentials. This involves setting up a Google Cloud project, enabling the Vertex AI API, and authenticating via the Google Cloud CLI.
gcloud auth application-default login
An .env file is often used to store project-specific configurations like GOOGLE_CLOUD_PROJECT and GOOGLE_CLOUD_LOCATION. For example:
#.env
GOOGLE_CLOUD_PROJECT="your-project-id"
GOOGLE_CLOUD_LOCATION="your-region" # e.g., us-central1
GOOGLE_GENAI_USE_VERTEXAI="True"
(Ensure this .env file is in the parent directory from which you run adk web or adk run).
Further details on setup can be found in the ADK Quickstart Guide and the adk-python repository.
Travel Planner v0.1: The Basic Greeting Agent
Our initial Travel Planner agent will perform a single, simple task: greeting the user. This exercise introduces fundamental ADK components: LlmAgent, Runner, and InMemorySessionService.
Core Components:
- LlmAgent: This is the most common type of agent in ADK, leveraging a Large Language Model (LLM) for reasoning, decision-making, and response generation. Its behavior is primarily guided by the instruction parameter.
- Runner: The Runner is responsible for orchestrating the execution of an agent in response to a user query. It manages the event loop and coordinates with services like the SessionService.
- SessionService: This service manages conversational context, including session state and event history. InMemorySessionService is a basic implementation that stores session data in memory, suitable for initial development and testing. It is important to note that data stored with InMemorySessionService is volatile and will be lost when the application restarts.
Code Implementation:
The standard ADK project structure involves creating a directory for your agent (e.g., travel_planner_v0_1), with an agent.py file defining the agent logic and an __init__.py file to make it a discoverable Python package.
from google.adk.agents import LlmAgent
travel_planner_agent_v0_1 = LlmAgent(
name="TravelPlannerAgent_v0_1",
model="gemini-2.0-flash", # Or a suitable available model like "gemini-1.0-pro"
instruction="You are a friendly and enthusiastic travel planner. Greet the user warmly and ask how you can assist them with their travel plans today.",
description="A basic travel planner agent that offers a welcoming greeting to the user."
)
travel_planner_v0_1/agent.py
The instruction parameter is paramount even for this simple agent. It directly shapes the LLM's persona and initial response. A clear, concise instruction is fundamental to achieving the desired agent behavior.
from.agent import travel_planner_agent_v0_1
travel_planner_v0_1/__init__.py
import asyncio
import os
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.genai.types import Content, Part
from dotenv import load_dotenv
# Load environment variables from.env file
load_dotenv()
# Import the agent instance
from travel_planner_v0_1.agent import travel_planner_agent_v0_1
async def main():
# Verify that necessary environment variables are set for Vertex AI
if os.getenv("GOOGLE_GENAI_USE_VERTEXAI") == "True":
if not os.getenv("GOOGLE_CLOUD_PROJECT") or not os.getenv("GOOGLE_CLOUD_LOCATION"):
print("Error: GOOGLE_CLOUD_PROJECT and GOOGLE_CLOUD_LOCATION must be set in.env for Vertex AI.")
return
APP_NAME = "travel_planner_app_v0_1"
USER_ID = "test_user_v0_1"
SESSION_ID = "session_travel_v0_1"
session_service = InMemorySessionService()
# Ensure session is created before runner tries to access it
session_service.create_session(app_name=APP_NAME, user_id=USER_ID, session_id=SESSION_ID)
runner = Runner(
agent=travel_planner_agent_v0_1,
app_name=APP_NAME,
session_service=session_service
)
print(f"--- Running Travel Planner v0.1: Basic Greeting Agent ({travel_planner_agent_v0_1.model}) ---")
user_query = "Hello" # A simple initial interaction
print(f"\n>>> User: {user_query}")
user_content = Content(role='user', parts=[Part(text=user_query)])
final_response_text = "Agent did not respond."
try:
async for event in runner.run_async(user_id=USER_ID, session_id=SESSION_ID, new_message=user_content):
if event.is_final_response() and event.content and event.content.parts:
# Assuming the first part is the main text response
final_response_text = event.content.parts.text
print(f"<<< {travel_planner_agent_v0_1.name}: {final_response_text}")
except Exception as e:
print(f"An error occurred during agent execution: {e}")
# Potentially log more details about the error or specific event types for debugging
# For example, if it's an API error from the LLM provider.
# Clean up the session (optional for InMemorySessionService, but good practice)
session_service.delete_session(app_name=APP_NAME, user_id=USER_ID, session_id=SESSION_ID)
if __name__ == "__main__":
# To run in a Jupyter notebook, you might need to handle the asyncio event loop differently
# For example, using nest_asyncio if running in an already active loop.
# For standalone scripts, asyncio.run(main()) is standard.
asyncio.run(main())
run_planner_v0_1.py (in the parent directory)
Running the Agent:
To run this agent, navigate to the parent directory containing run_planner_v0_1.py and the travel_planner_v0_1 folder, then execute:
python run_planner_v0_1.py
Alternatively, the ADK provides a web UI for interaction (adk web) which can discover and run agents structured this way.
The separation of the Agent definition, the Runner, and the SessionService, even for this elementary agent, is not accidental. It introduces core ADK architectural patterns from the outset. This modularity is fundamental to ADK's design philosophy, which aims to mirror software development best practices. Such a structure facilitates scalability and maintainability as the agent's complexity grows in subsequent iterations, laying a robust foundation for the more advanced features and multi-agent systems we will explore.
Key ADK Terms Introduced
This initial exploration has introduced several key terms fundamental to understanding and working with the Google Agent Development Kit.
Understanding these terms is crucial as they form the building blocks for the more sophisticated agents we will develop in subsequent posts.
Next Steps
In the next post, we will empower our TravelPlannerAgent by equipping it with its first FunctionTool, enabling it to perform actions beyond simple conversation. We will explore how to define custom Python functions as tools and integrate them into our agent's operational capabilities.
Further Reading:
- Google ADK Documentation: https://google.github.io/adk-docs/
- Google ADK Python Repository: https://github.com/google/adk-python
- Google ADK Samples: https://github.com/google/adk-samples