When to reach for it
- Agents from different frameworks must interoperate.
- Internal logic must remain private.
- Distributed scaling or vendor-neutral interfaces are required.
/pattern/a2a/
Open standard for interoperable agent-to-agent communication across system and network boundaries. Remote agents can be invoked as tools, inside graphs, or within swarms as if they were local.
In practiceA scheduling agent built on Google ADK invokes a travel-booking agent built on Microsoft Agent Framework via A2A, with neither system requiring custom connector code.
When to reach for it
When it backfires
The tradeoff
Vendor independence and isolation are gained against early-stage tooling and additional protocol overhead.
Picture other agents as services on a shared network. One agent — the client — orchestrates a job; it calls out to remote agents, each callable like a tool, whatever machine, vendor, or framework it runs on.
The catch that makes it a protocol and not just an API: each remote agent is opaque. The caller sees a capability and a result — never the remote's prompts, memory, tools, or reasoning. Agents collaborate as peers without merging into one another's codebase.
Two agents interoperate over a shared protocol.
A2A deliberately reuses the web stack: HTTP, JSON-RPC 2.0, and Server-Sent Events for streaming. A client agent discovers a remote agent through its Agent Card, authenticates, then sends messages that the remote turns into a Task with a defined lifecycle.
discover → authenticate → message/send → stream task & artifacts
The agent that initiates. It discovers remotes, decides what to delegate, sends messages, and merges the artifacts that come back into its own answer.
An A2A server that advertises an Agent Card and fulfils tasks. It is opaque: callers see capabilities and results, never its tools, memory, or reasoning.
JSON metadata served at /.well-known/agent-card.json — the remote's business card: skills, endpoint URL, version, and the security schemes a caller must satisfy.
Advertises who the agent is and what it can do, so a caller can decide whether and how to invoke it — without reading any code.
An ID-based unit of work with a defined lifecycle. The shared object between caller and callee — what was asked, what's in progress, what finished or failed.
Messages carry turns between agents; Artifacts are the results returned against a task — documents, data, images. Internal state never rides along.
Built for the enterprise, and for the long haul. A2A assumes work is asynchronous: tasks can run for minutes or hours, streaming progress over SSE or firing push notifications when they finish. It is modality-independent (text, files, audio, video) and leans on standard HTTPS auth — the same controls you already run for any web API.
# flight_agent.py — expose an agent over A2A
from a2a.types import AgentCard, AgentSkill, AgentCapabilities
from a2a.server.apps import A2AStarletteApplication
from a2a.server.request_handlers import DefaultRequestHandler
card = AgentCard(
name="Flight Booking Agent",
description="Searches and books flights between cities.",
url="https://flights.example.com/a2a",
version="1.0.0",
capabilities=AgentCapabilities(streaming=True),
skills=[AgentSkill(
id="search_flights",
name="Search flights",
description="Find flights between two cities on a date.",
)],
)
handler = DefaultRequestHandler(agent_executor=FlightExecutor())
# served at /.well-known/agent-card.json + the A2A endpoint
app = A2AStarletteApplication(agent_card=card, http_handler=handler)Two open protocols cross the boundary out of any single framework. MCP standardizes how an agent talks to a tool; A2A standardizes how an agent talks to another agent. You will often run both.
A local agent calls a remote agent via A2A for a simple lookup that could be a direct function call. Latency and cost multiply.
Fix · Reserve A2A for cross-boundary or cross-framework calls. Use in-process tools for same-runtime operations.
An internal agent accepts an A2A message from an external agent without verifying the sender's identity or permissions.
Fix · Mutual TLS and signed claims for every A2A interaction. Treat external agents as untrusted by default.
The client blocks on message/send for a long-running job, ignores streaming, and times out before the task completes.
Fix · Handle the Task lifecycle. Stream over SSE, or register a push notification for jobs that outlive the request.
Next pattern
Search patterns, frameworks, and pages.