A2A (Agent-to-Agent) Protocol in Google ADK

November 30, 20254 min read
A2A is an open protocol by Google that allows AI agents to communicate with each other across networks—even if they're built with different frameworks or run on different machines.

Think of it like this: Just as HTTP allows websites to talk to each other, A2A allows AI agents to talk to each other.


Key Concepts

ConceptDescription
A2A ServerExposes your agent so others can call it over the network
RemoteA2aAgentClient proxy that lets your agent call remote agents
Agent CardJSON file describing an agent's capabilities (like a business card)
TaskA unit of work exchanged between agents

When to Use A2A vs Local Sub-Agents

Use A2A When...Use Local Sub-Agents When...
Agents are separate servicesAgents share the same process
Different teams maintain agentsInternal code organization
Cross-language communication neededPerformance-critical operations
Formal API contracts requiredSimple helper functions

How A2A Works - Architecture Diagram


A2A Communication Flow


Simple Example

Step 1: Create the Remote Agent (to be exposed)

# remote_agent.py
from google.adk.agents import Agent
from google.adk.a2a.utils.agent_to_a2a import to_a2a

# Define a simple agent with a tool
def get_weather(city: str) -> str:
    """Get weather for a city."""
    return f"Weather in {city}: Sunny, 25°C"

remote_agent = Agent(
    model='gemini-2.0-flash',
    name='weather_agent',
    description='An agent that provides weather information',
    tools=[get_weather]
)

# Convert to A2A server (auto-generates agent card)
a2a_app = to_a2a(remote_agent, port=8001)

Run it:

uvicorn remote_agent:a2a_app --host localhost --port 8001

Step 2: Create the Consumer Agent

# main_agent.py
from google.adk.agents import Agent
from google.adk.agents.remote_a2a_agent import RemoteA2aAgent

# Create a proxy to the remote weather agent
weather_agent = RemoteA2aAgent(
    name='weather_service',
    agent_card_url='http://localhost:8001/.well-known/agent.json'
)

# Your main agent that uses the remote agent
root_agent = Agent(
    model='gemini-2.0-flash',
    name='assistant',
    description='A helpful assistant',
    sub_agents=[weather_agent]  # Add remote agent as sub-agent
)

Run it:

adk web .

Step 3: Interact

User: What's the weather in Tokyo?

Bot: Let me check the weather for you.
     Weather in Tokyo: Sunny, 25°C

Agent Card Structure

The Agent Card is auto-generated or manually created. It lives at /.well-known/agent.json:

{
  "name": "weather_agent",
  "description": "An agent that provides weather information",
  "url": "http://localhost:8001",
  "version": "1.0.0",
  "protocolVersion": "0.2.6",
  "skills": [
    {
      "id": "get_weather",
      "name": "get_weather",
      "description": "Get weather for a city"
    }
  ],
  "defaultInputModes": ["text/plain"],
  "defaultOutputModes": ["text/plain"]
}

Multi-Agent System Example


Quick Reference

ActionCode
Expose agenta2a_app = to_a2a(agent, port=8001)
Run A2A serveruvicorn module:a2a_app --port 8001
Connect to remoteRemoteA2aAgent(agent_card_url='...')
Check agent cardVisit http://host:port/.well-known/agent.json

Summary

  1. A2A = Protocol for agents to communicate over network
  2. Expose your agent using to_a2a() → creates A2A Server
  3. Consume remote agents using RemoteA2aAgent
  4. Agent Card = JSON describing capabilities (auto-generated or manual)
  5. Works across different frameworks, languages, and machines