# What 10 University Visits in Cameroon Taught Me About Building AI for the Real World, and Why Gemma 4 Was the Answer

> Source: <https://dev.to/rosius_ndimofor_a6fdb4ebb/educloud-a-fully-offline-ai-study-assistant-powered-by-gemma-4-e2b-mg1>
> Published: 2026-05-21 19:59:35+00:00

This is a submission for the Gemma 4 Challenge: Build with Gemma 4
I run Educloud Academy, a learning platform focused on cloud and AI skills for African students. Over the last year my team and I have done university outreach across 10 Cameroonian universities ,including my own alma mater, the University of Buea, running on-the-ground sessions on how to break into cloud and AI careers.
Outreach evidence (LinkedIn):
(Photos from these sessions attached below this post.)
Two problems kept showing up at every single campus, no matter the topic:
EduCloud (the app) is my answer to both. It's a fully offline, on-device AI study assistant that turns a learner's own PDFs, textbooks, and lecture screenshots into interactive study materials — multiple-choice quizzes, flashcards, multi-lesson workshops, mind maps, and summaries — without a single byte ever leaving the device. Because Gemma 4 is genuinely multilingual, the same binary that serves an English-speaking student in Yaoundé serves a French-speaking student in Douala without an extra translation hop.
ultraLean / lean / balanced / full
) and adjusts token budgets, RAG context size, and max question count so it runs cleanly on the iPhone 13 Pro Max I tested on as well as on lower-end mid-range Androids that students actually own.Everything is built in Flutter + Dart, with native Gemma 4 inference via the flutter_gemma
plugin (LiteRT-LM under the hood), and persistence via ObjectBox. iOS, Android, macOS, Linux, and Windows are all supported from one codebase — important because campus device fleets aren't uniform.
Watch the walkthrough on YouTube: https://youtu.be/dVYz8xq2L_8
Full source: https://github.com/trey-rosius/Local-Educational-App
Key directories to explore:
lib/services/educational_tool_service.dart
— all 8 function-call schemas (quiz, flashcards, workshop, plus 5 interactive tutor tools).lib/services/study_material_service.dart
— generation entry points + the JSON repair pipeline + semantic validators.lib/services/rag_service.dart
— PDF/image ingestion, batched embedding, HNSW search.lib/services/background_generation_service.dart
— the non-blocking task queue that branches between tool-call and text-mode paths.architecture.excalidraw
— full visual architecture diagram (open at https://excalidraw.com).README.md
— complete feature + architecture + failure-mode documentation.Model chosen: Gemma 4 E2B (.task
).
E2B was the only viable choice for a truly on-device application of this scope:
E2B hits the sweet spot for what EduCloud needs:
Message.withImage(...)
— critical for the "snap a textbook page" feature.ToolChoice.required
+ a Tool
schema, structured generation is guaranteed valid — no JSON parsing failures possible. Before migrating to tool calling I had to maintain a ~700-line state-aware JSON repair pipeline to handle every quirk the model produced (asymmetric quotes, missing braces, Python-style single quotes, \X
escapes outside strings, 0.0
as answerIndex
instead of 0
, citation paste-throughs…). After the tool-calling migration, that pipeline is now a fallback that almost never fires.How Gemma 4 is wired into the app, end to end:
flutter_gemma
's Embedder.generateEmbeddings(List<String>)
batch API. Ingestion runs ~10× faster than per-chunk thanks to batching.Float32List(512)
embeddings in ObjectBox.model.createChat(supportsFunctionCalls: true, tools: [...], toolChoice: ToolChoice.required)
returns a FunctionCallResponse
with already-parsed Map<String, dynamic>
args. The runtime constrains generation at the token level.chat.generateChatResponseAsync()
so the user sees Markdown materialize in real time.Message.withImage
with the same Gemma 4 model — no separate OCR engine needed.chat.close()
after each generation releases the KV cache; the model is reused as a singleton across tasks (closing it triggers a native double-free at the LiteRT layer).The most valuable Gemma 4 feature for a project like this was tool calling. Pre-Gemma-4 on-device LLMs would emit free-form JSON that I'd have to regex-and-state-machine my way through. With function calling, structured output is guaranteed — which is what made the offline study-material generation feel as reliable as a cloud product.
Sampling tuned for this app: temperature: 0.3, topK: 40, topP: 0.95
for tool calling (Gemma's published guidance for structured outputs — greedy decoding temp~0, topK=1
is prone to short repetition loops on long structured responses).
The next time I walk onto a Cameroonian campus to talk about cloud and AI careers, I won't have to caveat the AI portion of the talk with "…of course you'll need stable internet and an English-fluent prompt." I can hand a student a Gemma-4-powered app, watch them point it at their own French-language course PDF, and watch them get a quiz in French, generated on-device, with no data plan involved.
That's the bar for AI tools that actually work for the next billion learners — and that's the bar Gemma 4 cleared.
Built with Flutter, Dart, flutter_gemma
, ObjectBox, LiteRT-LM, and a healthy disregard for cloud dependencies.
Follow me on LinkedIn or check out EduCloud Academy for what comes next.
