Inspiration

On 20 May 2020, Cyclone Amphan made landfall in West Bengal — one of the most powerful storms to hit the Bay of Bengal in decades. In the chaotic first hours after a disaster like this, responders aren't short on information; they're drowning in it. Official alerts, panicked social posts, citizen phone reports, volunteer radio chatter, and outright rumors all arrive at once, often contradicting each other. A responder has to decide, in minutes, what's actually true before deciding where to send help. That gap — between information and verified information — is where people get hurt. I wanted to see if Gemini could help close that gap, fast.

What it does

Disaster Response Agent takes five independent, conflicting reports from the early hours of Cyclone Amphan's landfall and runs them through a three-agent Gemini pipeline:

  1. Extractor agent — reads each raw source independently and pulls out discrete, structured claims (what happened, where, how severe), flagging vague or low-specificity statements along the way.
  2. Cross-Verifier agent — takes all extracted claims together, groups them by topic, and marks each group corroborated, contradicted, unconfirmed, or low confidence based on how the sources agree or disagree.
  3. Reporter agent — synthesizes everything into one responder-ready situation report: confirmed facts, disputed items still needing resolution, unverified items needing follow-up, and concrete next verification steps.

The UI shows the entire trail — raw sources → extracted claims → verification status → final report — so nothing is a black box. A responder can see exactly why the system trusts one claim and flags another.

How I built it

  • Gemini API (gemini-2.5-flash-lite, chosen specifically for its higher free-tier daily quota) powers all three agents as isolated calls, each with its own system instruction and a strict JSON responseSchema — so output is always structured, never prose to re-parse by hand.
  • FastAPI backend, with an in-memory cache on the full pipeline result, since each run costs 7 Gemini calls and the free tier is genuinely limited.
  • Firestore (Firebase's free Spark tier) persists every completed run so history survives server restarts — surfaced in the UI as a "Run History" section, and the project's Google Cloud integration.
  • Plain HTML/CSS/JS frontend, deliberately framework-free — a dark, terminal-inspired UI built to read as a live ops dashboard rather than a typical web app, with an ambient Three.js particle animation behind the header for polish.
  • Split deployment: frontend on GitHub Pages, backend on Render — meaning the two had to learn to talk across origins rather than assuming same-origin convenience.

Challenges I ran into

  • Free-tier rate limits aren't a footnote — they're a design constraint. I hit Gemini's free-tier daily request limit during development, not at the demo. That's what pushed caching from "nice to have" to "actually required," and taught me to treat every Gemini call as something to budget, not fire casually while debugging.
  • Borrowed UI components weren't free. A couple of polish effects (the ambient particle background, card glow/spotlight interactions) came from React component libraries — but my frontend deliberately has no build step. Porting the underlying logic to plain ES modules, loaded via import maps straight from a CDN, meant tracking down a Three.js version mismatch that silently crashed the whole effect over one missing material property.
  • Two servers, two origins, one new bug class. Once the frontend moved to GitHub Pages and the backend to Render, relative API paths that worked fine locally broke completely — a CORS and absolute-URL lesson I'll carry into every future split deployment.
  • GitHub Pages only serves from / or /docs, no arbitrary folder names — which meant restructuring the repo mid-build rather than fighting the platform.

What I learned

Multi-agent prompting is less about one clever prompt and more about deliberately narrow prompts: the Extractor never sees other sources, the Verifier never sees raw text, the Reporter never re-derives facts — it only synthesizes what's already been verified. Keeping each agent's job small made the pipeline far more reliable than one giant "do everything" prompt would have been. I also came away with a concrete sense of what "free tier" means in practice: not infinite, but a real constraint that should shape architecture from day one, not get bolted on after testing burns through the quota.

What's next

Real-time source ingestion instead of a fixed mock scenario, confidence scores that update as more sources arrive over time, and a verified-claims API other emergency-response tools could consume directly.

Built With

Share this project:

Updates

Submission history