How I built the Email Triage demo
Read an inbound email once, and come out the other side with a category, an urgency level, who should own it, and a draft reply — the four decisions a human triaging a shared inbox actually makes.
Last reviewed
The problem
A shared inbox mixes sales inquiries, support tickets, complaints, spam, and the occasional legal notice. Triage isn't one decision — it's classify, prioritize, route, and often draft a first response, all before anyone with the right context has read the message.
One call, seven fields
Rather than chain separate classify → route → draft calls, the route asks for one JSON object with all seven fields at once: category, urgency, sentiment, routing destination, a one-line summary, a suggested reply, and extracted key entities. Fewer round trips, and the fields stay consistent with each other since one call reasons about all of them together.
The four classification fields are closed enums, not free text; summary, suggested reply, and key entities are free text
category: Sales | Support | Complaint | Partnership | Spam | Internal | Invoice | Legal
urgency: low | medium | high | critical
sentiment: positive | neutral | negative | frustrated | urgent
routeTo: Sales | Support | Finance | Legal | Management | Spam | HR
Why enums, not open categories
An open-ended "category": string field looks more flexible, but it pushes the hard part downstream: whatever consumes this output — a routing rule, a dashboard filter, a ticketing integration — now has to handle arbitrary strings a model might invent. Naming the exact set of allowed values in the prompt turns validation into a one-line membership check instead of fuzzy string matching against however the model phrased something this time. It's a small constraint that removes an entire category of downstream bugs.
Labeled benchmark
Run 2026-08-02Model
Claude Haiku 4.5 (claude-haiku-4-5-20251001)
Sample size
8 synthetic emails
Data source
8 hand-authored synthetic emails (complaint, sales inquiry, invoice, security incident, partnership pitch, spam, internal HR note, legal notice) run live against the production endpoint at tioga.ai.
Category exact-match
8/8 (100%)
Urgency exact-match
5/8 (63%)
Successful classifications
8/8 (HTTP 200)
Average latency
~1.8s
Limitations
- —Urgency is inherently more subjective than category — all 3 mismatches were one severity level off (e.g. "high" vs "critical"), and every miss erred toward flagging higher urgency, not lower.
- —Sample size is small (8 cases) and hand-authored; a production engagement would calibrate urgency thresholds against your team's actual triage decisions.
- —Sentiment and routing fields weren't scored in this run — only category and urgency.