System Architecture
Full A2A Orchestration Flow
Each subagent runs as an independent service with its own pod and scaling policy. Communication between services happens exclusively via Redis Streams — SSE is reserved for the last mile to the browser.
Core Protocol
Three Things A2A Defines
Agent Card
Every agent exposes
/.well-known/agent.json — name, capabilities, skills, input/output modes, endpoint. Supervisor fetches this at startup. No hardcoding.Message Contract
Standard envelope for every agent communication — text, files, structured data. Same format regardless of which framework the agent is built on. True interoperability.
Task Lifecycle
Every task has standard states:
submitted → working → completed / failed / cancelled. No ambiguity across teams or frameworks.Orchestration
Step-by-Step Flow
01
Supervisor loads Agent Cards at startup — fetches
/.well-known/agent.json from each agent service and compiles the LangGraph graph dynamically.02
Request arrives — supervisor dispatches independent agents in parallel via LangGraph's
Send() API. Each gets its own input slice of state simultaneously.03
Agents publish lifecycle events to Redis Stream keyed by
stream:{convo_id} — started, working (tokens), done, or failed.04
Supervisor actively listens via its own Redis consumer group — detects when all agents complete, then triggers the Synthesis agent as a DAG join node.
05
Synthesis agent aggregates all results, streams the final synthesised response token by token to Redis, then publishes
all_done.06
Chat Service reads every event via its own consumer group and forwards to the browser's SSE connection.
all_done closes the connection cleanly.Reliability
Fault Tolerance Patterns
Agent fails
Structured error event with
retryable flag published to stream. Supervisor self-corrects via LLM or skips.Agent hangs
Per-agent deadline in supervisor listener. Timeout triggers retry with backoff or graceful skip with partial result.
Pod crashes
Heartbeat events in Redis Stream. Supervisor detects staleness and handles — retry or fallback.
Optional agent down
Proceed with results from available agents. Don't fail the whole request for a non-critical agent.
User disconnects
Redis Stream persists with sliding TTL. Reconnect with
last_event_id replays missed events. TTL expired — serve from DB on login.Decision Guide
Single Agent vs Multi-Agent
| Stay Single Agent | Go Multi-Agent |
|---|---|
| Sequential tasks, no parallelism opportunity | Tasks are genuinely independent and parallelisable |
| Context flows freely between every step | Different agents have different load profiles |
| Small team — more services = more ops burden | Different teams need to own different capabilities |
| Still exploring the problem space | One context window genuinely isn't enough |
| Sub-100ms latency budget — network hops hurt | Need to swap components without touching the rest |
Let's talk architecture
Building agentic systems or want to discuss this design? Reach out.