Skip to content
Back to all work
AI Systems2026

AI Call Analysis

Upload call recordings, get transcripts, scores against your own quality rubric, and a report — with a transcription chain that degrades instead of failing.

Role
Architect & sole engineer
FastAPIPython 3.11Whisperfaster-whisperNext.js 14TypeScriptRecharts

The application

Screens, captured from the running app

Booted against its seeded database and walked route by route — these are the real pages, not mockups.

Call analysis dashboard with call volume, minutes and a quality breakdown by flag.
The dashboard leads with the flag split — error-free, deficient, critical — rather than an average score, because the average hides the calls worth listening to.
Filterable call evaluation table with per-call score, sentiment and flag.
Every evaluated call, filterable, drilling into transcript and per-parameter scoring.
Configurable quality parameters grouped by category with weights.
The rubric is data, not a prompt. The person who owns quality standards can change them without touching the model.
Agent management screen listing agents and their evaluated call counts.
Agents, so scores aggregate to a person rather than floating free.
Call analysis reporting view with time-series quality trends.
Quality over time — the thing a sampling-based QA process could never produce.

The problem

Contact-centre QA is a sampling exercise. A supervisor listens to five calls out of four hundred, scores them on a paper rubric, and extrapolates. The sample is small, the rubric is applied inconsistently between supervisors, and nothing about it produces a trend you could act on.

The interesting part of automating it is not the transcription. It is making the scoring defensible enough that an agent will accept it.

The transcription chain

Three tiers, tried in order:

  1. OpenAI Whisper (whisper-1) when a key is configured.
  2. Local faster-whisper when it isn't, or when the API call fails.
  3. A mock transcript when neither is available.

Each result records which tier produced it. That last tier exists so the entire system — upload, queue, evaluation, analytics, export — runs end to end on a laptop with no credentials and no GPU, which is the difference between a project someone can actually look at and one that needs an onboarding call.

Scoring against parameters, not a prompt

Quality parameters are database records grouped by category — Greetings, Call Handling, Service Attitude, Closing, Compliance — each with its own weight. The model is asked to judge a call against those parameters, and returns a per-parameter verdict rather than a single number.

That matters for two reasons. The score decomposes, so an agent disputing a 62 can see it came from a compliance miss rather than a vague tone judgement. And the rubric is editable by the person who owns the rubric, without touching a prompt.

There is a heuristic offline evaluator behind the same interface — keyword and structure based, obviously cruder — so the pipeline still produces scores when no model is reachable.

Flags over averages

Each call carries a flag: error-free, deficient, critical, or auto. Averaging call scores hides exactly the calls worth listening to; the current seed sits at 45 calls with 24 critical, and the dashboard leads with that split rather than with a mean.

The rest of it

An async upload-to-analytics pipeline with retry and per-call status tracking; a filterable evaluation table drilling into transcript and per-parameter scoring; agent management; time-series reporting in Recharts; CSV export and PDF transcript download. FastAPI and SQLAlchemy on the backend, Next.js 14 and TypeScript on the front, containerised with docker-compose.

You have a process thatshould be a system.

Tell me what arrives, who has to act on it, and where it currently falls over. That conversation is usually enough to scope the build.