Automatic quality evaluation system for call center recordings. Transcribes audio with Whisper, analyzes agent performance with Gemini 2.5 Flash, and displays KPIs on an interactive Streamlit dashboard.
Built as a technical challenge for a real QA use case in a Colombian telecom company (Claro Colombia context).
- Transcribes
.wav/.mp3call recordings using OpenAI Whisper (local, no API cost) - Analyzes each call with Gemini 2.5 Flash using a structured prompt that evaluates:
- Formality (greeting, farewell, wait-time communication, plain language)
- Solution quality (problem clarity, resolution clarity)
- Protocol compliance (diagnostic questions, escalation, data offers, satisfaction survey)
- Call handling (wait times with timestamps, who ends the call)
- Generates a structured JSON with scores, wait-time breakdown, and a call summary
- Displays an interactive dashboard with KPIs, charts, and per-call drill-down
| Tab | Content |
|---|---|
| Real-Time Analysis | Upload audio → transcribe → analyze → instant results |
| KPI Dashboard | Overall quality %, compliance by category, top 5 protocol failures, duration histogram |
| Detailed Data | Filterable table with color-coded scores per call |
| Transcriptions | Full-text search across all stored transcriptions |
KPI logic: A call passes quality if it meets 3 out of 4 categories (Formality, Solution, Protocol, Handling).
Audio (.wav/.mp3)
│
▼
┌─────────────────┐
│ Whisper (local) │ ← transcription + timestamps
└────────┬────────┘
│
▼
┌─────────────────────┐
│ Gemini 2.5 Flash │ ← structured JSON analysis
│ (google-genai SDK) │ thinking_budget=0 for speed
└────────┬────────────┘
│
▼
┌─────────────────────┐
│ consolidado.json │ ← persistent storage
└────────┬────────────┘
│
▼
┌─────────────────────┐
│ Streamlit Dashboard│ ← KPIs + charts + filters
└─────────────────────┘
Modules:
| File | Responsibility |
|---|---|
app.py |
Streamlit UI — all tabs and visualizations |
batch_processor.py |
CLI tool — process a full folder of audio files |
src/audio_processing.py |
Whisper transcription + Gemini analysis + file I/O |
src/kpi_calculator.py |
KPICalculator class — all KPI logic separated from UI |
src/transcription_reader.py |
Read, search, and export stored transcriptions |
src/utils.py |
Date utilities for the consolidated JSON |
git clone https://github.com/TheBarrelExploit/call-quality-analyzer.git
cd call-quality-analyzer
python -m venv .venv
source .venv/bin/activate # Linux/Mac
# .venv\Scripts\activate # Windows
pip install -r requirements.txtGPU acceleration (optional): Install
requirements-gpu.txtfirst for faster Whisper transcription on NVIDIA GPUs.
cp .env.example .env
# Edit .env and add your Gemini API keyGet your free Gemini API key at aistudio.google.com.
streamlit run app.pyOpen http://localhost:8501 in your browser.
Process an entire folder of recordings without the UI:
python batch_processor.py \
--input ./recordings \
--output_txt ./data/transcripcion \
--output_json ./data/respuesta_ia| Argument | Description |
|---|---|
--input |
Folder with .wav or .mp3 files |
--output_txt |
Where to save transcription .txt files |
--output_json |
Where to save the consolidated JSON |
--api_key |
Optional — overrides the .env key |
Edit .env to configure:
GEMINI_API_KEY=your_key_here
GEMINI_MODEL_NAME=gemini-2.5-flash # or gemini-2.0-flash for lower cost
WHISPER_MODEL=small # tiny | base | small | medium | largeWhisper model tradeoffs:
| Model | Speed | Accuracy | VRAM |
|---|---|---|---|
tiny |
Fastest | Lower | ~1 GB |
small |
Fast | Good | ~2 GB |
medium |
Moderate | Better | ~5 GB |
large |
Slow | Best | ~10 GB |
call-quality-analyzer/
├── app.py # Streamlit dashboard (entry point)
├── batch_processor.py # CLI tool — process a folder of audios
├── requirements.txt # Core dependencies
├── requirements-gpu.txt # Optional GPU dependencies
├── .env.example # Environment variables template
├── src/ # Core package
│ ├── __init__.py
│ ├── audio_processing.py # Whisper transcription + Gemini analysis
│ ├── kpi_calculator.py # KPICalculator class — all KPI logic
│ ├── transcription_reader.py # Read, search and export transcriptions
│ └── utils.py # Date utilities for the JSON consolidado
└── data/ # Auto-created at runtime (git-ignored)
├── transcripcion/ # .txt transcriptions per call
└── respuesta_ia/ # response_consolidate.json
The analysis prompt is one of the most important parts of this project. Key design decisions:
- Thinking disabled (
thinking_budget=0) — reduces latency for real-time use - Timestamp-aware wait detection — uses Whisper segments to detect silent gaps >15s and evaluate whether the agent communicated the hold
- Role disambiguation — explicit rules to distinguish agent vs. customer even in ambiguous transcriptions
- Strict JSON output — no markdown fences, no explanations, directly parseable
| Layer | Technology |
|---|---|
| Transcription | OpenAI Whisper (local) |
| LLM Analysis | Google Gemini 2.5 Flash |
| Dashboard | Streamlit + Plotly |
| Data | Pandas + JSON |
| Config | python-dotenv |
Each analyzed call produces a JSON record:
{
"nombre_archivo": "call_001.wav",
"fecha_procesamiento": "2025-08-29T09:11:45",
"duracion_llamada_segundos": 393.04,
"evaluacion_formalidad": {
"saludo_formal": true,
"despedida_formal": true,
"informa_espera": true,
"lenguaje_sencillo": true
},
"evaluacion_solucion": { "claridad_falla": true, "claridad_solucion": true },
"evaluacion_protocolo": {
"preguntas_diagnostico": true,
"informa_escalacion": true,
"oferta_paquete_datos": false,
"ofrece_encuesta": false
},
"evaluacion_manejo": {
"tiempos_espera": [
{ "inicio_espera_segundos": 136.0, "duracion_espera_segundos": 172.0,
"fue_informado": true, "fue_adecuado": true }
],
"quien_finaliza": "cliente"
},
"resumen_llamada": "..."
}MIT — free to use, modify, and distribute.
Built with Whisper + Gemini 2.5 Flash · Python 3.11+ · Streamlit