Photo-in, diagnosis-out crop disease pipeline for Zimbabwe. Two-stage retrieval over a 281-condition knowledge base, Claude vision + reasoning. Zero-dependency BM25 core.
# zimkb — wiring the Zimbabwe crop disease KB to Claude
A small Python package that turns the knowledge base into a working photo-in, diagnosis-out pipeline. The core retrieval has **zero dependencies** and runs offline; only the Claude calls need the network.
```bash
pip install anthropic # only needed for the diagnosis half
export ANTHROPIC_API_KEY=sk-ant-...
export ZIMKB_ROOT=./zimbabwe-crop-disease-kb
python -m zimkb stats
python -m zimkb search "grey rectangular lesions between the veins on lower leaves" --crop maize
python -m zimkb diagnose photo.jpg --crop maize
```
```python
from zimkb import Diagnoser
dx = Diagnoser()
result = dx.diagnose_image("leaf.jpg", crop="maize",
farmer_context="Pfumvudza plot, Mashonaland East, planted late November")
print(result["farmer_message"])
```
## About the knowledge base this reads
`zimkb` is the retrieval and diagnosis layer. The corpus it reads is a separate artifact and is
**not included in this repository**.
The knowledge base is 281 condition records across five crops — tobacco 65, bean 65, maize 58,
wheat 49, sorghum 44 — pre-chunked into 1,850 passages. The category mix is a deliberate design
decision rather than an accident of sourcing: disease 138, insect pest 55, **nutrient deficiency 45,
abiotic disorder 33**, storage pest 6, parasitic weed 2, vertebrate pest 2. A third of it is not a
pathogen at all, because a third of the wrong answers a vision model gives are pathogens that were
really hunger, drought, frost, herbicide drift or lightning.
Each record carries a forensic `visual_diagnosis` (lesion geometry, colour zoning, size in
millimetres, margins and halos, texture, leaf surface, canopy position, distribution, progression),
a `diagnostic_field_test`, a `look_alikes` differential layer, `vision_tags` and
`farmer_query_phrases` for retrieval, `management` split into a chemical path and a smallholder
path, `what_not_to_do`, a `safety` block, and a per-record `confidence` flag for where the
un …