Agent-to-Agent (A2A) Communication
Build two independent agents that talk to each other via the A2A protocol — each owned by a different team, running in its own process, discovered through a standardized AgentCard. Learn how A2A differs from multi-agent orchestration and when each architecture fits.
What you'll learn
- 1Meet the AgentCardIn Lab 3 you built multi-agent orchestration with LangGraph — a supervisor routing queries to specialist agents (researcher, calculator, writer) all inside one Python process. That's great when you control all the agents.
- 2The AgentCard: An Agent's Public ManifestThe AgentCard is A2A's killer feature. It's a JSON document that describes everything another agent or client needs to know to talk to yours:
- 3Build the Metrics Agent (A2A Server)The AgentCard is the *label on the box*. Now we build what's in the box: an agent that actually does work when called. In A2A, that means implementing AgentExecutor:
- 4Client Discovery and Direct CallNow we write a client that:
- 5Support Agent That Delegates via A2AWe have a working DataOps agent (A2A server). Now we build SupportOps — an LLM-powered agent that treats the DataOps agent as a delegated peer, not a tool inside its own process.
- 6Production Patterns: Streaming + Decision FrameworkYou have a working A2A stack. Two last pieces before you ship it.
Prerequisites
- Completed Lab 3 (Multi-Agent Orchestration) — we compare A2A to that pattern
- Completed Lab 7 (MCP) — helpful for context on agent interop
- Comfort with async Python, HTTP, and JSON-RPC concepts
Exam domains covered
Skills & technologies you'll practice
This advanced-level ai/ml lab gives you real-world reps across:
What you'll build in this A2A communication lab
Agent-to-Agent is the emerging standard for cross-team, cross-language, cross-org agent interop — the missing layer once your company has more than one LLM-powered service and the teams that own them speak different programming languages. This lab stands up two independent A2A agents — a DataOps metrics agent owned by SRE, a SupportOps LangChain agent owned by CX — and makes them talk to each other as peers. You finish with a working A2A server, an AgentCard manifest at /.well-known/agent-card.json, a direct JSON-RPC client, an LLM-powered delegator, and a decision framework contrasting A2A against MCP and in-process LangGraph orchestration. The LLM side runs on NVIDIA NIM endpoints we provision.
The substance is the word peer. A2A is not MCP (which standardises how an agent reaches its tools) and it is not multi-agent orchestration inside one LangGraph process (where specialists share state via in-process function calls). A2A is an HTTP + JSON-RPC contract between agents designed, built, deployed, and owned separately. You work through the A2A Python SDK: an AgentCard with AgentSkills and AgentCapabilities from a2a.types, protocol_version='0.2.0', preferred_transport='JSONRPC', APIKeySecurityScheme, and a MetricsExecutor(AgentExecutor) wrapped by DefaultRequestHandler + A2AStarletteApplication on port 9100. You internalise why skills answer 'what' while capabilities answer 'how', why A2A's overhead is wasted inside one process and well-spent the moment you cross a team or language boundary, and why the declarative security_schemes block still needs middleware to enforce anything.
Prerequisites: async Python, HTTP and JSON-RPC basics, and both the multi-agent-orchestration and mcp-tool-servers labs (A2A is deliberately contrasted against both). The hosted environment ships with a2a-sdk, uvicorn, httpx, and the LangChain NIM integration preinstalled, running against our managed NIM proxy — no keys, no GPU allocation. About 40 minutes of focused work. You leave with a minimal AgentCard, a full metrics-agent server, a direct A2A client that round-trips message/send, a LangChain SupportOps agent delegating via A2A, SSE streaming, and the A2A-vs-MCP-vs-orchestration decision framework — everything you need to argue the right pattern for the next edge in your agent architecture.
Frequently asked questions
How is A2A different from a REST API between two services?
AgentCard and call any compliant agent, no per-integration code required. It also models agent-specific concepts — skills, streaming tasks via SSE, push notifications via webhooks, long-running tasks with state — that a flat REST design has to reinvent. The right mental model is 'REST is to A2A what HTTP is to MCP': the transport is familiar, the protocol on top of it is what's new.When should I use LangGraph multi-agent orchestration instead of A2A?
StateGraph — effectively free in both time and tokens. A2A adds an HTTP hop, JSON-RPC serialization, and auth on every call; that overhead is wasted if you're just routing between a researcher, calculator, and writer you all wrote yourself. Reach for A2A the moment you're crossing a boundary: different teams, different languages (Python ↔ TypeScript ↔ Rust), different hosts, different orgs, or a callsite you haven't coordinated with yet.What does security_schemes actually enforce?
security_schemes actually enforce?security_schemes advertises what auth the server expects (APIKeySecurityScheme, HTTPAuthSecurityScheme for bearer tokens, OAuth2SecurityScheme, OpenIdConnectSecurityScheme) and security says which schemes are required for each operation. Enforcement is a server-side middleware you add to the Starlette app, typically a dependency that reads the header named in the scheme (X-Api-Key) and validates it against your key service. The lab keeps the scheme declarative so you focus on the contract; production A2A deployments almost always front the app with an auth dependency plus rate limiting.Why JSON-RPC instead of plain REST for the wire format?
message/send, tasks/get, tasks/cancel, tasks/pushNotificationConfig/set) without having to shoehorn them into HTTP verbs and URL paths, and it gives you a uniform error envelope with numeric codes the SDK can translate into Python exceptions. It also plays nicely with bidirectional streaming over Server-Sent Events — the streaming variants (message/stream) reuse the same request shape. The A2A spec pins the wire format so SDKs in different languages stay interoperable; you as the app author mostly interact with AgentCard, AgentExecutor, and the request handler, not with the raw JSON-RPC frames.What's the difference between a skill and a capability on an AgentCard?
streaming: true, push_notifications: true — the kind of thing a client library reads to decide how to connect. The lab enforces this split by modelling skills as List[AgentSkill] with their own id, name, description, tags, and examples, versus capabilities as a flat AgentCapabilities flags object. Good skill descriptions and worked examples are what let an LLM-powered SupportOps agent pick the right peer agent autonomously.