AI agent team builds quality courses on any topic
Challenge: Building a course on a new topic — even a short one — typically takes hours of research, fact-checking, and writing. Single-LLM tools rush straight to writing, often producing content that sounds confident but contains gaps or errors. Visitors and students don't always notice, but the credibility damage is real.
Solution: Course Creator is a team of four specialised AI agents that divide the work the way a small editorial team would. A Researcher gathers information, a Judge reviews it for completeness, a Content Builder turns the approved research into structured course material, and an Orchestrator coordinates the handoffs. Each agent runs as its own Cloud Run service and talks to the others over Google's A2A (Agent-to-Agent) protocol.
Most AI multi-agent demos run inside a single Python process — one container, one runtime, all agents sharing memory. This build doesn't. Each of the four agents runs as a separate Cloud Run microservice and communicates over Google's Agent-to-Agent (A2A) protocol — standard JSON-RPC over HTTP, with each agent publishing an "agent card" at /.well-known/agent-card.json describing what it does.
Think of it as the difference between a small startup where everyone shouts across one room, and a real company with departments, formal handoffs, and each team in its own building. Both can produce work, but only the second can scale, swap members, or audit the trail.
| Dimension | Single-Process (CrewAI / LangGraph in one script) | A2A (this build) |
|---|---|---|
| Code layout | One script imports all agents | Each agent is its own deployable service |
| Failure blast radius | One agent bug crashes the pipeline | Other agents keep responding; only the failing one is degraded |
| Scaling | Scale everything together | Scale only the slow agent |
| Upgrades | Swap an agent → rewrite imports across the codebase | Swap an agent → change one URL in the Orchestrator |
| Observability | One log stream, hard to attribute | Per-agent Cloud Run logs + HTTP traces between hops |
| Auth boundary | Trust everything in-process | Service-to-service IAM at every call |
Independent Cloud Run service that uses Google Search via the ADK google_search_tool to gather information on the requested topic. Saves findings to the shared session state for the Judge.
Strict editor that evaluates the Researcher's findings against the original request. Returns a Pydantic-structured response (status: pass | fail) so the Orchestrator can branch deterministically.
Turns approved research into well-structured Markdown course material. No tools, no external calls — pure synthesis from the verified findings.
Front-door agent that wires the others together using ADK's LoopAgent and SequentialAgent. Talks to remote agents via RemoteA2aAgent with authenticated httpx clients.
Custom BaseAgent that reads the Judge's verdict and decides whether to break the research loop (status pass) or run another iteration (status fail), up to a maximum of 3 rounds.
FastAPI web app deployed as a fifth Cloud Run service. Sends the user's topic to the Orchestrator, displays per-agent progress, and renders the final Markdown course.
Every agent runs on Gemini 2.5 Pro through Vertex AI (GOOGLE_GENAI_USE_VERTEXAI=true). No API keys passed around — service accounts handle auth at the Cloud Run boundary.
The Researcher agent uses ADK's built-in google_search_tool to fetch live web context. Search results feed into the LLM's reasoning before it writes its findings.
The Judge returns a JudgeFeedback schema (status + feedback fields) instead of free-form text. This lets the EscalationChecker make a deterministic decision without parsing prose.
The LoopAgent wraps Researcher → Judge → EscalationChecker and re-runs the cycle up to 3 times until the Judge passes the research, then hands off to the Content Builder.
/.well-known/agent-card.json and call each other with JSON-RPC payloadsauthenticated_httpx client signs every request with a Cloud Run identity token, enforced by IAMLoopAgent wraps the research loop; a SequentialAgent wraps the loop and the Content Builder into a single pipelineafter_agent_callback so downstream agents can read them./run_local.sh — Start all 4 agents + the web app as background uvicorn processes (ports 8001–8004 + 8000)./deploy.sh — Deploy each agent + the web app to Cloud Run./init.sh — Initialise the Google Cloud project (enable APIs, create service accounts, set IAM)uv sync — Install/update dependencies from uv.lockEach agent is deployed as a separate Cloud Run service. The Web App is configured with environment variables pointing to each agent's /.well-known/agent-card.json URL so the Orchestrator can discover them.
min-instances=0 on agent services for cost control during low traffic; the cold start adds a few seconds to the first request