What it is
robo-fleet is a virtual AI company of 25 AI agents plus one human CEO that runs as a self-organizing software workforce on Google Cloud. Each agent is built on Google ADK and runs on Gemini 3.5 Flash; together they plan, code, QA, review, and merge real tasks through a structured lifecycle, observable from a live Next.js control panel. It is submitted to the All Things Agentic hackathon, Fortified Enterprise Fleet track.
What inspired it
Most AI agent demos are one agent doing one task in a terminal. robo-fleet starts from a different premise: a software company is not a single intelligence, it is an organization, with a hierarchy, specialized roles, handoffs, review gates, and a human in the loop who approves real work. So robo-fleet is a complete software workforce: a board (Product Owner, Head of Marketing, a silent Auditor), a main PM, three cells (backend, frontend, UX/UI) each with two developers, a QA, a PM, a documenter, and a PR reviewer, plus an intake interviewer, a secretary, and the human CEO. The human is the CEO, not a prompt engineer. They set goals, approve major changes, and hold the publish and cost-cap decisions; the fleet plans, codes, reviews, and merges autonomously up to that line. The question was never "can an agent write code," it was "can a fleet of agents operate as a company that ships."
How I built it
I ported the existing RoboFleet AI-agent-company system to the Google stack. Three real changes, everything else carried over verbatim.
- Spawn backend. Instead of docker-run-ing a container per task, a CloudRunJobsProvider submits a Cloud Run Job execution per agent task and polls it to completion. One image serves every role; role behavior comes from the tool manifest and the composed system prompt. Each agent is a bounded Cloud Run Job with a terminal state, not a long-lived container to keep alive and reap.
- Agent runtime. Instead of the Claude Code CLI, each agent is an ADK LlmAgent run by the ADK Runner on Gemini 3.5 Flash, pure Python, no MCP servers, no Node.js. A gateway tool-shim and git/file FunctionTools let the agent call the same server-side intent verbs (give_me_work, i_will_work_on, open_pr, i_am_done, claim_review, pass_review, fail_review, complete, submit_up, submit_root) through a Choreographer that composes the domain services and returns a standardized Envelope. Agents never call domain services directly.
- Infrastructure. Postgres plus pgvector moved to Cloud SQL Postgres 16 via the Cloud SQL python connector; Redis to Memorystore for Redis 7.x; the workspaces volume to a Filestore NFS share; agent clones and artifacts to GCS; the Fernet key, the agent-auth HMAC secret, and the Gemini API key to Secret Manager; the three images (orchestrator, panel, agent-adk) to Artifact Registry built by Cloud Build; the orchestrator and panel deploy to Cloud Run behind a load balancer, on a VPC with private service access for Memorystore and Cloud SQL.
Everything else is unchanged: the org hierarchy, the task lifecycle, the findings ledger, the architectural-conventions standard, the audit log, and the Next.js control panel. A task flows claimed, in_progress, awaiting QA, PR review, PM review, then CEO approval for major work, then merged. An in-path PR review gate reviews every assembled PR before the PM merges. Scheduling is sequence-based: a task cannot be claimed while a same-parent sibling with a strictly lower sequence is non-terminal, so independent work runs in parallel and colliding work runs in order. Every bounce (QA fail, PR-gate fail, PM request-changes, CEO reject) produces a structured, file-and-line-anchored finding, not prose, and the developer must name each open finding by id before they can re-submit.
The seven fleet properties the Fortified Enterprise Fleet track scores all already exist in the system and map onto the Google stack. Agent registry: the 25 agents plus the CEO in the agent registry and the agents DB table, loaded at orchestrator startup. Runtime: Cloud Run Jobs running the ADK Runner and LlmAgent on Gemini 3.5 Flash in the robofleet-agent-adk image. Memory bank: a pgvector knowledge base (an in-house RAG engine) on Cloud SQL, plus the organizational-memory loop that captures one distilled lesson per completed task and injects the relevant lessons into the next claim's briefing. Identity: per-agent HMAC tokens signed with the agent-auth secret for the agent gateway, plus FastAPI Users cookie and JWT cloud auth for the human CEO on the public panel. Gateway: the Choreographer plus the flow and do intent-verb routes; every verb returns a standardized Envelope with a next field and a remediate field so agents never guess state. Model armor: the task-content guardrails (a prompt-injection guard, forbidden-content screening, per-role tool manifests) plus the architectural-conventions standard, enforced at i_am_done and at the in-path PR review gate. Observability: the audit-log transition journal plus MetricsService (cycle time, rework rate, spawn-waste) surfaced in the panel, plus Cloud Logging for the Cloud Run services and jobs.
Challenges I faced
Replacing the Claude Code CLI agent runtime with ADK and Gemini without re-implementing the tool surface. The fleet's security posture depends on agents never calling domain services directly; they go through intent verbs. ADK's FunctionTool shim let the LlmAgent call the same verbs over a thin HTTP gateway, preserving the Choreographer's centralized tracing, claim-locking, and remediation hints, while the agents run on Gemini 3.5 Flash.
The interactive intake and secretary chat paths were originally a persistent Claude agent-sdk runtime. Rebuilding them as a Gemini/ADK twin, using an ADK MCPToolset against the existing FastMCP tool servers with a persistent InMemorySessionService session and a GeminiChatSession implementing the IntakeSession protocol, without re-implementing the tool servers, was the hardest single piece. The IntakeDriver is reused untouched across all three interactive paths (Claude legacy, Grok, Gemini), so the transport seams had to be extracted into a shared module before the Claude mains could come out.
Keeping the security posture on GCP. The homelab stack ran on a private network; the GCP panel is publicly reachable, so cloud auth (a cookie plus a JWT bound to a fingerprint of the current password, with sliding sessions) had to be armed, and the per-agent HMAC identity and the model-armor guardrails had to survive the port. The agent mesh runs on one bridge and the data plane (Cloud SQL, Memorystore) on another, so agent containers cannot reach the database at all; network membership is the containment.
Git history hygiene before submission. Internal planning docs had been pushed to the branch and had to be purged from history with filter-repo, then every commit re-signed, then force-pushed, not merely deleted in a new commit.
Cost discipline. The live deploy burns GCP credits, so the fleet auto-parks on rate limits and model overloads instead of crash-respawning and burning tokens, the organizational-memory distillation runs on a cheap model, and every originate-a-task engine (self-heal, multi-repo CI-watch, the gated release manager) is held behind the CEO, never auto-merging or auto-deploying.
What I learned
The hardest problem in an agent fleet is not the model, it is the coordination protocol: who does what, in what order, with which review gate, and how a failure routes back. Sequence-as-the-bar and structured findings were the two patterns that broke the infinite rework loops that killed earlier versions. A fleet without a sequence bar either serializes everything (slow) or races siblings that edit the same files (broken); a fleet without structured findings bounces prose back and forth and never converges on what to fix.
Cloud Run Jobs is a surprisingly natural spawn backend for a per-task agent lifecycle. Each agent is a bounded job with a terminal state the orchestrator polls, not a long-lived container to keep alive, health-check, and reap. The serverless spawn model fits an agent that does one task and exits.
ADK and Gemini are a clean fit for a pure-Python agent runtime that still goes through a server-side gateway. The LlmAgent plus FunctionTool shim separates what the model can do (call intent verbs) from what the verbs do (server-side service composition), which is exactly the seam a fleet needs to keep the model swappable and the business logic centralized.
A human CEO in the loop is not a limitation, it is the autonomy boundary that makes the rest safe to automate. The fleet can plan, code, review, and merge autonomously up to the line; the CEO holds the publish, merge-to-prod, and cost-cap decisions. That boundary is what lets the rest run without a human watching every step.
Built With
- agents
- artifact-registry
- cloud-build
- cloud-run-jobs
- cloud-sql-for-postgresql
- docker
- fastapi
- filestore
- gemini-3.5-flash
- google-adk
- google-cloud
- google-cloud-vpc
- googlecloudrun
- memorystore-for-redis
- multi-agent-systems
- next.js
- pgvector
- postgresql
- pydantic
- python
- redis
- secret-manager
- sqlalchemy
- terraform
- uv
Log in or sign up for Devpost to join the conversation.