Skip to main content

Overview

The Agent Development Kit (ADK) is Google’s open-source framework for building AI agents. ADK has built-in support for the A2A protocol, allowing your agents to communicate with remote A2A agents like StackOne’s. Use ADK to build agents that:
  • Consume StackOne’s A2A agents as remote sub-agents
  • Orchestrate multi-agent systems with local and remote agents
  • Access StackOne platform actions without managing tool definitions

Installation

Install ADK with A2A support using pip:
pip install google-adk[a2a]

Quick Start

This example creates an orchestrator agent that delegates HR tasks to a StackOne A2A agent.
import base64
import httpx
from google.adk.agents.llm_agent import Agent
from google.adk.agents.remote_a2a_agent import RemoteA2aAgent

# StackOne A2A configuration
STACKONE_API_KEY = "<stackone_api_key>"
STACKONE_ACCOUNT_ID = "<account_id>"
BASE64_API_KEY = base64.b64encode(f"{STACKONE_API_KEY}:".encode()).decode()

# Create an HTTP client with StackOne authentication headers
http_client = httpx.AsyncClient(
    headers={
        "Authorization": f"Basic {BASE64_API_KEY}",
        "x-account-id": STACKONE_ACCOUNT_ID
    }
)

# Create a remote A2A agent pointing to StackOne
stackone_agent = RemoteA2aAgent(
    name="stackone_hr_agent",
    description="Agent that handles HR operations via StackOne integrations.",
    agent_card="https://a2a.stackone.com/.well-known/agent-card.json",
    httpx_client=http_client
)

# Create the orchestrator agent with StackOne as a sub-agent
root_agent = Agent(
    model="gemini-2.0-flash",
    name="hr_assistant",
    instruction="""
        You are an HR assistant that helps with employee management tasks.
        Delegate HR operations to the stackone_hr_agent.

        When the user asks about employees, time off, or other HR data,
        use the stackone_hr_agent to fetch or update the information.
    """,
    sub_agents=[stackone_agent],
)
See Authentication Guide for details on obtaining your API key and account ID.

Architecture

ADK’s RemoteA2aAgent allows your local agent to delegate tasks to remote A2A agents:

Complete Example

Here’s a complete example with a local tool and a remote StackOne agent:
import base64
import httpx
from google.adk.agents.llm_agent import Agent
from google.adk.agents.remote_a2a_agent import RemoteA2aAgent
from google.genai import types

# Configuration
STACKONE_API_KEY = "<stackone_api_key>"
STACKONE_ACCOUNT_ID = "<account_id>"
BASE64_API_KEY = base64.b64encode(f"{STACKONE_API_KEY}:".encode()).decode()

# Local tool example
def get_current_date() -> str:
    """Get the current date."""
    from datetime import datetime
    return datetime.now().strftime("%Y-%m-%d")

# Create an HTTP client with StackOne authentication headers
http_client = httpx.AsyncClient(
    headers={
        "Authorization": f"Basic {BASE64_API_KEY}",
        "x-account-id": STACKONE_ACCOUNT_ID
    }
)

# Remote StackOne A2A agent
stackone_agent = RemoteA2aAgent(
    name="stackone_hr_agent",
    description="""
        Agent that handles HR operations via StackOne integrations.
        Can list employees, get employee details, manage time off requests,
        and perform other HR operations depending on the connected integration.
    """,
    agent_card="https://a2a.stackone.com/.well-known/agent-card.json",
    httpx_client=http_client
)

# Root orchestrator agent
root_agent = Agent(
    model="gemini-2.0-flash",
    name="hr_assistant",
    instruction="""
        You are an HR assistant that helps with employee management tasks.

        You have access to:
        1. get_current_date - Get today's date
        2. stackone_hr_agent - Delegate HR operations (employees, time off, etc.)

        When users ask about HR data, delegate to stackone_hr_agent.
        Always confirm actions before making changes.
    """,
    global_instruction="You are HRBot, ready to help with HR tasks.",
    sub_agents=[stackone_agent],
    tools=[get_current_date],
    generate_content_config=types.GenerateContentConfig(
        temperature=0.7,
    ),
)

Running the Agent

Use ADK’s built-in web server to interact with your agent:
adk web path/to/your/agent/folder
Then open http://localhost:8000 in your browser to chat with your agent.

Example Interactions

Listing Employees:
User: List all employees
Bot: I'll get that information for you from the HR system.
     [Delegates to stackone_hr_agent]
     Here are the employees:
     1. John Doe - Software Engineer
     2. Jane Smith - Product Manager
     ...
Getting Employee Details:
User: Get details for employee ID emp_123
Bot: [Delegates to stackone_hr_agent]
     Here are the details for emp_123:
     - Name: John Doe
     - Department: Engineering
     - Start Date: 2023-01-15
     ...

Multiple StackOne Accounts

Connect to multiple StackOne accounts by creating separate HTTP clients and RemoteA2aAgent instances for each:
import base64
import httpx
from google.adk.agents.llm_agent import Agent
from google.adk.agents.remote_a2a_agent import RemoteA2aAgent

STACKONE_API_KEY = "<stackone_api_key>"
BASE64_API_KEY = base64.b64encode(f"{STACKONE_API_KEY}:".encode()).decode()

# HTTP client for HiBob account
hibob_http_client = httpx.AsyncClient(
    headers={
        "Authorization": f"Basic {BASE64_API_KEY}",
        "x-account-id": "<hibob_account_id>"
    }
)

# HTTP client for BambooHR account
bamboo_http_client = httpx.AsyncClient(
    headers={
        "Authorization": f"Basic {BASE64_API_KEY}",
        "x-account-id": "<bamboohr_account_id>"
    }
)

# Agent for HiBob integration
hibob_agent = RemoteA2aAgent(
    name="hibob_agent",
    description="Agent for HiBob HR operations",
    agent_card="https://a2a.stackone.com/.well-known/agent-card.json",
    httpx_client=hibob_http_client
)

# Agent for BambooHR integration
bamboo_agent = RemoteA2aAgent(
    name="bamboo_agent",
    description="Agent for BambooHR operations",
    agent_card="https://a2a.stackone.com/.well-known/agent-card.json",
    httpx_client=bamboo_http_client
)

# Orchestrator with both agents
root_agent = Agent(
    model="gemini-2.0-flash",
    name="multi_hr_assistant",
    instruction="""
        You have access to multiple HR systems:
        - hibob_agent: For HiBob HR operations
        - bamboo_agent: For BambooHR operations

        Route requests to the appropriate system based on user context.
    """,
    sub_agents=[hibob_agent, bamboo_agent],
)

Best Practices

Provide detailed descriptions for your RemoteA2aAgent instances. The orchestrator uses these descriptions to decide when to delegate tasks.
# Good: Specific description
stackone_agent = RemoteA2aAgent(
    name="stackone_hr_agent",
    description="Handles employee management: listing employees, getting employee details, updating employee information, and managing time off requests.",
    ...
)

# Bad: Vague description
stackone_agent = RemoteA2aAgent(
    name="stackone_agent",
    description="HR agent",
    ...
)
Include clear delegation instructions in your orchestrator’s system prompt:
root_agent = Agent(
    instruction="""
        When the user asks about:
        - Employee data -> delegate to stackone_hr_agent
        - Time off requests -> delegate to stackone_hr_agent
        - Local operations -> use local tools

        Always confirm before making changes to HR systems.
    """,
    ...
)
ADK handles A2A communication errors, but you should instruct your agent on how to respond:
root_agent = Agent(
    instruction="""
        If the HR agent returns an error or is unavailable:
        1. Apologize to the user
        2. Explain the issue briefly
        3. Suggest trying again later or contacting support
    """,
    ...
)
When your application shuts down, clean up the HTTP client and agent resources:
# Clean up when done
await stackone_agent.cleanup()
await http_client.aclose()

Next Steps

Python SDK

Build custom A2A tools with the Python SDK

JavaScript SDK

Use the A2A JavaScript SDK

Authentication

Learn about authentication and security

Quickstart

Learn A2A basics with cURL