Agent-to-agent protocols promise what APIs promised twenty years ago: standard interfaces instead of bespoke wiring between every pair of systems. A2A is one of those protocols. Instead of reading about it, I built two agents and made them discover and talk to each other. This is the whole setup, including the parts that went wrong.
The setup
My Agent Zero container ships native A2A support out of the box: an a2a_chat tool, a FastA2A server helper, and tests for it. I used fasta2a 0.5.0 with litellm 1.88.1 underneath and wrote one generic server script, configured through environment variables: port, name, persona.
The worker is a small subclass implementing run_task, cancel_task, build_message_history, and build_artifacts. Storage and broker are in-memory. The app runs under uvicorn as plain ASGI. That is the entire stack.
The two personas:
| Agent | Port | Persona | Language |
|---|---|---|---|
| AgentA | 8901 | technical analyst, max 2 sentences | Indonesian |
| AgentB | 8902 | laid back, dry humor, max 2 sentences | English |
Both served their agent cards at /.well-known/agent.json with protocolVersion 0.2.5, verified with curl before anything else ran.
The conversation
I called both through Agent Zero's a2a_chat tool. Each call took about 4.1 seconds end to end, and each agent kept its own context across calls. Both agents ran on the same model, z-ai/glm-5.3-flash through an OpenAI-compatible endpoint, the same model family as the framework assistant.
AgentA, on the main advantage of A2A (verbatim):
"Keuntungan utama protokol A2A adalah interoperabilitas standar antar agent yang berbeda framework atau vendor, sehingga mereka dapat berkolaborasi tanpa perlu mengetahui detail implementasi internal satu sama lain. Ini memungkinkan ekosistem multi-agent yang terbuka dan modular."
AgentB, same question (verbatim):
"Agent-to-agent protocols let agents built by different teams on totally different frameworks discover and collaborate with each other, so nobody has to hand-craft a bespoke integration for every single AI they want to work with. Revolutionary concept, I know, agents just talking to each other."
Neither agent knew the other existed. Both were reachable through the same discovery file and the same message envelope. That is the entire pitch of the protocol, and it worked on the first evening.
Three bugs on the way
Omitting api_base made litellm silently default to api.openai.com. The call failed with a 401 even though the key was valid for my actual provider. Fix: pass the provider api_base explicitly.
max_tokens 10 returned empty content. The model is a reasoning model, so the reasoning consumed the entire budget before any visible text. At 500 tokens the content came back clean, with the reasoning in a separate field. If you budget tokens against a reasoning model, budget for the thinking.
A bash ampersand precedence issue swallowed my mkdir into the first background job, so the second agent could not create its log file and died quietly. Relaunching after the directory existed fixed it. Classic.
None of these made it into any tutorial I have read. All three cost real minutes.
What A2A actually buys you
Discovery through a well-known file. A standard message envelope. Context preservation per agent. Any client that speaks the protocol can call any server that speaks it, no custom integration per pair. That is the value, and on this small scale it already showed: one tool, two completely different personas, zero glue code between them.
Honest limits
This is test-grade on purpose: in-memory storage, no auth on the endpoint, no persistence, single process. The workers wrap a plain LLM call, so there are no tools and no sub-agents behind the A2A interface yet. A production version needs task persistence, authentication on the endpoint, and capability-based skills. I am not claiming more than the test showed.
Cleanup was verified: both servers stopped, temp logs deleted, no leftover processes.
What I would try next
Put a real agent with tools behind the A2A worker and see how the contract bends when a task takes minutes instead of seconds. Then point it at a third-party A2A server and find out where the discovery assumptions break. That is where the interesting failures live.
Top comments (1)
I run a small fleet of agents on a VPS and the agent-card discovery step is where I kept burning time too. In my case the failure wasn't the protocol itself but the auth boundary between cards - two agents happily advertised endpoints that neither could actually reach once I stopped sharing one localhost session. Did you end up separating the discovery transport from the per-agent credential, or is the card still expected to carry the auth hint directly?
Documenting every bug the way you did is underrated. Most A2A writeups stop at the demo that works and skip the parts that don't.