Inspiration

Uganda completes Primary Seven for less than half the children who start Primary One — 739,204 out of 1.7 million enrolled. At secondary level, only 352,929 of 508,769 students who begin Senior One make it to Senior Four. More than 40% of primary pupils and 30% of secondary students drop out before finishing. Even at Makerere University, Uganda's flagship institution, an estimated 1,000 students drop out every year, largely from economic hardship — proving this isn't only a rural primary-school problem, it follows learners all the way to university and into every cohort-based program in between: bootcamps, scholarship cohorts, vocational training, online courses.

The official story is always told after the fact — a missed exam, a failed term, a final dropout record. But by the time a dropout is recorded, the learner checked out weeks earlier, and the signs were almost always there the whole time: a question asked three times because they were too embarrassed to push for a clear answer, a message posted at 1am, a person who used to joke around in the cohort channel going quiet. None of that shows up on a dashboard. It shows up in chat.

We built Kusoma because we believe the conversation a cohort is already having, in Slack, contains the earliest and most honest signal of who is struggling — weeks before any formal system would catch it. And we built it with an explicit eye toward scale: a single bootcamp cohort is the smallest unit this can run on, but the same engine — reading informal signal, cross-referencing it against where a learner should be, and routing one specific, human, non-punitive nudge — is the seed of something that could eventually operate at the scale of a national education monitoring effort, the kind Uganda's own statistics make clear is urgently needed.

What it does

Kusoma watches a training cohort's public Slack channels (never private DMs) for five distinct kinds of struggle signal, because dropout research shows struggle isn't one thing:

  • Academic — the same question asked more than once, left unresolved
  • Overload — life and time pressure unrelated to the material itself
  • Confidence — self-doubt and comparison to peers, even while on track
  • Isolation — social disengagement, even from a learner who is academically fine
  • Withdrawal — a real drop in someone's own activity, judged against their own baseline, not the cohort average

It cross-references whatever it detects against the learner's actual curriculum position, pulled live via an MCP connection to the program's tracking sheet, so a flag is never just "this message sounds concerning" — it's "this message sounds concerning, and here's where they actually stand." When the two line up, Kusoma sends one specific, plain-language nudge: who, what kind of struggle, and who's best placed to help — a mentor for a knowledge gap, a coordinator for everything else. It also looks across the whole cohort: if several learners struggle with the same topic in the same week, it tells the coordinator the content may need revisiting, not just the individual.

It never contacts a learner directly, never escalates anything punitively, and only reads what people already chose to post in a shared channel.

How we built it

We started this hackathon somewhere very different — a lead-generation agent — and spent real time validating it before realizing the category was already commoditized (Slack's own native AI already does CRM logging and commitment tracking for free). That pushed us toward the Slack Agent for Good track, and through several more rounds of validation toward cohort dropout detection specifically, once we found that existing dropout-prediction research splits causes into several distinct categories that no single existing tool detects together.

From there: we wrote a classifier system prompt encoding all five risk categories with explicit rules for telling them apart (the hardest design problem — for example, making sure a learner who is on track academically but isolated still gets flagged, and that confidence-related self-doubt doesn't get misread as academic confusion). We built a seeded six-persona test cohort, including a deliberate "no signal" control persona, specifically to prove the system doesn't cry wolf on normal venting and banter. We designed the curriculum-tracking schema as an MCP-connected source of ground truth, and wrote the fusion and routing logic as pure, fully unit-tested functions — 20 passing tests — before wiring anything to a live Slack workspace, so we could verify the actual decision logic independent of any platform plumbing. Only after that did we scaffold the real app with slack create agent, using the Bolt for Python + Claude Agent SDK starter template, and connect it to our developer sandbox via Socket Mode.

Challenges we ran into

The hardest part wasn't the code, it was the discipline of saying no to ideas that sounded good but weren't actually new — we killed at least three earlier concepts after researching that Slack's own roadmap or an existing product already covered them, which is a humbling but necessary process for a hackathon this competitive. Technically, the trickiest design challenge was making the five risk categories genuinely distinguishable rather than overlapping mush — it's easy to build a classifier that just says "this person seems at risk," much harder to build one that correctly tells you why, since the right intervention is completely different depending on whether someone is confused, overwhelmed, doubting themselves, isolated, or withdrawing. We also had to deliberately design against the easy, more invasive version of this idea — anything that looked like surveillance of private messages or individual risk-scoring that follows a learner permanently was ruled out early, because the moment a tool like this feels punitive, it stops getting trusted, and an untrusted tool watching a vulnerable population is worse than no tool at all.

Built With

  • anthropic-api
  • claude-agent-sdk
  • google-sheets
  • mcp
  • python
  • slack-bolt
  • slack-cli
  • slack-real-time-search-api
Share this project:

Updates