Anubha Kanwar · Socrates
AI data product · Emversity · 2024–25

Socrates

What if anyone could just ask the data — and it answered in plain English?

Two internal AI products, one name, one philosophy — make Emversity's data work for the people who need it, no SQL or statistics required. One lets the ops team query the database in English. The other diagnoses why leads convert, clustering thousands of sales calls to find the patterns nobody could see.

My Role
AI Product Intern (E2E)
Users
Internal teams + leadership
Stack
React · FastAPI · MySQL 8
AI Layer
OpenAI · PCA · K-means
01 The problem

Ops teams waited days for analysts to answer simple metrics, and sales leaders had only gut feelings about lead conversion.

02 What I did

I built two internal AI products end to end — a natural-language-to-SQL tool and a call-diagnostics engine using clustering.

03 The outcome

Post-Sales Socrates answers questions across 7 approved views instantly, always showing its generated SQL for full auditability.

Part 1 · Post-Sales
Which tutors have the best feedback scores this month?
✦  → SQL + results, instantly

A natural-language interface over 7 approved database views. The generated SQL is always shown alongside results — auditable, never a black box.

Part 2 · Pre-Sales
Why are non-converted leads from Bangalore showing low call empathy?
✦  → AI Insight Summary

A diagnostic engine over thousands of sales calls — PCA clustering, stratified sampling, and plain-English insights that explain conversion behaviour.


01
Post-Sales Socrates
Natural language → SQL, over 7 approved views
Q · 01

Why does one simple metric take three days and two people to answer?

Emversity's post-sales team — managing tutors, attendance, feedback, engagement — sat on a rich database they couldn't touch without an analyst. Every metric meant waiting days for someone to write, run, and format a SQL query. Decisions were being made on stale data.

Socrates never guesses. If the answer isn't in the seven approved views, it says so — out loud.

Post-Sales Socrates sits on top of the 7 active view tables — attendance, centres, tutors, students, feedback, video feedback, schedules — and turns a plain-English question into an executed, audited query.

User question
(plain English)
→
Interpreter Agent
reads intent
→
Intent Layer
validates vs schema
→
Semantic Layer
joins · filters · rules
→
SQL generated
(MySQL 8)
→
Results + SQL
shown to user
Layer 1The Interpreter
Reads the user's question and understands intent — what are they actually asking, which metrics matter. Outputs structured JSON the next layer consumes.
Layer 2The Intent Layer
Validates the ask against what's actually possible given the 7 tables. If a question maps to a metric that doesn't exist, it asks a clarifying follow-up rather than generating a broken query.
Layer 3The Semantic Layer
The most important part. Complete schema knowledge — every table's structure, column-level descriptions mapped to business terms, inter-table relationship rules. This is what lets "best performing tutor" resolve to tutor_rating and class_start_adherence. Without it, the LLM hallucinates columns.
Restricting the LLM to 7 approved views only.
The biggest risk in NL→SQL is hallucination — queries referencing columns that don't exist, joins that corrupt results. The semantic layer is a hard constraint: if a question needs data outside the 7 views, the system says so explicitly rather than guessing. Trade-off: some questions get "can't answer" instead of a guess
The clarification flow — ask, don't assume.
"Show me performance" without a tutor or time period triggers a follow-up question, not an assumption. A confident wrong answer is worse than an honest "I need more information" — that's how you build trust with non-technical users. Trade-off: one extra turn for vague questions
Showing the generated SQL, always.
The original plan hid the SQL and showed only results. I pushed back — the team needed to audit what the system did, not trust a black box. Showing the query let them catch errors and build confidence over time. Trade-off: a more "technical-looking" UI for non-technical users

02
Pre-Sales Socrates
Behaviour intelligence over thousands of sales calls
Q · 02

Everyone had a gut feeling about why leads weren't converting. Where was the evidence?

Thousands of calls per month. Every call had a transcript, scores across intro / pitch / objection handling / follow-up, and a known conversion outcome. Managers had intuitions — "Indiranagar has a fee objection problem" — but no systematic way to look across all of it and find the actual patterns.

"Why are Mysore leads
not converting?"
→
/ask endpoint
filters centre slice
→
Real-time PCA
on call + lead features
→
K-means clustering
(3–8 clusters)
→
Stratified sample
from each cluster
→
OpenAI →
AI Insight Summary
Q · 03

Why pilot one centre when there are twenty-five?

Rather than building across every centre at once, I scoped the pilot to Bangalore–Indiranagar — clean dataset, manageable size, known-interesting conversion patterns. The master query joins call_summary ↔ leads, applies quality filters (transcript present, duration > 1 min), and outputs call fields + aggregated 4-cut scores + lead context + a derived converted_flag.

Simple random sampling would hand the LLM a dataset dominated by short, failed calls — and the insight summary would be useless.

So sampling is stratified across four dimensions — outcome, program category, lead-age bucket, and call pattern from the 4-cut scores. Each stratum contributes proportionally, so the sample OpenAI sees is representative of the real distribution, not the most common failure mode.

"What call patterns differentiate converted vs non-converted leads in Mysore?" "Are longer calls correlated with better conversion?" "At what call stage do most leads drop off?" "Which agents have the highest call-quality scores?" "Which programs convert best?"
Q · 04

What does messy, real-world data actually break?

01
Database dying on naive queries
The first version ran SELECT * with LIKE filters on the full leads table — the Redash worker died with SIGKILL. Fixed with column selection, WHERE + LIMIT constraints, and the Indiranagar-scoped query.
02
Centre name mismatches
Filtering campus = 'Bangalore - Indiranagar' returned 0 rows — the DB stored a different format. Inspected DISTINCT values, switched to a LIKE match.
03
Call duration unit ambiguity
Seconds or minutes? Getting it wrong would corrupt the entire sampling logic. Validated it was minutes; set the quality filter accordingly.
04
UI prompts that didn't match the schema
The initial UI suggested "top products by revenue" — generating SQL against tables that didn't exist. Redesigned every example question around the actual pre-sales context: leads, calls, conversions, objection scores.
PCA + stratified sampling before the LLM, not instead of it.
The temptation was to dump raw call data into OpenAI and ask for patterns. That fails at scale — finite context, noisy transcripts, surface-level insights. Clustering first, then sampling one representative set per cluster, gives the LLM clean, diverse, structured input. Trade-off: a real ML pipeline to build and maintain
Piloting one centre before scaling to 25+.
Scoped hard to Indiranagar, got the pipeline working end-to-end, validated insight quality manually before expanding. Architecture decisions got made on real data instead of assumptions. Trade-off: no company-wide insights on day one
A manual annotation layer under the automation.
Designed a framework for hand-tagging a subset of calls across the 4 cuts. This labelled dataset is the foundation for future fine-tuning and RAG — you can't build reliable AI on data you haven't verified is correct. Trade-off: slow, human hours spent reading transcripts

Q · 05

And what would I ask of myself, next time?

Build the eval suite before users touch Post-Sales Socrates.

The system generates SQL dynamically — without a test set of known question → correct-SQL pairs, there's no way to know when a schema change silently breaks query generation. I'd build 50 gold-standard pairs before any user testing.

Instrument query rejection rates from day one.

When the intent layer can't match a question to a valid metric, it asks a clarifying question — but I wasn't logging how often, or which questions triggered it. Every failed query is a training signal for refining the semantic layer, wasted if you don't capture it.

Enforce annotation-first before any RAG work.

The next step for Pre-Sales is a RAG layer surfacing relevant past calls and playbooks. But RAG is only as good as its documents — without the manually annotated, quality-flagged call sample as the foundation, it retrieves noise.