Draw a field. Ask a question. See why.
Draw the boundary on a map or import GeoJSON, fetch weather and Sentinel-2, and ask in plain English. Every input shows its origin, age and reliability.
Open research software · MIT · Python 3.9+
SmartAgri answers a farmer’s question about one maize field. Before a word is written, explicit rules decide whether it may recommend, recommend on a condition, ask one follow-up question, or abstain.
Four possible acts
The policy layer picks one act from the data that are actually available and how reliable they are. A language model, if one is configured, only phrases that act.
The inputs this type of advice needs are present and reliable enough. A quantity is given only when the rules allow it.
The answer hinges on one missing fact. Each possible value of that fact gets its own consequence.
One follow-up question, chosen because its answer would change the decision, with a tip on how to check it in the field.
No recommendation, and the reason why. Questions outside the scope, or without support in the corpus, are referred to the extension service.
Features
Draw the boundary on a map or import GeoJSON, fetch weather and Sentinel-2, and ask in plain English. Every input shows its origin, age and reliability.
The same client, responsive, with light and dark themes and keyboard drawing.
Crop water use, the water balance and irrigation doses come from tested FAO-56 functions, never from the language model.
ETc = Kc × ET0
Each answer stores its configuration, corpus and prompt hashes, the decision date, and the satellite and forecast dates it used.
SQLite and a deterministic template generator by default. No keys, no model and no network access to one.
Answers are in English. Set SMARTAGRI_LOCALE=sr-Latn for the local language. Sources stay in their original language.
How it works
Each layer is plain code with its own tests and configuration file. Every answer keeps each layer’s decision, so “Why?” has a concrete answer.
The parcel, its agronomic inputs, Open-Meteo weather and Sentinel-2 L2A NDVI, each with its date.
A deterministic filter over passage metadata: crop, growth stage, region, date and source type. No hidden model.
Origin, age, coverage and reliability of every input. Missing inputs are listed, never filled in.
Whether the inputs are enough for the type of advice asked for, and which are missing.
A missing input whose answer would change the decision, weighed against the effort of answering it.
The act: recommend, conditional, ask or abstain, with a reason code and whether a quantity is allowed.
Checks the answer: numbers must come from the tools, and sentences must be supported by the cited passages.
Interfaces
The web app and the research API share one service. The evaluation harness calls the decision pipeline directly, so its results never depend on the web layer.
http://127.0.0.1:8100SMARTAGRI_LOCALEFastAPI, bound to 127.0.0.1 and without accounts by default. The OpenAPI schema is at /docs. For a public server, SMARTAGRI_ACCOUNTS=optional adds optional email accounts: anyone can try it, and a parcel is saved once you create an account.
python -m smartagri.research_api --port 8100
curl -s localhost:8100/api/health
curl -s -X POST localhost:8100/api/parcels \
-H 'Content-Type: application/json' \
-d @parcel.json # name, sowing_date, geometry
curl -s -X POST localhost:8100/api/parcels/$ID/profile/refresh
curl -s -X POST localhost:8100/api/parcels/$ID/chat \
-H 'Content-Type: application/json' \
-d '{"text": "When should I irrigate?", "variant": "V5"}'
run scenario sets under one or more variantsreport automatic and rated measures, paired comparisonsguard n-gram leakage check between scenarios and corpuslock sha256 of scenarios, corpus, config, prompts and rater guideexport and sweep for items, ratings and synthetic variationscd backend
python -m smartagri.evalkit run --set dev
python -m smartagri.evalkit report
python -m smartagri.evalkit report --compare V4 V3
python -m smartagri.evalkit guard --set dev
Evaluation and reproducibility
The repository holds the method and the harness. This page reports no results.
Each variant adds to the one before, so a paired comparison such as V4 against V3 isolates what those layers change. A free LLM conversation with the same data and passages (VC) is a baseline outside the ladder.
Raters score items on a five-criterion rubric with critical-error classes. They never see the variant, generator or model, and each rater gets a fixed item order.
Before measurement, a lock file records the sha256 of the scenarios, corpus, configuration, prompts and rater guide. Held-out test scenarios are published only after the lock.
Limitations
SMARTAGRI_LOCALE=sr-Latn switches them to the local language (Serbian, Latin script). The published development corpus consists of short paraphrases in Serbian, so source titles and excerpts appear in Serbian. The blind rating screen follows the rater guide and stays in the local language.Get started
Python 3.9 or newer. SQLite and offline mode by default; Docker is not required.
git clone https://github.com/ZeljkoDzafic/smartagri-core.git
cd smartagri-core/backend
python3 -m venv .venv && . .venv/bin/activate
pip install -c constraints-py39.txt -e ".[dev,api]"
pytest -q
python -m smartagri.research_api # http://127.0.0.1:8100
On Python 3.12, use -c requirements.lock. On Windows, create the environment with py -m venv .venv and run .venv\Scripts\python.exe. Optional settings are listed in .env.example: SMARTAGRI_LOCALE sets the answer language, and SMARTAGRI_TILE_URL sets another tile server (none turns tiles off).