`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.
- `leaf-diseases-detect` treats plant diagnosis as a guarded triage flow, not a simple image classifier.
- The repo’s main trick is a prompt that forces the model to reject non-leaf images before it is allowed to diagnose anything.
- A strict JSON response turns multimodal inference into UI-ready data for symptoms, cause, and treatment.
- The architecture favors fast iteration and flexible guidance over the rigidity of a custom-trained CNN pipeline.
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 labels | Uses a vision LLM with a prompt and schema |
| Returns mostly a disease class | Returns leaf check, symptoms, cause, and treatment |
| Harder to iterate without retraining | Faster to change through prompt and output design |
| Strong when the dataset is clean and stable | Stronger when inputs are messy and the output must be structured |
| Usually tied to a model-training pipeline | Fits 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.
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.
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-minded | What still reads as prototype |
|---|---|
| Clear separation between UI, API, and model logic | No visible history store or longitudinal patient record |
| Prompted structured output for rendering | Limited evidence of hard validation beyond the prompt |
| In-memory file handling | No obvious persistence or audit layer |
| Config-driven deployment | A 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.