Inspiration
We are members of the AMR Club at Soroti University. Through our work and engagement with communities, we came to understand that antimicrobial resistance (AMR) is not just a medical problem — it is a growing threat to people, animals, food systems, and our communities. Globally, bacterial AMR was directly responsible for an estimated 1.27 million deaths in 2019, and was associated with nearly 5 million deaths overall. One of the major drivers is the inappropriate use of antimicrobials across human health, animal health, and agriculture — antibiotics prescribed when they shouldn't be, courses stopped early, and antibiotics fed to livestock without oversight. This led us to a simple question: what if people could access reliable guidance on antibiotic use even where there is no internet? That is why we built OneAMR — an offline AI assistant designed to help Ugandan health workers, patients, and farmers make better decisions about antibiotic use, directly from a laptop, with no internet connection required.
What it does
OneAMR is an offline antimicrobial-stewardship assistant that talks to three different audiences in three different registers:
- Health workers get fast, guideline-grounded answers on whether an antibiotic is indicated, which one, at what AWaRe tier, dose, and duration — every fact traceable to a real source and page.
- Patients get plain-language education on adherence, why a prescriber might withhold antibiotics, and the real risks of sharing or splitting a course — without ever being handed a dose or drug name to self-manage.
- Farmers get guidance on livestock antibiotic use — prophylactic
feed-dosing, mastitis, and withdrawal periods — grounded in the same
stewardship logic, because resistant organisms don't respect the line
between human and animal medicine.
It runs entirely on-device via
llama.cpp, with no network connection required at inference time, and every clinical fact it uses can be traced back to a specific page in the WHO AWaRe antibiotic book, the WHO IMCI chart booklet, the WHO Pocket Book of Hospital Care for Children, or the Uganda Clinical Guidelines 2023.---
How we built it
- Base model: Qwen2.5-3B-Instruct, quantized to GGUF (Q4_K_M), chosen to fit comfortably under the challenge's 7GB memory ceiling with real headroom to spare.
- Grounding via retrieval, not fine-tuning. Rather than fine-tune on a rushed, unverified dataset, we built a lightweight offline BM25 retrieval index over four source documents. Each answer's clinical facts are retrieved at query time and cited by source and page, so what the model says is traceable to something we can check — not invented.
- Audience-tagged retrieval. Two of our four sources are paediatric-only; two are general. We tag each source accordingly and filter retrieval by detected patient audience (adult vs. child cues in the query), so an adult case doesn't get answered with paediatric guidance.
- Three system-prompt personas (health worker, patient, farmer) share the same base model and retrieval index, switching register and what information is safe to surface (e.g. patients never receive a specific dose to self-administer).
- Streamlit based User Interface for easy interaction with the system,
- Prefix caching. The three personas' system prompts are fixed and reused on every query. We precompute and persist each persona's KV-cache state to disk after processing its system prompt once, so a fresh process doesn't have to reprocess that fixed prefix from scratch every time.
- A runtime config sweep, honestly reported. We benchmarked
n_threadsandn_batchcombinations directly through the actualllama-cpp-pythonruntimeapp.pyuses, constrained to the challenge's 4-core target hardware. The sweep confirmed our chosen configuration was already near-optimal (7.05-7.08 tok/s across several verified runs) and, more usefully, ruled out a configuration that would have been roughly half the speed (3.51 tok/s) had we guessed differently — a real result even though it wasn't a dramatic throughput win. - Verified against a real memory constraint, not just the dev machine's specs: we ran the full profiler inside a Linux cgroup capped at 7GB to confirm zero out-of-memory events, rather than trusting that our dev machine's larger RAM meant we were safe.
Challenges we ran into
The most important one: during our own testing, we found that
retrieval could silently pull the wrong-audience source. An adult
watery-diarrhoea query — a presentation that should get "no antibiotic,
ORS and zinc" — retrieved paediatric dysentery guidance instead, and the
model followed it into recommending an antibiotic that wasn't warranted.
We caught this because we tested our actual headline claim end-to-end
rather than trusting the architecture to be correct by construction, and
fixed it with audience-aware retrieval filtering plus an explicit
instruction for the model to check a retrieved passage's age group and
clinical picture against the patient described before using it.
A related lesson: our first attempt at fixing that bug over-corrected —
we added a specific fact about diarrhoea management to the prompt, and
the model started applying "no antibiotic → ORS and zinc" as a generic
template to unrelated presentations like a common cold. The fix was to
teach the principle (match symptomatic management to the actual
presentation) rather than patch a single case with a hardcoded fact.
We also hit an early, unglamorous challenge that ate real time:
getting a reliable, versioned WSL/Linux dev environment set up at all —
DNS resolution failures, a Docker-only WSL distro with no package
manager, and a Windows-filesystem limitation that silently broke Python's
venv. None of that is domain-specific, but it's a real part of what
"building for a laptop-constrained environment" actually involves.
Two more findings surfaced in later testing rounds, both worth mentioning because they're the same underlying lesson showing up twice. First, the audience-mismatch bug recurred in a different form after we thought it was fixed: a mistagged passage let a paediatric-specific dosing detail leak into an adult diarrhoea answer. Second, when we specifically tested whether the assistant holds its position under simulated patient pressure ("just give me something to be safe"), an early version caved — not by naming an antibiotic, but by fabricating an ungrounded loperamide recommendation with a specific dose, which is a softer version of the same fabrication risk. Both were fixed with more precise instructions (restricting retrieval fallback to general-audience sources only, and an explicit anti-fabrication guard plus required danger-sign language), and both were re-verified before we stopped.
Accomplishments that we're proud of
- Catching and fixing a genuine, dangerous retrieval failure through our own testing before it could reach a judge, and documenting it honestly rather than hiding it.
- Verifying our memory footprint against an actual enforced 7GB constraint (via cgroups), not just assuming our numbers would transfer safely to the evaluation hardware.
- Building a stewardship assistant that reliably tells the difference between "antibiotic indicated" and "antibiotic not indicated" — the single hardest and most consequential judgment in outpatient antimicrobial care — and holds that judgment even under simulated pushback from a patient.
- Extending the same stewardship logic across the human/animal boundary, with an assistant that explicitly declines to fabricate a farm-specific number it doesn't have, rather than guessing.
What we learned
- Retrieval-augmented grounding is only as trustworthy as its awareness of who a source document is written for — a keyword-matching retriever has no innate concept of "this is a children's manual."
- A small model given a single hardcoded fact will over-generalize it into a template; teaching a principle with scoped examples is more robust than patching one failure case directly.
- The gap between "runs without an error" and "gives the clinically correct answer" is exactly where testing has to focus — every real bug we found (four in total, across retrieval and prompting) passed silently until we tested the specific case that mattered, and none would have shown up from just confirming the pipeline executed without an exception.
What's next for OneAMR
- A small, hand-verified instruction-tuning dataset (rather than a rushed, unverified one) to improve reasoning consistency beyond what retrieval alone provides, particularly for numeric tasks like weight-based dosing.
- Expanding the agricultural/One Health grounding with Uganda's National Action Plan on AMR and, where available, verified regional withdrawal- period data, rather than relying solely on the model's deferral behaviour.
- Broader language support for Luganda and other locally spoken languages, given the target users often work in settings where English isn't the first language of daily use.
Log in or sign up for Devpost to join the conversation.