DEV Community

OJ
OJ

Posted on

Built an agent fleet that helps farmer's for free

I built this for the All Things Agentic Hackathon. This post covers how it works and what broke along the way.

A satellite can't see crop disease. It sees one signal — plants looking less healthy than they should — and that has a dozen causes: drought, harvest, haze, a field boundary drawn over a car park. Every satellite tool alerts on that drop, and because most alerts are nothing, farmers stop opening them.

So I built Fieldhand: a fleet of agents where most of the effort goes into trying to prove its own findings wrong.

The shape of it

Nobody logs in. Cloud Scheduler → Pub/Sub wakes it at 4am, a Watchman picks the fields worth looking at, and each runs through a Google ADK fleet: Diagnostician (reads the satellite evidence) → Skeptic (attacks the diagnosis) → Agronomist (plans treatment + a real spray window) → Operations (work orders). Anything that costs money stops at a human.

The Skeptic is the whole project

It's not told to "verify" — a model asked to verify goes and finds supporting evidence. It's told to find the reason the diagnosis is wrong. Its main instrument is arithmetic: compare this field to its neighbours, and to its own history in prior years. On a real Palouse field reading −5.5σ (catastrophic), the Skeptic pulled 3 years of history, saw it's harvested and bare every August, and refused to alarm. During testing it also caught a "dying 400-acre field" I'd drawn over downtown Pullman — it looked at the imagery, saw rooftops, and dropped confidence to 0.10.

Three things that bit me

  1. On Gemini 3.x, max_output_tokens covers thinking AND the answer. Budgets ported from another provider got eaten by reasoning and returned truncated fragments with no error.
  2. Gemini sends numeric tool args as strings ("$6,044"), which crashed the policy layer until I coerced at the tool boundary.
  3. A trailing newline in a secret costs an afternoon — Python stripped it, TypeScript didn't, every cross-service write 401'd.

Where the autonomy stops

The policy layer is plain code with no model in it. Even a wrong or prompt-injected agent physically can't spend a grower's money. The interesting engineering wasn't making the agents smart — it was deciding where they don't get a vote.

Built with Google ADK · Gemini 3.5/3.7 Flash on Vertex AI · Gemma · Cloud Run · Firestore · Cloud Scheduler + Pub/Sub. Data from Sentinel-2 and Open-Meteo, both free.

Live: https://fieldhand-web-37zk72cqha-uc.a.run.app
Code: https://github.com/OJ-IRO/fieldhand

Top comments (0)