Why architecture matters here
A single-team monolith can change an internal interface and redeploy every caller in the same commit. A multi-agent system cannot: agents are built by different teams (or different organizations), deployed on their own schedules, and discovered dynamically. There is no global moment when everyone upgrades. That means at any instant the network contains agents speaking several versions of the protocol at once, and correctness must hold across that mix. Versioning matters because it is the only thing standing between 'we shipped an improvement' and 'we caused a cascade of failures in agents we did not know existed'.
Three concrete risks make it non-negotiable. Silent breakage: an agent that renames or repurposes a field, or tightens a validation, breaks consumers who parse the old shape — and because agents are loosely coupled, the breakage surfaces as mysterious downstream task failures, not a compile error. Coordination deadlock: without a compatibility window, every change requires all peers to upgrade simultaneously, which at scale is impossible, so the protocol ossifies and stops improving. Capability mismatch: a caller assumes a feature the callee does not support (or vice versa) and the interaction fails at runtime rather than being caught during negotiation. Versioning converts all three from production incidents into negotiated, observable decisions.
The payoff is independent evolvability: any agent can add capabilities and retire old ones on its own schedule, as long as it advertises what it speaks, negotiates honestly, and honors a compatibility window while old peers catch up. That property — change without a flag day — is what makes a federated agent ecosystem viable at all, and it is entirely a consequence of getting versioning right.
A useful way to internalize the stakes is to think about the blast radius of a bad change. In a single service a breaking change fails loudly in your own test suite or the one downstream team's integration tests. In an agent network the same change can propagate silently through chains of delegation: agent A calls B, which calls C, and a contract break at C surfaces as an inexplicable failure two hops away in a workflow the C team has never seen. Debugging that requires reconstructing which versions each hop negotiated, which is only possible if versioning is observable in the first place. This is why the discipline is not just 'add a version number' but a whole apparatus — negotiation, compatibility windows, telemetry, contract tests — designed to keep changes contained and their effects traceable across a graph of agents no single team fully controls.
The architecture: every piece explained
The Agent Card is the anchor. Each agent publishes a card declaring the protocol version(s) it supports and its capability set — task types, streaming support, auth schemes, optional extensions. Because the card is discoverable, a caller can learn what a callee speaks before committing to an interaction. Version negotiation is the handshake: given both agents' advertised versions, they select the highest version both support (the common maximum), so peers automatically use the best mutually understood protocol and gracefully fall back when one side is older.
The SemVer contract gives change a grammar. Following semantic versioning — major.minor.patch — a patch is a bug fix with no contract change, a minor bump adds capabilities in a backward-compatible way (new optional fields, new task types), and a major bump signals a breaking change that older peers cannot assume. This lets a consumer reason about safety from the version number alone: same major, higher minor is safe to talk to; a major jump requires the consumer to opt in. Schema evolution rules enforce the minor-bump promise: fields are added, never removed or repurposed; identifiers are never reused for new meanings; unknown fields are ignored rather than rejected, so a newer producer's extra fields do not break an older consumer.
The compatibility window is the policy that agents support version N and at least N-1 (or a defined range), giving peers time to migrate. The deprecation lifecycle governs removal: a capability is first announced as deprecated, then enters a sunset period during which it still works but warns, and only then is removed — so no peer is surprised. Fallback and feature flags provide graceful degradation: when a callee lacks a capability, the caller either downgrades to an older behavior or disables the feature rather than erroring. A version registry tracks which versions are actually in use across the fleet, turning the compatibility window from a guess into data.
It is worth separating two things that beginners often conflate: versioning the protocol and versioning a specific agent's capabilities. The protocol version governs the wire grammar and core method semantics — how a task is structured, how messages are framed, how errors are reported — and is shared across all agents that speak A2A. Capabilities are per-agent and finer-grained: whether this particular agent can stream, which task types it accepts, what auth schemes it offers, what optional extensions it implements. Two agents can speak the same protocol version yet differ entirely in capabilities, and negotiation handles both axes — it settles on a common protocol version and then intersects capability sets to find what this pair can actually do together. Keeping the two axes distinct is what lets the ecosystem evolve the shared protocol slowly and conservatively while individual agents add and retire features quickly, without the two kinds of change interfering.
End-to-end flow
Trace two agents meeting for the first time. Agent A wants to delegate a task to Agent B. A first fetches B's Agent Card (from a registry or directly) and reads that B supports protocol versions up to 1.4 and a capability set including streaming responses and a particular task type. A itself supports up to 1.3. During negotiation they select version 1.3 — the highest both understand — and A restricts its request to capabilities available at that version. Because 1.3 and 1.4 share a major version, additive schema evolution guarantees that B, running newer code, can still parse A's 1.3 request; B simply does not use the fields or features A never sends.
A now sends the task using the negotiated version. B validates it against the 1.3 contract, ignoring any fields it does not recognize (there are none here, but the rule protects the reverse case), and executes. Suppose the task response would normally include a new field introduced in 1.4; because the interaction is pinned to 1.3, B omits it, and A — which would not know what to do with it anyway — is unaffected. If A had instead advertised a capability B lacks, negotiation would have surfaced the mismatch up front: A would fall back to a supported behavior or decline the interaction cleanly, rather than sending a request B fails on at runtime.
Now play the change forward. B's team wants to remove a legacy task option. They do not simply delete it: they mark it deprecated in a minor release, keep it working through a sunset window while telemetry shows how many peers still use it, notify or wait out those peers, and only in a subsequent major release remove it — bumping the major version so any peer that depended on it negotiates down to an older major or is explicitly told the capability is gone. Throughout, the version registry shows which versions are live, so B can retire old support only when real traffic on it has drained. No agent is broken by surprise; every removal is a scheduled, observable event.
Now consider the harder case: a genuinely breaking change that cannot be made additive, such as restructuring how a task's result is returned. B introduces protocol major version 2 alongside its existing major version 1, advertising both in its Agent Card during an overlap period. New callers that understand version 2 negotiate up to it and get the new behavior; existing version-1 callers keep negotiating version 1 and are untouched. B runs both code paths in parallel — this dual-support window is the cost of a breaking change, and it is why breaking changes are batched and rare rather than continuous. Telemetry tracks how much traffic still negotiates version 1; when it drains below a threshold and the remaining laggards have been notified, B announces version 1's deprecation, sunsets it, and finally drops it, leaving version 2 as the floor. The whole maneuver — advertise both, let peers migrate at their own pace, retire the old major only when telemetry says it is safe — is the concrete shape of 'evolve without a flag day', and it works precisely because negotiation and the registry make every step observable rather than a leap of faith.