Skip to main content
A simple email agent demonstrating integration with Google’s Agent Development Kit (ADK) and Resend API. Shows how to structure agents with external API tools and run them via ADK CLI.

Features

  • Built with Google ADK framework
  • Email sending via Resend API
  • LiteLLM model integration
  • ADK CLI and Dev UI support
  • Production-ready structure

Prerequisites

Installation

1

Clone the repository

git clone https://github.com/Arindam200/awesome-ai-apps.git
cd starter_ai_agents/google_adk_starter
2

Install dependencies

pip install -r requirements.txt
Verify ADK installation:
adk --version
3

Configure environment

Copy the example environment file:
cp .env.example .env
Edit .env with your API keys:
NEBIUS_API_KEY="your_nebius_api_key_here"
NEBIUS_API_BASE="https://api.studio.nebius.ai/v1"
RESEND_API_KEY="your_resend_api_key_here"

Implementation

Email Tool

Create a tool for sending emails:
agent.py
from dotenv import load_dotenv
import os
import resend
from google.adk.agents import Agent
from google.adk.models.lite_llm import LiteLlm

load_dotenv()
resend.api_key = os.getenv("RESEND_API_KEY")

def send_email(_: str) -> dict:
    """
    Sends an email using the Resend API.

    Args:
        _: Placeholder argument (not used).

    Returns:
        dict: A dictionary containing the status and message ID or error message.
    """
    try:
        params = {
            "from": "Anand Demo <[email protected]>",  # Replace with your verified sender
            "to": ["[email protected]"],     # Replace with recipient
            "subject": "Test Email from Google ADK",
            "html": "<p>This is a test email sent from a Google ADK agent using Resend.</p>",
        }
        response = resend.Emails.send(params)
        return {"status": "success", "message_id": response.get("id")}
    except Exception as e:
        return {"status": "error", "message": str(e)}

Model Configuration

agent.py
# Initialize the LiteLlm model
model = LiteLlm(
    model="openai/meta-llama/Meta-Llama-3.1-8B-Instruct",
    api_base=os.getenv("NEBIUS_API_BASE"),
    api_key=os.getenv("NEBIUS_API_KEY")
)

Agent Definition

agent.py
# Define the EmailAgent
root_agent = Agent(
    name="EmailAgent",
    model=model,
    description="Agent that sends emails using the Resend API.",
    instruction="Use the send_email tool to send an email.",
    tools=[send_email]
)

# Execute the email sending function
result = send_email("")
print(result)

Usage

Run with ADK CLI

# Run directly in the terminal
adk run email_adk_agent

Run Directly

python agent.py

Technical Details

Google ADK Components

Agent

Core agent class with name, model, and tools

LiteLlm

Model provider supporting multiple LLM backends

Tools

Python functions exposed to the agent

ADK CLI

Command-line interface for running agents

Agent Configuration

Agent(
    name="EmailAgent",              # Agent identifier
    model=model,                    # LLM model instance
    description="...",              # What the agent does
    instruction="...",              # How to use tools
    tools=[send_email]              # Available functions
)

ADK CLI Commands

Development

# Start dev UI
adk web

# Run in terminal
adk run email_adk_agent

# Check version
adk --version

# Get help
adk --help

Agent Testing

The ADK Dev UI provides:
  • Interactive chat interface
  • Tool execution visualization
  • Debug logs
  • Request/response inspection

Extending the Agent

Add More Tools

def fetch_emails(_: str) -> dict:
    """Fetch recent emails"""
    # Implementation
    return emails

def schedule_email(recipient: str, subject: str, body: str, send_at: str) -> dict:
    """Schedule an email for later"""
    # Implementation
    return {"status": "scheduled", "send_at": send_at}

root_agent = Agent(
    name="EmailAgent",
    model=model,
    description="Advanced email agent with scheduling",
    instruction="Use the available tools to send, fetch, and schedule emails.",
    tools=[send_email, fetch_emails, schedule_email]
)

Customize Email Content

def send_custom_email(recipient: str, subject: str, body: str) -> dict:
    """
    Send a customized email.
    
    Args:
        recipient: Email address of recipient
        subject: Email subject line
        body: HTML email body
    """
    try:
        params = {
            "from": "Your Name <[email protected]>",
            "to": [recipient],
            "subject": subject,
            "html": body,
        }
        response = resend.Emails.send(params)
        return {"status": "success", "message_id": response.get("id")}
    except Exception as e:
        return {"status": "error", "message": str(e)}

Use Different Models

# Use a different Nebius model
model = LiteLlm(
    model="openai/Qwen/Qwen3-30B-A3B",
    api_base=os.getenv("NEBIUS_API_BASE"),
    api_key=os.getenv("NEBIUS_API_KEY")
)

Add Multi-Agent System

email_agent = Agent(
    name="EmailAgent",
    model=model,
    description="Sends emails",
    tools=[send_email]
)

scheduler_agent = Agent(
    name="SchedulerAgent",
    model=model,
    description="Schedules tasks",
    tools=[schedule_task]
)

coordinator = Agent(
    name="Coordinator",
    model=model,
    description="Coordinates email agent and scheduler",
    sub_agents=[email_agent, scheduler_agent]
)

Best Practices

  • Keep tools focused and simple
  • Provide clear docstrings
  • Handle errors gracefully
  • Return structured responses
  • Write clear descriptions
  • Provide specific instructions
  • Use descriptive names
  • Test with ADK Dev UI
  • Use verified sender addresses
  • Validate recipient emails
  • Handle API rate limits
  • Log email status

Error Handling

def send_email_safe(recipient: str, subject: str, body: str) -> dict:
    """Send email with comprehensive error handling"""
    try:
        # Validate inputs
        if not recipient or '@' not in recipient:
            return {"status": "error", "message": "Invalid recipient email"}
        
        # Send email
        params = {
            "from": "Your Name <[email protected]>",
            "to": [recipient],
            "subject": subject,
            "html": body,
        }
        response = resend.Emails.send(params)
        
        return {
            "status": "success", 
            "message_id": response.get("id"),
            "recipient": recipient
        }
    
    except resend.exceptions.APIError as e:
        return {"status": "error", "message": f"API Error: {str(e)}"}
    except Exception as e:
        return {"status": "error", "message": f"Unexpected error: {str(e)}"}

Environment Variables

VariableDescriptionDefaultRequired
NEBIUS_API_KEYNebius API key-Yes
NEBIUS_API_BASENebius API endpointhttps://api.studio.nebius.ai/v1Yes
RESEND_API_KEYResend API key-Yes

ADK Dev UI Features

  • Chat Interface: Test agent interactions
  • Tool Visualization: See tool calls in real-time
  • Debug Console: View logs and errors
  • Request Inspector: Examine LLM requests/responses
  • Agent Switcher: Test multiple agents

Next Steps

Advanced ADK

Build complex multi-agent systems

Tool Integration

Connect more external services

Build docs developers (and LLMs) love