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