Inspiration
Millions of Nigerian smallholder farmers make daily decisions about planting, pest control, and storage without reliable internet access or the money for data. Most AI farming tools assume a cloud connection and an ongoing subscription both are blockers for the exact people who'd benefit most. We wanted to build something that runs entirely on the kind of laptop already sitting in an internet café or a local agricultural extension office: no API fees, no connectivity required, just useful answers.
What it does
FarmMate is an offline, conversational farm advisor covering 10 crops beans, cassava, rice, yam, maize, tomato, groundnut, cocoa, millet, and ginger. A farmer can ask natural questions like "what pests attack rice?" or "when is yam ready for harvest?" and get a real, conversational answer grounded in a hand-compiled knowledge base, not a rigid FAQ lookup. The whole system runs locally with zero network calls at inference time.
How we built it
The knowledge base is a set of Word documents, one per crop, each broken into consistent sections (climate and soil requirements, land preparation, planting, fertilizer and manure, weed management, crop rotation, pests, pest control, harvest, and storage). At query time, the system embeds the user's question with a GGUF-quantized MiniLM embedding model running through llama.cpp, retrieves the most relevant sections by similarity, and passes them as context to a Qwen2.5-1.5B-Instruct model (also GGUF-quantized, also running through llama.cpp) with an explicit instruction to answer conversationally and never copy the source text verbatim. Both the embedder and the chat model share the same llama.cpp runtime, so there's a single dependency for all inference, no torch or cloud SDKs required at runtime.
Challenges we ran into
Getting llama-cpp-python to install and run consistently on Windows without a working C++ build toolchain was a real obstacle we ended up switching to a prebuilt CPU wheel instead of compiling from source with BLAS support, trading a little inference speed for a much simpler, more reproducible setup.
We also built and then removed a semantic caching layer. The idea was to reuse answers for questions that meant the same thing as ones already asked, to cut latency and repeated LLM calls. In practice, this backfired: once a question was cached, later edits to the dataset or retrieval logic had no effect on that cached answer, so the system was instantly serving an outdated, flawed response straight from memory instead of re-running retrieval or querying the model. Since correctness matters more than speed for farm advice, we removed the cache rather than add complexity to keep it correctly invalidated under a tight deadline.
Accomplishments that we're proud of
Getting real retrieval-grounded, conversational generation working end to end, fully offline, on a quantized 1.5B model was the core technical goal, and it works: the system correctly retrieves the right crop section for a given question and produces a natural-sounding answer instead of pasting dataset text back verbatim.
What we learned
Simpler is often more robust under a hackathon deadline the semantic cache and the BLAS build both looked like straightforward wins on paper, but each introduced failure modes (staleness, toolchain fragility) that cost more time than they saved. We also learned that keeping the whole inference stack on one runtime (llama.cpp for both embedding and generation) meaningfully simplifies dependencies compared to mixing in a separate embedding library.
What's next
Expanding the dataset beyond the current 10 crops and fixing any bugs that pop up during the expansion
Log in or sign up for Devpost to join the conversation.