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


- 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.
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.
Per-parcel enrichment is fetched and cached once at onboarding. Each chat turn reuses that cache instead of re-fetching the external APIs.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.
