Skip to content

ADK + A2A Architecture: SequentialAgent and shared artifacts

The system has two layers:

  1. Orchestrator — manages execution flow (DAG, retries, rollback). Does not execute infrastructure tasks.
  2. 7 specialized agents — each with a unique responsibility, coordinated by the Orchestrator via SequentialAgent.

SequentialAgent is a built-in component of Google ADK that executes sub-agents in deterministic order. It doesn’t use an LLM to decide the sequence — execution is fixed and predictable. Pass it the list of agents and ADK handles the complete cycle.

from google.adk.agents import SequentialAgent
orchestrator = SequentialAgent(
name="idp_orchestrator",
sub_agents=[
platform_architect, # 1. Defines stack → platform-config.yaml
infrastructure, # 2. Reads YAML → docker-compose.yml
security, # 3. Scans → security-report.json
cicd, # 4. Generates → cicd/ + Jenkinsfile
observability, # 5. Configures → grafana-dashboards/
devex, # 6. Generates CLI → cli-tool/idp
web_portal # 7. Builds → portal/
]
)

The Orchestrator builds a dependency graph before executing. Each agent depends on the outputs of the previous ones:

Platform Architect (~12s)
└── Infrastructure (~18s)
├── Security (~14s)
│ └── CI/CD (~16s)
│ └── Observability (~19s)
│ └── DevEx (~15s)
│ └── Web Portal (~45s)
└── [Web Portal also reads docker-compose]

Total time: ~4.5 minutes. The Web Portal is the most expensive agent because it reads the complete configuration from all previous agents to generate the portal.

MAX_RETRIES = 3 # Attempts before declaring failure
TIMEOUT_PER_AGENT = 300 # 5 minutes maximum per agent
BACKOFF_MULTIPLIER = 2 # Exponential backoff between retries
┌─────────────────────────────────────────────────────┐
│ 1. USER INPUT │
│ "Build IDP for Python FastAPI apps" │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ 2. ORCHESTRATOR │
│ — Parses the task │
│ — Builds the execution DAG │
│ — Initializes global context │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ 3. PLATFORM ARCHITECT (~12s) │
│ Input: task description │
│ Output: platform-config.yaml │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ 4. INFRASTRUCTURE (~18s) │
│ Input: platform-config.yaml │
│ Output: docker-compose/app-stack.yml │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ 5. SECURITY (~14s) │
│ Input: docker-compose.yml + Dockerfiles │
│ Output: security-report.json │
│ Decision: APPROVED / BLOCKED │
└─────────────────────────────────────────────────────┘
↓ (only if APPROVED)
┌─────────────────────────────────────────────────────┐
│ 6. CI/CD (~16s) │
│ Input: platform-config.yaml + security OK │
│ Output: cicd/ + Jenkinsfile │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ 7. OBSERVABILITY (~19s) │
│ Input: platform-config.yaml │
│ Output: prometheus.yml + grafana-dashboards/ │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ 8. DEVEX (~15s) │
│ Input: all previous outputs │
│ Output: cli-tool/idp │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ 9. WEB PORTAL (~45s) │
│ Input: complete IDP configuration │
│ Output: portal/ (FastAPI + HTMX) │
└─────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ 10. ORCHESTRATOR — FINAL SUMMARY │
│ Output: orchestration-report.json │
│ Total time: ~4.5 min | 21 files | 7/7 │
└─────────────────────────────────────────────────────┘

Before declaring a failure, the Orchestrator retries automatically with increasing wait time between attempts:

for attempt in range(MAX_RETRIES): # 3 attempts
try:
result = await agent.execute()
break
except TimeoutError:
wait_time = BACKOFF_MULTIPLIER ** attempt # 1s → 2s → 4s
await asyncio.sleep(wait_time)
except AgentError as e:
if e.severity == "critical":
raise # Critical failure → immediate rollback
else:
continue # Non-critical failure → retry

If an agent fails critically after 3 attempts:

  1. The Orchestrator detects the failure
  2. Invokes rollback in reverse order for completed agents
  3. Cleans up generated files
  4. Saves the failure state in orchestration-report.json

The rollback preserves the ability to restart from the failed agent without losing the work of the previous ones.

Each agent writes an execution report that the Orchestrator reads to build the final orchestration-report.json:

{
"agent_id": "infrastructure-agent",
"timestamp": "2026-01-29T10:30:15Z",
"status": "success",
"result": {
"files_generated": [
"docker-compose/app-stack.yml"
],
"decisions": {
"database": "PostgreSQL 15 — robust and compatible with FastAPI",
"cache": "Redis Alpine — minimal image for local scope"
}
}
}

See in detail: how A2A works with shared artifacts