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
| Concept | Description |
|---|---|
| A2A Server | Exposes your agent so others can call it over the network |
| RemoteA2aAgent | Client proxy that lets your agent call remote agents |
| Agent Card | JSON file describing an agent's capabilities (like a business card) |
| Task | A 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 services | Agents share the same process |
| Different teams maintain agents | Internal code organization |
| Cross-language communication needed | Performance-critical operations |
| Formal API contracts required | Simple 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
| Action | Code |
|---|---|
| Expose agent | a2a_app = to_a2a(agent, port=8001) |
| Run A2A server | uvicorn module:a2a_app --port 8001 |
| Connect to remote | RemoteA2aAgent(agent_card_url='...') |
| Check agent card | Visit http://host:port/.well-known/agent.json |
Summary
- A2A = Protocol for agents to communicate over network
- Expose your agent using
to_a2a()→ creates A2A Server - Consume remote agents using
RemoteA2aAgent - Agent Card = JSON describing capabilities (auto-generated or manual)
- Works across different frameworks, languages, and machines