`leaf-diseases-detect`: When a Plant Doctor Is Just a Prompt

How a small Python app turns a vision LLM into a leaf triage pipeline, using a strict JSON contract, an invalid-image guardrail, and a fast API wrapper around a surprisingly practical workflow.

7 min read • View on GitHub • More from krishna1012k

A wide field-scene illustration shows a tractor hood used as a desk, with a leaf notebook, a healthy leaf, and a diseased leaf laid out beside a rejected photo of a glove and phone. A diagnostic sheet hovers above the scene like a gatekeeper, showing that the system must first verify the image is a leaf before it will attempt any diagnosis.
The repo’s real idea is not disease classification. It is triage first, diagnosis second.
Key Takeaways

The real product is not diagnosis. It is triage.

Most plant-disease apps start with the label. This one starts with a refusal. The prompt tells the vision model to decide whether the upload is actually a leaf before it says anything useful, which turns the whole system into a gatekeeper rather than a classifier.

That matters because field input is messy. Farmers do not upload curated benchmark images. They upload gloves, hands, phones, shadows, partial leaves, and bad crops of bad crops. A model that diagnoses everything is worse than useless. A model that declines bad inputs is doing product work.

Why this repo chose an LLM over a custom CNN

The usual playbook for leaf disease detection is familiar: collect images, train a CNN, freeze a label set, ship predictions. That gives you speed and repeatability, but it locks the product into a fixed taxonomy. It also gives you a model that is excellent at one thing and awkward at everything around that thing.

Traditional plant classifier`leaf-diseases-detect`
Trains a custom vision model on fixed labelsUses a vision LLM with a prompt and schema
Returns mostly a disease classReturns leaf check, symptoms, cause, and treatment
Harder to iterate without retrainingFaster to change through prompt and output design
Strong when the dataset is clean and stableStronger when inputs are messy and the output must be structured
Usually tied to a model-training pipelineFits a thin orchestration and UI pipeline

That is the trade. The repo gives up the discipline of a dedicated classifier and gets back flexibility. For an app that wants to say not just what this is but what to do next, that flexibility is the point.

How the stack is split into three jobs

The codebase is cleanly separated. Streamlit handles the screen. FastAPI handles the request path. The leaf-disease logic lives in its own module, with utility code for image handling and encoding. That separation is what keeps the project feeling like an application instead of a notebook that escaped.

The app is split into a thin UI, a request layer, and a model orchestration core. The structure keeps the LLM work isolated from presentation.

Leaf Disease/
  main.py        # LLM logic and prompt construction
app.py           # FastAPI orchestration
main.py          # Streamlit frontend
utils.py         # image encoding and helpers
config.py        # environment-based settings

The interesting part is not just the folder layout. It is the way the repo keeps the model boundary narrow. The UI never has to guess what the model meant, because the model is asked to speak in a structured format from the start.

The prompt is the model’s hidden operating system

This repo’s most important file is not the one with the biggest function. It is the one that defines the prompt. The prompt is doing policy, validation, and serialization all at once. It tells the model to inspect the image, refuse if needed, and emit a machine-readable answer that the frontend can trust.

A close-up editorial illustration shows a metal press stamping a messy image into a clean JSON form. Three output channels emerge from the press as labeled-looking data shapes: symptoms, likely cause, and treatment steps. The scene explains how prompt design can turn a multimodal model into structured application data.
The prompt acts like a serialization layer. It converts visual inference into product-ready fields.

That is the hidden operating system here. The LLM is not left to improvise a paragraph. It is boxed into a contract. The output becomes easy to render, easier to validate, and much less likely to collapse into vague prose.

From upload to answer: the fastest path through the app

The API path is optimized for lightness. It accepts an upload, keeps the bytes in memory, encodes the image, sends it onward, and returns the result without introducing storage as a first-class dependency. That is a good fit for ephemeral deployment and a simple diagnostic workflow.

This is also why the app can feel responsive without pretending to be enterprise infrastructure. The stack is just enough: request in, model call out, JSON back, render it cleanly. No database, no job queue, no ceremony.

What the UI is doing that the model cannot

Streamlit is not here to wow anyone. It is here to translate structured output into something a non-technical user can act on immediately. The cards, formatting, and layout choices matter because they turn a raw machine response into a readable field report.

That split is healthy. The model handles interpretation. The interface handles comprehension. The repo works because it does not ask the model to design the experience, and it does not ask the UI to invent the answer.

What this project gets right, and what it still lacks

The strongest signal here is engineering discipline. The repository separates concerns, uses environment-based config, and treats logging and structured output seriously. That is a better foundation than the average demo app gets.

What looks production-mindedWhat still reads as prototype
Clear separation between UI, API, and model logicNo visible history store or longitudinal patient record
Prompted structured output for renderingLimited evidence of hard validation beyond the prompt
In-memory file handlingNo obvious persistence or audit layer
Config-driven deploymentA few dependencies suggest prior experimentation

The weaker signals are just as useful. They show a project that is practical, but not yet hardened. That is not a flaw. It is a stage.

Why this matters beyond plants

The broader lesson is bigger than agriculture. This repo is a compact pattern for modern AI products: accept messy input, force the model through a narrow schema, and wrap the result in a lightweight API and UI. That is how a lot of useful software will be built.

Not every domain needs a custom-trained model. Some need a reliable triage layer, fast iteration, and outputs that downstream systems can trust. `leaf-diseases-detect` makes that trade visible.