Repository navigation
A2A 2 · The two-agent handshake, end to end #20
akash-coded
started this conversation in
Exercises
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Exercise 2: The Two-Agent Handshake
Type: Comprehensive | Time: 50 to 60 minutes | Work: solo or pairs
By the end you will have built one peer and consumed it four ways, from fully manual to fully autonomous. This is the core A2A muscle.
Learning goals
Setup
us.anthropic.claude-haiku-4-5-20251001-v1:0(inference profile, not bare model id)us-east-1, AWS account12345678901201_A2A_with_Strands.ipynb, Parts A and BReminder: the bare model id
anthropic.claude-haiku-...throwsValidationException. Keep theus.prefix.The four ways to talk to a peer
flowchart TD P["Baggage Agent A2A server"] A["A2AAgent sync call"] -->|you decide| P B["A2AAgent stream_async"] -->|you decide, live events| P C["A2AClientToolProvider 3 discovery tools"] -->|orchestrator decides| P D["A2AAgent wrapped in @tool"] -->|orchestrator decides, clean interface| PSame peer. Control moves from you to the orchestrator as you go down the list.
Task ladder
Everyone starts at Tier C. Climb as far as your time and confidence allow. Higher tiers are open to all, never locked.
Tier C: Build it and call it (Base)
Build a Baggage Agent A2A server with two skills:
track_bagtrack_bag(tag_id: str)file_claimfile_claim(pnr: str)Use mock return values. Decorate both with
@toolor your card ships empty.Then, as a client, call it once synchronously to ask about bag tag
BAG7781and read the answer.Requirements
baggage_server.pyboots on127.0.0.1:9000A2AAgentcall and printsresult.messageBounded done: the card shows both baggage skills, and a single synchronous call returns a sensible plain-language answer about the bag. You did not stream and you did not use an orchestrator yet.
Tier B: Stream it, then let it discover (Stretch)
Add two more consumption styles against the same running server.
Streaming. Call the peer with
stream_asyncand print the final answer. The shape, confirmed from the SDK:The final answer lives in the last event under
event["result"].message. It is not underevent["data"]. Branch onevent.get("type")first.Tool provider. Build an orchestrator agent, give it
A2AClientToolProvider(known_agent_urls=[...]).tools, and ask it in plain English to discover the agent and check bagBAG7781. Let the model decide when to calla2a_discover_agentanda2a_send_message.Bounded done: streaming prints the same answer as the sync call, sourced from the last event. The tool-provider orchestrator discovers the peer on its own and reports the bag status without you naming any tool by hand. You can say in one line how "you decide" (sync/stream) differs from "the model decides" (tool provider).
Tier A: Two peers, one mixed request (Advanced)
Wrap the baggage peer as a single clean
@tool(give theA2AAgentaname). Then bring in the Flight Status agent from Exercise 1 as a second peer, also wrapped as a tool.Build a TravelMind orchestrator holding both peer-tools. Hand it one mixed request:
TravelMind must call both peers and compose one warm reply.
Production angle (required at Tier A): make the orchestrator degrade gracefully when a peer is unreachable. Stop one peer, send the request again, and confirm TravelMind still answers about the reachable peer instead of crashing.
sequenceDiagram participant U as Passenger participant T as TravelMind participant F as Flight Status peer participant B as Baggage peer U->>T: MA417 delayed + bag BAG7781 missing (JX48Q2) T->>F: check flight status / disruption F-->>T: delayed, weather T->>B: track bag + file claim B-->>T: in transit, claim filed, 24h SLA T-->>U: one reply covering flight and bagBounded done: one passenger request fans out to two peers and returns a single coherent answer. With one peer stopped, the reply still helps the passenger on the other concern and names what it could not reach. No stack trace reaches the user.
Bonus (any finisher)
Pick one:
file_claimreturn a structured Artifact (a claim record) and make TravelMind quote the claim id back to the passenger.LLM-integrated task (required, pass or fail)
An agent's
descriptionandsystem_promptare how other agents find and trust it. Vague text breaks discovery.description(the one in the Agent Card) and itssystem_prompt.You pass this task only if all four parts are present: prompt, raw output, two named weaknesses, corrected version.
Reflection (4 lines)
@toolwrapper gives it one named tool. When is each the right call?Skeptic's corner
"This is just an HTTP call wrapped in ceremony. Why not let TravelMind import the baggage function directly?" Because the day the baggage team rewrites their service in Go, redeploys it behind their own scaling, or a second airline reuses it, the import breaks and the A2A contract does not. You are paying a small tax now to avoid a rewrite later. If baggage will never leave your repo, the skeptic is right and you should keep it in-process. That judgment is exactly Exercise 3.
Answer Key
Solution shape
Server (Tier C):
Sync client (Tier C):
Streaming (Tier B):
Tool provider (Tier B):
Agent-as-tool wrapper and graceful degradation (Tier A):
The
try/exceptreturning a string is the simplest correct degrade pattern. The orchestrator reads the apology string as a normal tool result and works around it.Three common errors
@tool. The card is the tell.event["data"](from stale tutorials), never hit it, and printNone. Point them to the printed event keys: the payload isevent["event"], the final answer isevent["result"], emitted last.baggage(...)with no guard. The unhandled exception aborts the whole orchestrator turn. The fix is catching it inside the tool so the model sees a graceful string.Five discussion prompts
stream_asyncyield raw protocol events instead of text deltas like a normal agent?track_bagskill, how does the orchestrator choose?Five viva questions (easy to hard)
Timing
Tier C ~25 min, Tier B ~15 min, Tier A ~15 min.
All reactions