Inspiration
EggWise is a real fertility-care platform with a clinical side. Clinics get lab results the way most of medicine does: as faxed or emailed PDFs. Staff retype them by hand, then decide who needs attention. Hours of clinical time, spent on paperwork.
So we built the fleet we actually want to run in production, under real enterprise constraints: PII isolation, zero-trust identity, and a full audit trail.
What it does
Upload a lab PDF and walk away. No chatbot. The prompt is a PDF.
While you do something better with your time, the fleet:
- Screens first. Model Armor de-identifies PII and blocks prompt injection before any reasoning model sees a single character.
- Reads anything. A deterministic quality gate passes clean text straight through; messy scans get a fenced, transcribe-only multimodal Gemini read.
- Files bulk uploads safely. A deterministic matcher assigns a chart only on two exact identifiers plus a unique roster hit. Anything less parks in a Needs Identification queue for a human. Chart assignment is never a model's guess.
- Extracts, then verifies. A Gemini 3.5 Flash agent pulls the hormone biomarkers. Clinical range verdicts are plain code, ported from our production rules. A bounded critic gives shaky extractions one focused re-read; after that, the refusal stands.
- Triages with context. A second Gemini agent cites weeks of the patient's cycle history from Vertex AI Memory Bank and clinical guideline ground truth, by name.
- Delivers. A structured alert lands in Firestore plus an HL7 FHIR R4 export. The doctor's dashboard updates in real time, and a telemetry dashboard tracks block rate, latency, and cost per PDF (about half a cent).
How we built it
Two Cloud Run services, one container image. A public gateway is the only front door: API key, content type, size, and clinic allowlist checks, with every decision audited. A private worker is reachable only through a Pub/Sub OIDC push subscription. Upload flows gateway to GCS to Pub/Sub to worker, dead-letter queue included.
Inside the worker, an ADK SequentialAgent runs five agents: Gemini parser,
deterministic range validator (zero LLM, including its refusals: no verdict on
phase-dependent markers without a cycle day), bounded extraction critic, Gemini
triage agent (custom recall tools query Memory Bank and the guideline corpus through
backend seams), and a deterministic dispatcher that writes the alert and its FHIR
export. Two more fleet members sit in front: the patient matcher and the multimodal
transcriber. Seven agents total. LLMs handle extraction and reasoning; everywhere a
mistake is unacceptable, it's plain code.
Security is structural, not decorative. PII never reaches a model. Patient identity travels in the GCS object path, never in document content. Three least-privilege service accounts split gateway, worker, and push identities.
Observability is one trace per document: the gateway plants traceparent in GCS object
metadata, the worker resumes it, and the whole journey (upload, guard, parse, memory
recall, triage, write) shows as a single Cloud Trace waterfall, mirrored to an append-only
audit collection.
The money shot: alert documents conform exactly to our production dashboard's schema. The real EggWise Pro UI, repointed at the sandbox by env vars alone, zero code changes, lights up live as the fleet writes.
Challenges we ran into
- Gemini 3.5 Flash only serves from the
globalendpoint (404s in us-central1), while Model Armor, DLP, and Agent Engine are regional. Fix: a deliberate two-location split. - Our guard initially failed open. A non-SUCCESS Model Armor call let documents continue. We inverted it: any guard failure now quarantines. Same posture in the gateway, which refuses everything if no API key is configured.
- Model Armor's service agent secretly needs DLP roles before advanced de-identification will run. Found by reading invocation results, not docs.
- No trace context survives a GCS notification, so
traceparentrides GCS object metadata into the Pub/Sub envelope. - The usual production landmines:
/healthzeaten by the GFE on run.app, an org policy silently blocking public access, a Firestore create that "succeeded" without creating anything, and ADK forbiddingoutput_schemaand tools on the same agent (solved by splitting extraction and tool-using triage into separate agents).
Accomplishments that we're proud of
- A production UI rendered a hackathon fleet's output with zero code changes. Schema conformance enforced by tests turned out to be the strongest integration contract we have ever shipped.
- Verified end to end. 86 unit tests plus a 5-golden-PDF eval suite. A clean document becomes a cited, history-aware alert in about 40 seconds. A prompt-injected document is quarantined by real Model Armor in half a second. An unauthenticated call to the worker gets a 403.
- The fleet grew from four agents to seven without changing verified behavior. Every enterprise feature is additive behind a deterministic gate: the matcher only sees unassigned uploads, the critic only fires on extraction refusals, the multimodal fallback only on scan-quality documents.
What we learned
- Determinism is a feature, not a fallback. The two places mistakes are unacceptable (range verdicts and database writes) are plain code, and the audit trail shows exactly which kind of agent did what.
- Fail closed, everywhere. Guard, gateway key, clinic allowlist. Enterprise "fortification" turned out to be about 20% model work and 80% IAM, org policy, and plumbing. The backend seams are what kept velocity while using real services.
What's next for EggWise Clinical Fleet
The pillars built here (Model Armor screening, Memory Bank, observability, the agent registry) are the production roadmap for EggWise's live agent. Everything shown is synthetic; the system is a prototype, not a medical device.
Data sources. Every document, patient, and observation is synthetic and generated by
the repo itself: scripts/generate_dummy_lab.py produces the lab PDFs (including the
prompt-injection variant), scripts/seed_firestore.py seeds the fictional clinic roster,
and scripts/seed_memory_bank.py seeds cycle history into Vertex AI Memory Bank. The
clinical guideline corpus is an original synthetic corpus written for this project, not
copied from ASRM or any published source. No real patient data, no external datasets, no
production EggWise data anywhere in the sandbox. Not a medical device.
Built With
- agent-development-kit
- cloud-run
- cloud-storage
- cloud-trace
- fastapi
- firebase
- firestore
- gemini
- google-cloud
- model-armor
- next.js
- opentelemetry
- pub-sub
- pydantic
- python
- typescript
- vertex-ai

Log in or sign up for Devpost to join the conversation.