jgvilchezc.dev
← Back to work
/agroasistenteLive

AgroAsistente

Agronomic advice grounded in this farm's own dirt. Per-parcel weather, soil, land-cover and NDVI assembled into every answer.

Role
Solo founder · Lead engineer
Year
2026
Status
Live
Offline-first · PWA
Camera · Plant ID
Listening
Don Agro · ES-VE
Offline · queued
José Gabriel Vilchez CarrasqueroJosé Gabriel Vilchez Carrasquero
At a glance
Grounding
Per-parcel geo
Signals
Weather · soil · land-cover · NDVI
Retrieval
RAG over pgvector
LLM fallback
3 tiers

Overview

A generic LLM tells a Venezuelan farmer what's true on average. It can't know that this plot is sandy clay, two weeks into a dry spell, with NDVI trending down. AgroAsistente grounds every answer in the data of the specific parcel the farmer drew on the map. Weather, soil, land-cover and satellite vegetation feed the prompt before the model ever sees the question.

It's built for the constraints of the market it serves: flaky rural connectivity and a region where API cost and reliability are first-order problems, not afterthoughts. Offline-first PWA, durable rate limiting, and a fallback chain that survives a Google outage. A native Expo client for iOS and Android now ships alongside the web app, and roughly 147 automated test files cover both surfaces. It's a working product with real engineering depth, not yet a hardened release.

The answer is grounded in this farm's own weather, soil and NDVI, not in what a generic LLM remembers about agriculture.

Architecture

Steps 01–03 run once when a parcel is registered: auth, draw the plot, then lazily fetch and cache its weather, soil, land-cover and NDVI. Steps 04–06 fire on each chat turn, assembling the cached context plus RAG and streaming a grounded answer from Gemini.

onboard (once per parcel)
01 · AuthGoogle OAuth → Supabase session (per-user RLS)
02 · Register parcelLeaflet-Geoman draw on satellite map → polygon
03 · Enrich + cacheOpen-Meteo · SoilGrids · MapBiomas · Sentinel-2 NDVI → parcel row
enrich → cached
chat turn (grounded)
04 · Assemble contextcached per-parcel signals → prompt block
05 · Retrievepgvector over INIA/FONAIAP agronomic chunks
06 · Generate + streamGemini 3.5 Flash (3-tier fallback) · voice · photo recognition

Steps 01–03 run once when a parcel is registered: auth, draw the plot, then lazily fetch and cache its weather, soil, land-cover and NDVI. Steps 04–06 fire on each chat turn, assembling the cached context plus RAG and streaming a grounded answer from Gemini.

Key features

  • /01

    Per-parcel geo-grounding

    The farmer draws the plot on a satellite map. Open-Meteo weather, SoilGrids soil, MapBiomas land-cover and Sentinel-2 NDVI for that exact polygon get assembled into the prompt, so the answer reflects this farm, not the regional average.

  • /02

    RAG over a real agronomic corpus

    Retrieval runs against an INIA/FONAIAP corpus embedded in pgvector. Recommendations cite local agronomy, not whatever an ungrounded LLM happens to recall.

  • /03

    Dual-role, one app

    The same surface serves the productor (grow advice) and the vendedor (supply and sales context). Role shapes the prompt and the retrieval, not the codebase.

  • /04

    Voice and photo, in the field

    Voice input in Venezuelan Spanish and photo plant recognition mean a farmer with dirt on their hands can ask without typing. Multimodal input over a single chat turn.

  • /05

    Native client, same backend

    An Expo app for iOS and Android runs as a thin client over the same Vercel API and Supabase project. Offline queueing, resumable chat streams after a signal drop, EAS builds with OTA updates, and per-endpoint contract tests against the shared backend.

Technical decisions

  • Weather, soil, land-cover and NDVI come from rate-limited external APIs. Fetching all four on every chat turn would add seconds of latency and hammer quotas that aren't ours to burn. The data is fetched lazily once, cached on the parcel row, and reused. Chat stays fast and the external APIs stay happy.

What I'd do differently

  • /01

    Refresh the per-parcel enrichment on a schedule, not just lazily. NDVI and weather go stale; a cron that re-fetches plots whose cache is older than its signal's natural cadence would keep answers current without making chat pay the fetch cost.

  • /02

    Push parcel geometry and the cached context into the offline store more aggressively. Right now offline mode leans on the last chat state; pre-caching the full parcel context would let a farmer get grounded answers even on the first cold start without signal.

AgroAsistente concept key visual: an aerial false-color NDVI view of farmland parcels in greens, amber and clay, one parcel highlighted with floating agronomic data cards (soil moisture 65%, soil index 52%, NDVI 0.81, weather), the per-parcel geo-grounding that anchors every answer.