01 · AI Municipal CRM
MuniGo
An AI municipal call-center and CRM. It answers citizen calls, classifies and routes complaints to the right department, tracks every case to resolution, and reports the KPIs municipal management actually asks for, live across two municipalities.
Municipal call centers drown in repeat calls about the same potholes.
A mid-size municipality fields thousands of calls a month: broken streetlights, overflowing bins, water leaks, noise complaints. Each one has to be heard, classified, routed to one of dozens of departments, tracked until closed, and reported on. Most of that workload was manual: an operator listening, typing notes, guessing which department owns it, and a spreadsheet standing in for a case system.
The cost showed up twice: citizens waited longer for a human, and management had no real-time view of what was actually happening across departments.
A voice-first intake layer, a routing brain, and a CRM the departments actually use.
As co-founder and lead developer I built the Django backend, the PostgreSQL data model for complaints, departments and cases, the GPT-based intake pipeline, and the AWS Polly voice layer, then optimized all three for production load across two municipalities.
- Voice intake. Calls are transcribed and the request classified into one of 300+ complaint subcategories across 20+ departments.
- Routing & case tracking. Each classified complaint becomes a tracked case, assigned to the owning department with a priority and SLA.
- Follow-up & notification. Citizens receive status updates by email as their case moves through resolution.
- KPI dashboards. Department leads and management see live volumes, response times and resolution rates per category.
Two production bottlenecks, two deliberate fixes.
The first version worked, but felt slow and cost more than it should at scale. Both problems were in the voice pipeline, and both had a concrete, measurable fix.
Response latency: 7s → 1.5s
The original request path made sequential model calls before producing any audio. I restructured the pipeline to start synthesis as soon as the first usable text chunk was ready, cutting the time-to-first-audio from ~7 seconds to ~1.5 seconds, the difference between a call that feels broken and one that feels instant.
TTS cost: −80%
AWS Polly was billed per character synthesized, and the same prompts (menu options, confirmations, department names) were being re-synthesized on every call. I introduced a cached + batched synthesis pipeline with voice reuse for repeated phrases, cutting Polly spend by roughly 80% with no audible quality loss.
Classification & routing
Incoming requests are classified against a taxonomy of 300+ subcategories mapped to 20+ departments, each with its own priority and SLA, so every case lands on the right desk without a human triage step.
The routing layer, running in your browser.
A small, keyword-based re-implementation of MuniGo's classifier. Describe a complaint in Turkish (the language MuniGo operates in) and see which department it lands on, with what priority and SLA, and the words that drove the decision.
What changed.
What I'd build next.
- Confidence-based escalation. Low-confidence classifications route to a human reviewer instead of a best guess.
- Cross-department SLA dashboard. Surface bottlenecked departments before complaints pile up, not after.
- Multilingual intake. Extend the voice pipeline beyond Turkish for mixed-language municipalities.