Skip to content

siddhit/khet-saathi-bot

Repository files navigation

AgriPulse logo

Khet Saathi bot

A multilingual WhatsApp farm advisor, built with the Claude API and running in a live pilot on a real onion, cotton, and groundnut farm in Saurashtra, Gujarat.

📺 Build-in-public video series · 💼 LinkedIn


Khet-Saathi (खेत साथी) means "farm companion." Farm supervisors message a WhatsApp number in Gujarati, Hindi, or English and get practical agronomy advice back in the same language — crop disease diagnosis, irrigation and harvest timing, spray recommendations — grounded in the crops and climate of the Mahuva region.

This is not a demo with mock data. It runs on a working farm, and the design decisions in this repo (and the video series documenting them) come from real messages sent by real supervisors standing in real fields.

How it works

Every message goes through a fast classifier, then routes to the agent best suited to answer it:

flowchart TD
    WA[WhatsApp message] --> WH[Vercel webhook]
    WH --> C{Classifier<br/>Claude Haiku}
    C -->|greeting / off-topic| Canned[Canned reply]
    C -->|crop_disease| D[Diagnosis agent<br/>Claude Haiku, structured JSON]
    C -->|farm_strategy| S[Strategy agent<br/>Claude Sonnet + weather tool]
    D --> R{Independent reviewer<br/>second Haiku pass}
    R -->|high severity + concern| E[Escalate to human<br/>Kisan Call Centre]
    R -->|otherwise| F[Formatted WhatsApp reply]
    S --> W[wttr.in weather lookup]
    W --> F
    D -.->|diagnosis persisted| KV[(Upstash Redis<br/>24h conversation + farm state)]
    KV -.->|context injected| S
Loading

The interesting parts:

  • Two agents, two contracts. The diagnosis agent answers in strict JSON (validated, with a one-shot retry on malformed output) so replies can be formatted consistently for WhatsApp. The strategy agent answers conversationally and can call a weather tool when timing depends on current conditions.
  • An independent reviewer. Every diagnosis gets a second, context-free review pass by a separate model call. A high-severity diagnosis that the reviewer flags doesn't get treatment advice — it gets escalated to a human agronomist instead. An AI that recommends the wrong pesticide dose is worse than no AI.
  • Cross-agent memory. Diagnoses are persisted to Upstash Redis (REST API — no TCP sockets in serverless) and injected into the strategy agent's context, so "should I harvest early?" is answered with knowledge of last week's purple blotch diagnosis.
  • Language detection without a language model. Unicode script counting picks Gujarati vs. Hindi vs. English in microseconds; the reply language is injected into the system prompt.
  • Serverless-honest webhook handling. Meta retries on any non-200, so the handler is built to always return 200 — every processing path is wrapped so a Claude API hiccup never becomes a webhook retry storm.

Tech stack

Layer Choice
Messaging WhatsApp Business Platform (Meta Graph API webhooks)
Compute Vercel Python serverless functions
AI Claude Haiku 4.5 (classification, diagnosis, review) + Claude Sonnet 4.6 (strategy, tool use)
Memory Upstash Redis via REST (24h expiring conversation history, farm state, farmer profile)
Weather wttr.in

Repo layout

api/webhook.py        # Entire bot: webhook handler, classifier, both agents, reviewer, escalation
test_classifier.py    # Live classification accuracy suite (10 labelled cases incl. edge cases)
test_escalation.py    # Pure-logic tests for the escalation decision
eval_strategy.py      # Model-graded eval: Sonnet answers, Haiku grades against a rubric
public/privacy.html   # Privacy policy for the pilot
branding/             # Logo + design philosophy
vercel.json           # Routes /webhook → /api/webhook

Running it yourself

You'll need a Meta WhatsApp Business app, an Anthropic API key, and an Upstash Redis database.

  1. Set environment variables (in Vercel's dashboard, or .env.local for local dev — never committed):

    Variable Purpose
    WHATSAPP_VERIFY_TOKEN Webhook verification handshake with Meta
    WHATSAPP_ACCESS_TOKEN Graph API bearer token
    WHATSAPP_PHONE_NUMBER_ID WhatsApp Business phone number ID
    ANTHROPIC_API_KEY Claude API
    KV_REST_API_URL / KV_REST_API_TOKEN Upstash Redis REST credentials
  2. Run locally and expose to Meta:

    vercel dev          # localhost:3000
    ngrok http 3000     # register the https URL + /webhook in Meta's console
  3. Push to main — Vercel deploys automatically.

Tests & evals

python test_escalation.py    # Pure logic, no API calls
python test_classifier.py    # Live classifier accuracy (needs env vars)
python eval_strategy.py      # Model-graded quality eval (needs env vars)

The eval uses a second model as grader with a per-question rubric and prefilled-JSON output — a small taste of LLM-as-judge in ~80 lines.

The story behind it

This bot advises supervisors on my dad's farm. I'm building it in public — every architecture decision, mistake, and fix is recorded as a video:

The bot is in a private pilot and not open to the public. See the privacy policy for what data is collected and how it's used.

Roadmap

  • Async processing (enqueue → 200 → process) once response latency outgrows the synchronous window
  • Webhook signature validation (X-Hub-Signature-256)
  • Photo diagnosis — supervisors already send crop photos; the bot should read them
  • Voice notes in Gujarati
  • Possible migration to Telegram to support groups

Releases

Packages

Contributors

Languages