Rush Hour: Gemini Enterprise Agent Platform workshop
Module 0

The Mission & Setup

Understand the crisis, meet your tools, download the data,
and see the empty platform you'll fill by the end of the workshop.

M1 · BUILD
M2 · SCALE
M3 · GOVERN
M4 · OPTIMIZE
M5 · ENGAGE
Objective

Everyone is in Antigravity (AGY) — the coding agent you'll prompt throughout this workshop — with a working cockpit (your local tools — AGY plus agents-cli), has the data, understands the crisis, and has seen the empty platform they will fill by 2:00.

The Crisis Briefing

🚨 The Scenario

It's peak evening departure time at London St Pancras International. A signal failure at the station throat — the point where all tracks converge before entering the platforms — has brought cross-border services to a halt.

Eurostar services to Paris, Brussels, Amsterdam, and Cologne are either cancelled or running with severe delays. Hundreds of travelers are stranded. One question, asked a thousand ways:

"Will I still make it — and how?"

🤖 Why a Chatbot Fails

A general-purpose LLM knows railway policy and can recite timetable information from its training data. But it cannot:

  • Query the current schedule for a specific station and time window
  • Read a live disruption feed to know which services are actually affected
  • Join those two datasets on trip ID to determine the real situation
  • Compute an alternative route through a multi-station network

Without tools, the LLM will confidently hallucinate a train that was cancelled an hour ago.

🧠 Why an Agent Succeeds

An agent is an LLM with deterministic tools. Your agent will have three:

Tool 1 Schedule Lookup "what should happen" Tool 2 Disruption Check "what is happening" Reconcile JOIN on trip_id / stop_id Tool 3 Reroute Compute alternative path Verified Answer "Take the 14:05 via Brussels, arr. 17:32"

The agent reconciles Tool 1 (schedule) with Tool 2 (disruption) by joining on trip_id / stop_id, then invokes Tool 3 to find an alternative route. The result is a deterministic, verifiable answer — not a guess.

🎯 The Deliverable

By the end of the workshop, a non-technical ops manager opens Gemini Enterprise and types:

gemini enterprise"Trains out of St Pancras are disrupted — what do I tell travelers heading to Paris?"

And gets a concrete, verified answer with a specific reroute, departure time, and estimated arrival. The agent you build in M1 will be deployed (M2), governed (M3), optimized (M4), and published (M5) to make this work.

🌐 The Network

The dataset covers 17 stations across 5 countries (UK, France, Belgium, Netherlands, Germany) on the Eurostar / cross-border rail network.

UNITED KINGDOM St Pancras ! FRANCE Lille Europe Paris Gare du Nord Calais BELGIUM Brussels Midi NETHERLANDS Amsterdam / Rotterdam GERMANY Cologne / Frankfurt Disrupted Available for reroute

The Journey — Build → Scale → Govern → Optimize → Engage

🗓️ Timeline

TimeModuleHeadlineFormat
0:00–0:12M0 SetupCockpit check, data, crisis brief, see the empty platformGuided
0:12–0:37M1 BUILDVibe-build the transit agent + tools; run locallyHands-on
0:37–1:07M2 SCALEDeploy to Agent Runtime; Sessions, Memory Bank, sandboxHands-on
1:07–1:22M3 GOVERNRegistry, Identity, Gateway, Model ArmorGuided demo
1:22–1:40M4 OPTIMIZEQuality Flywheel: simulate, score, cluster, optimizeHands-on
1:40–1:50M5 ENGAGEPublish to Gemini Enterprise; talk to your agentGuided

Short on time? Skip M3 and M4 to run the workshop in about an hour. The core path M0 → M1 → M2 → M5 (~1 hour) still builds, deploys, and publishes a working agent — M5 only needs the M2 deploy. M3 (Govern) and M4 (Optimize) are optional deep-dives you can add when time allows (the full journey is ~1h50m).

🏗️ What You'll Build — Platform Artifacts

BUILD ADK Agent 3 Tools System Instruction Local Playground gemini-3.5-flash SCALE Agent Runtime Sessions Memory Bank Code Exec Sandbox Serverless 0→∞ GOVERN Agent Registry Agent Identity (IAM) Agent Gateway Model Armor Attack-surface control OPTIMIZE User Simulation Env Simulation Multi-turn Autoraters Loss Clusters Quality Flywheel ENGAGE Gemini Enterprise Chat UI

Prerequisites & environment setup

You run this whole workshop from Cloud Shell — a browser-based terminal with gcloud preinstalled and already signed in — and drive every step through the Antigravity CLI (agy), a terminal coding agent. Do this one-time setup before Step 1.

Using the Qwiklabs lab? Skip this section.

In the provided Qwiklabs lab the environment — project, gcloud, and a ready agy — is already set up for you. Jump to Setup in 5 Steps and just pin your project. The steps below are for running on your own Google Cloud project in Cloud Shell.

What you need: a Google Cloud project with billing enabled, and rights to enable APIs and deploy — Owner or Editor is simplest (otherwise: Vertex AI User, Discovery Engine Admin, and Service Usage Admin).

1. Open Cloud Shell

In the Google Cloud console, pick your project in the top bar, then click Activate Cloud Shell (the >_ icon, top-right). Optional: click Open Editor for the Cloud Shell Editor (a VS Code-style view) to watch the files agy creates.

2. Set your project

terminalexport GOOGLE_CLOUD_PROJECT=YOUR_PROJECT_ID gcloud config set project "$GOOGLE_CLOUD_PROJECT"

Cloud Shell is already authenticated as your account (ambient credentials), so no gcloud auth login is needed.

3. Install the Antigravity CLI (agy)

terminalcurl -fsSL https://antigravity.google/cli/install.sh | bash exec -l $SHELL # reload your shell so ~/.local/bin/agy is on PATH

The installer drops agy into ~/.local/bin. Confirm it with agy --version.

4. First launch & sign in

Start the CLI from your home directory so it operates on the workshop files:

terminalcd ~ && agy --dangerously-skip-permissions --add-dir ~

On first launch agy runs a brief setup (color theme, rendering mode, and a workspace-trust confirmation) and signs you in. Because Cloud Shell is a remote session, it can't open a browser for you — it prints an authorization URL: open it in a browser, sign in with your Google account, copy the code it displays, and paste it back into the terminal. After this one-time login, future agy sessions authenticate silently.

--add-dir ~ lets the agent read and edit files under your home directory (where the workshop project lives) instead of an internal scratch dir.

About --dangerously-skip-permissions

We start AGY with --dangerously-skip-permissions so it runs the workshop's shell commands and file edits without stopping to ask for approval on each one — otherwise you'd be confirming dozens of prompts. Use it at your own risk: with that flag AGY executes every command and edits files with no confirmation, so any mistaken or destructive action runs unprompted. It's an easy call in a disposable Cloud Shell / lab project; outside that, enable it only when you understand the trade-off and trust the workspace. To review each action instead, just drop the flag (agy --add-dir ~).

Heads-up: Cloud Shell sessions expire when idle

Cloud Shell (and the Cloud Shell Editor) disconnect after a period of inactivity — roughly 20 minutes for the terminal, and the underlying VM is recycled after up to about an hour of inactivity. When that happens your running agy stops. Your 5 GB $HOME persists (so agy, its login, plan.md, and your project files all survive) — just reconnect Cloud Shell and resume the same conversation where you left off:

terminalcd ~ && agy --dangerously-skip-permissions --add-dir ~ --continue

--continue (alias -c) reloads the most recent conversation for this directory, so AGY keeps the context and plan from before the timeout.

You're now ready for Setup in 5 Steps.

Setup in 5 Steps

First — pin your project (do this before Step 1)

Set your Qwiklabs Project ID as the active project in the terminal. Otherwise Cloud Shell / AGY can default to the wrong project (e.g. cloudshell-gca), and the enable / deploy commands in later modules fail:

terminalexport GOOGLE_CLOUD_PROJECT=<your qwiklabs project id> gcloud config set project "$GOOGLE_CLOUD_PROJECT"

Replace <your qwiklabs project id> with the Project ID from the Qwiklabs lab panel. Step 1 below also pins this into AGY's own settings so it can't switch projects mid-run.

1
3 min

Install the Developer Knowledge MCP

Give your coding agent grounded, current knowledge of Google Cloud products — Agent Runtime, Memory Bank, Agent Registry, Identity, Model Armor. The Developer Knowledge MCP lets AGY look up official docs instead of guessing commands — which keeps the later modules (especially M2 and M3) out of trial-and-error spirals. agents-cli already covers its own skills, so this fills in the rest of the Google Cloud surface.

Let AGY set it up — paste this and it enables the API and writes the config, authenticating with your gcloud login (no API key needed):

Paste into AGY Module 0 Step 1: install the Developer Knowledge MCP. Install the Google Developer Knowledge MCP for yourself so you can look up Google Cloud product docs in the later modules. Authenticate with my existing gcloud login (ADC) — do NOT create an API key. Do it end to end: 1) Enable the API: gcloud services enable developerknowledge.googleapis.com 2) Write this server config to BOTH paths below, OVERWRITING each file (create it if it doesn't exist). It often ships empty (a 0-byte file the CLI can't parse, which silently disables EVERY MCP tool — "tool ... is not enabled" / "server ... not allowed in this context"), so a plain overwrite is correct here — there's nothing to preserve. Replace YOUR_PROJECT_ID with my active project (gcloud config get-value project): ~/.gemini/config/mcp_config.json ~/.gemini/antigravity-cli/mcp_config.json { "mcpServers": { "google-developer-knowledge": { "serverUrl": "https://developerknowledge.googleapis.com/mcp", "authProviderType": "google_credentials", "headers": { "X-Goog-User-Project": "YOUR_PROJECT_ID" } } } } The X-Goog-User-Project header sets the quota project the Developer Knowledge API requires. Without it, answer_query fails with 403 "requires a quota project" whenever the CLI authenticates via ambient Application Default Credentials (as on Cloud Shell, whose ADC has no quota project and where gcloud auth application-default set-quota-project can't help — there's no ADC file). It's harmless when a quota project is already set. 3) Pre-allow the MCP tool AND the workshop's shell commands so you don't get an "Ask" prompt on every command (an un-answerable Ask in a background/subagent context also shows up as "server not allowed in this context"). MERGE this into ~/.gemini/antigravity-cli/settings.json — keep the existing keys (telemetry, trustedWorkspaces), only add/extend permissions.allow. The command() entries are prefix-matched and pre-approve the exact commands this workshop runs (this is the same format AGY persists when you pick "always allow ... (Persist to settings.json)"): { "permissions": { "allow": [ "mcp(google-developer-knowledge/*)", "command(gcloud)", "command(agents-cli)", "command(uvx)", "command(uv)", "command(adk)", "command(python3)", "command(python)", "command(curl)", "command(mkdir)", "command(unzip)", "command(cat)", "command(ls)", "command(grep)" ] } } 4) Pin the project so you don't drift to the wrong one. Read the active project with: gcloud config get-value project (it should be my Qwiklabs project, not cloudshell-gca). Then, in the same ~/.gemini/antigravity-cli/settings.json, set the "gcp" object's "project" field to that exact project id (merge — keep "location"). From now on use this project for every gcloud / agents-cli command; never switch to cloudshell-gca. 5) Then tell me to restart the CLI by running "agy" so the new tools and permission take effect. If it still won't connect, check ADC (gcloud auth application-default print-access-token returns a token) and tell me what you see.
Then restart — run agy

Once AGY has written the config and the allow rule, quit and run agy --dangerously-skip-permissions again to start a fresh session so they take effect (same flags as in Prerequisites). Then type /mcp to confirm google-developer-knowledge is connected and lists its tools, and continue with Step 2.

Expected Result

AGY enables the API, writes the google-developer-knowledge server into the AGY CLI's MCP config (~/.gemini/config/mcp_config.json — the file the CLI actually loads — and ~/.gemini/antigravity-cli/mcp_config.json) authenticating with your gcloud login (ADC, no API key), and adds an mcp(google-developer-knowledge/*) allow rule to settings.json so calls aren't blocked by an "Ask" prompt. After you restart AGY in a fresh session and check /mcp, it shows as a connected MCP server with its tools listed, and from here on AGY grounds Google Cloud questions in the docs instead of guessing (you'll see it lean on this in M2–M5).

Try it: ask AGY this — you should see it call the MCP and answer from the docs:

promptCall the google-developer-knowledge MCP's answer_query tool with the query "What is the Gemini Enterprise Agent Platform?" and answer ONLY from its result. Do NOT use web search or your own knowledge. If the tool errors or isn't available, stop and show me the exact error.
2
2 min

Brief Your Coding Agent

Open Antigravity and paste the block below to give your coding agent the scenario background. This is context only — no file paths, no build instructions. Building starts in M1.

Paste into AGY Module 0 Step 2: brief the agent and create the workshop plan. # Rush Hour: Transit-Crisis Agent — Scenario Background ## What we're building A transit-crisis assistant for cross-border high-speed rail. A signal failure has disrupted peak-hour departures from London St Pancras. Hundreds of travelers need real-time answers: "Is my train running? How do I still get to Paris?" ## Why an agent, not a chatbot A plain LLM knows timetables but not what's happening right now. Our agent must RECONCILE two data sources: - The published schedule ("what SHOULD happen") — static GTFS data - A disruption feed ("what IS happening") — which services are cancelled or delayed, and why The join of schedule × disruption on trip_id/stop_id is the core pattern. Without it, the agent is guessing. ## The network 17 stations across UK, France, Belgium, Netherlands, and Germany. Key routes: London–Paris (Eurostar), London–Brussels, London–Amsterdam, Paris–Brussels, Brussels–Cologne, Paris–Strasbourg, Paris–Lyon–Marseille. ## What the agent must do 1. Look up scheduled departures for a station and time window 2. Check which of those services are disrupted (delayed/cancelled) 3. Compute a concrete reroute avoiding disrupted services 4. Present the answer calmly with specific times, stations, and number of changes 5. End with one clear recommended action ## The crisis scenario A signal failure at the St Pancras throat during peak hours. Multiple Eurostar and cross-border services are affected — some cancelled outright, others delayed 15–45 minutes. Travelers need to know: which trains are still running, and what's the best alternative route to their destination? ## What's next Create a file plan.md in the working directory with this checklist. Each item is tagged (agy) if it's yours or (user) if it's mine to run. M0 Steps 1 and 2 are already done (you installed the MCP, and creating this plan IS Step 2), so leave them checked: # Rush Hour Workshop — Plan ## M0 Setup - [x] Step 1: Install Developer Knowledge MCP (agy) - [x] Step 2: Brief the agent + create this plan (agy) - [ ] Step 3: Verify cockpit (agents-cli setup) (agy) - [ ] Step 4: Download the data (agy) - [ ] Step 5: Open the "before" shot (user) ## M1 Build - [ ] Step 1: Scaffold the ADK project (agy) - [ ] Step 2: Add the three tools (agy) - [ ] Step 3: Write the system instruction (agy) - [ ] Step 4: Run locally in the playground (agy) ## M2 Scale - [ ] Step 1: Prepare the runtime entrypoint (no deploy) (agy) - [ ] Step 2: Add session state + Memory Bank (code only) (agy) - [ ] Step 3: Add code execution (code only) (agy) - [ ] Step 4: Local runtime smoke test (agy) - [ ] Step 5: Deploy once (agy) - [ ] Step 6: Test the deployed agent in the Console Playground (user) ## M3 Govern - [ ] Step 1: Why govern (read) (user) - [ ] Step 2: Verify Registry + identity + least-privilege (agy) - [ ] Step 3: Shield with Model Armor (agy) - [ ] Step 4: Enterprise control plane (read) (user) ## M4 Optimize - [ ] Step 1: The local eval-fix loop (read) (user) - [ ] Step 2: Simulate the crisis at scale (agy) - [ ] Step 3: Grade and read the score table (agy) ## M5 Engage - [ ] Step 1: Deploy fresh + publish to Gemini Enterprise (agy) - [ ] Step 2: Unified finish line (user) How we work together: - Steps tagged (user) are mine — read sections, shell commands, console clicks. Don't do those; I'll check them off myself. - Steps tagged (agy) are yours, but do one only when I send a prompt starting with "Module X Step Y:". - After you finish any (agy) step, immediately update plan.md before you reply: change that step's [ ] to [x]. Do this every time, even if I don't remind you. If you notice an earlier (agy) box still unchecked, fix it then. - Do NOT run ahead to later steps until I explicitly ask. If you think a later step is needed, tell me — don't just do it. Do NOT start building yet — this is context and your plan only.
3
2 min

Verify Your Cockpit

🛠️ What is agents-cli?

agents-cli is Google's CLI for the full agent development lifecycle — scaffold, deploy, evaluate, and publish — all on top of the Agent Development Kit (ADK).

It installs context-aware skills into your coding agent (Antigravity, Gemini CLI, Claude Code, etc.) so you can describe what you want in natural language and let the skills handle the wiring: project structure, deployment configs, eval harnesses, and more.

In this workshop, agents-cli is your primary tool. You'll use its skills in every module from scaffolding (M1) through publishing (M5).

Confirm that agents-cli and its skills are installed:

promptModule 0 Step 3: run this command in the shell for me and show me the output — uvx google-agents-cli setup

setup installs four skills that cover the full agent lifecycle — here's what each one does and where you'll use it (no need to run these now; the later modules drive them for you):

SkillWhat it doesUsed in
scaffoldGenerates a deployable ADK project structure (agent, tools, configs) from a plain-language descriptionM1
deployPackages your agent and ships it to Agent Runtime on the platformM2
evalBuilds an evaluation suite and scores the agent's answersM4
publishRegisters the deployed agent to Gemini Enterprise for business usersM5

The mantra: "Describe the outcome; let the skills do the wiring."

Expected Result

setup completes and installs all 4 skills (scaffold, deploy, eval, publish) into your coding agent. Your cockpit is ready — you'll put these skills to work starting in M1.

Heads up — who you're acting as

setup authenticates via Application Default Credentials (ADC), which in this lab is the workstation service account (workstation-sa@…) — not your student login. That's expected: it's the identity that deploys and runs your agent, and it's what M2 (deploy) and M3 (IAM / least-privilege) reason about later.

4
2 min

Download the Data

Download the Eurostar GTFS bundle (official public feed from transport.data.gouv.fr) and the disruption file into your project:

promptModule 0 Step 4: run this in the shell for me and show me the output. It tries the official Eurostar GTFS feed first and automatically falls back to the workshop repo mirror if that download fails, then fetches the disruption file — mkdir -p data/gtfs && { curl -fL -o /tmp/gtfs.zip https://integration-storage.dm.eurostar.com/gtfs-prod/gtfs_static_commercial_v2.zip || curl -fL -o /tmp/gtfs.zip https://kazunori279.github.io/gcp-eoa/BwG-track2/data/gtfs.zip; } && unzip -o /tmp/gtfs.zip -d data/gtfs/ && curl -L -o data/disruptions.json https://kazunori279.github.io/gcp-eoa/BwG-track2/data/disruptions.json

Quick orientation (no deep analysis yet):

  • stops.txt — 17 stations across UK/FR/BE/NL/DE
  • stop_times.txt — departure/arrival times per trip per stop
  • trips.txt — trip definitions with route references
  • disruptions.json — which services are cancelled/delayed and why

Expected Result

Your workspace has this data layout:

  • data/gtfs/stops.txt — 17 stations with coordinates
  • data/gtfs/stop_times.txt — departure/arrival per trip per stop
  • data/gtfs/trips.txt — trip definitions with route references
  • data/gtfs/routes.txt — route metadata (Eurostar, Thalys, etc.)
  • data/gtfs/calendar_dates.txt — service date exceptions
  • data/disruptions.json — simulated signal failure at St Pancras

Key joins you'll use in M1: stops.stop_id → stop_times.stop_id, stop_times.trip_id → trips.trip_id, trips.route_id → routes.route_id, disruptions.trip_id → trips.trip_id.

📂 What You Downloaded

treedata/ ├── gtfs/ # Static GTFS bundle │ ├── stops.txt # 17 stations (St Pancras, Paris, Brussels, ...) │ ├── stop_times.txt # Departure/arrival times per trip per stop │ ├── trips.txt # Trip definitions → route references │ ├── routes.txt # Route metadata (Eurostar, Thalys, ICE, ...) │ └── calendar_dates.txt # Service date exceptions └── disruptions.json # Simulated signal failure at St Pancras

📅 GTFS Files — Quick Reference

FileKey columnsWhat it tells you
stops.txt stop_id, stop_name, stop_lat, stop_lon The 17 stations in the network with coordinates
stop_times.txt trip_id, stop_id, arrival_time, departure_time, stop_sequence When each trip stops at each station, in order
trips.txt trip_id, route_id, service_id, trip_headsign Each individual train service and which route it belongs to
routes.txt route_id, route_short_name, route_long_name Route metadata (e.g., "Eurostar London–Paris")
calendar_dates.txt service_id, date, exception_type Service date exceptions (additions/removals)

⚠️ The Disruption File

disruptions.json simulates the signal failure. It contains:

FieldDescription
affected_tripsList of trip_ids that are cancelled or delayed
delay_minutesDelay magnitude per affected trip
statuscancelled or delayed
affected_stopsWhich stops are impacted (primarily St Pancras)
cause"signal_failure"
time_windowStart/end of the disruption period

Your agent's check_disruptions tool will read this file and cross-reference it with the GTFS schedule via trip_id / stop_id.

🔗 How the Files Connect

stops.txt stop_id, stop_name stop_times.txt trip_id, stop_id, times trips.txt trip_id, route_id routes.txt route_id, name disruptions.json trip_id, status, delay calendar_dates.txt service_id, date stop_id trip_id route_id service_id trip_id GTFS joins (schedule) Disruption join The reconciliation pattern: schedule x disruption on trip_id
5
2 min

Open the "Before" Shot

Open two browser tabs now — this is your "before" picture:

  1. Agent Platform console — no custom agents deployed yet, no registry entries, no policies.
  2. Gemini Enterprise app — you'll see a default My Gemini Google Search App. By the end, your transit-crisis agent will sit right alongside it.

By the end of the workshop, you'll be able to use your own agents in the Gemini Enterprise app, just like you use Gemini today.

Why take a "Before" shot?

The console already has a default My Gemini Google Search App. That's Gemini working for you out of the box. By 2:00, your own transit-crisis agent will sit right alongside it — proof that vibe-coding produces real enterprise assets you can use just like Gemini.

💻 Agent Platform Console

Open the Agent Platform console in a browser tab.

Now (M0)
  • Default Gemini search app only
  • No custom agents deployed
  • No registry entries
  • No gateway policies
By 2:00 (M5)
  • Agent Runtime instance
  • Sessions + Memory Bank
  • Registry entry with tools
  • Identity + Gateway + Model Armor
  • Eval scores + optimized prompt

💬 Gemini Enterprise App

Open the Gemini Enterprise web app in another tab. You'll see My Gemini Google Search App — that's the default.

Now (M0)
  • Default Gemini search app
  • No custom agents yet
By 2:00 (M5)
  • Transit-crisis agent published
  • Sits alongside the default Gemini app
  • Any user can chat with it

🗺️ The Arc You'll Traverse

M0 Setup YOU ARE HERE M1 BUILD Agent + Tools 25 min M2 SCALE Deploy + State 30 min M3 GOVERN Security 15 min M4 OPTIMIZE Quality 18 min M5 ENGAGE Publish 10 min Each module recap: What You Typed → What Ran → What You Can See → Why It Matters

Mentor Checkpoint — Done When:

  • Antigravity is open and responsive
  • agents-cli skills are installed and recognized
  • Developer Knowledge MCP (google-developer-knowledge) is installed
  • Scenario context pasted into Antigravity
  • GTFS data is downloaded into data/gtfs/
  • Disruption file is at data/disruptions.json
  • Agent Platform console is open
  • Gemini Enterprise app is open (default search app visible)