Skip to main content
DoneThat

AI Adoption GuideOperationsIntake

Auto-classification by type

Classifier assigns category, sub-category, and owning team from the first message, routing each request to the correct queue.

Operations processIntakePrioritizeScheduleExecuteVerifyDeliverConfirmClose

By Don, DoneThat’s AI coach · updated

Overview

New requests rarely arrive with a clean type. They land as email, chat, portal comments, and forwarded threads. The queue owner still has to put each one on a team that can act. Auto-classification by type reads that first message and proposes a category, a sub-category, and an owning team so the item sits in the right queue instead of a shared dump.

The point is speed at intake, not a locked decision. Routing to the wrong team costs more than sitting a few minutes in triage: the wrong queue idles, the right queue never sees the clock, and the requester gets a bounce. Scoring the opening text against your live taxonomy shortens the sort. Staff still move the ticket when the suggestion is off.

Mapping category, sub-category, and owning team

Treat classification as three fields, not one label. Category is the coarse bucket your operation already uses, such as access, facilities, payroll, vendor, or incident. Sub-category is the narrower cut that changes who touches the work and what a useful first response looks like, for example a badge reprint versus a building access exception. Owning team is the queue that should own the work. That field is not always a one-to-one map from category. You may split the same category by region, customer tier, or channel.

Score against the taxonomy you actually staff. If the model invents a type that has no queue, you have created a holding pen. Keep the label set identical to queue names, or maintain an explicit map from label to queue ID. When a request could fit two teams, use the more specific sub-category only when the first message supports it. Otherwise stay at category and let owning team default to the team that already owns that category.

Use the first message as the unit of evidence. Subject lines help. The body usually carries the intent. Signatures, legal footers, and quoted prior threads are noise unless you strip them first. Unstructured request parsing is the usual upstream step: parsing extracts the ask, the object, and the constraints. Classification then decides type. If you classify the raw dump, forwarded FYI chains look like every type at once.

Do not wait for a completed form. The value of this use case is that a free-text open still gets a queue. Forms can override later. Until then, the suggested type is what puts the item in front of someone who can ask the missing question.

When the first message is too thin

Empty output is a valid result. If the opening text cannot support a category, the classifier should return no category, no sub-category, and no owning team rather than a guess. Short pings such as "please advise", "see attached", a screenshot with no caption, or a ticket that is only a forwarded header do not contain type. Guessing manufactures misroutes that look like automation success in a dashboard and like delay on the floor.

Define thin in operational terms. Character count is a weak proxy. A short note that names a system and a failure mode is classifiable. A long status update that never states a request may not be. Prefer rules such as: no actionable verb, no object of work, and no named process. If parsing already flagged the body as empty or attachment-only, classification should abstain.

Route abstentions to a triage queue, not into a random team. The triage queue is staffed to ask one clarifying question or to open the attachment. Measure abstention rate. A sudden spike usually means a channel change (a new chatbot that sends a greeting as the first message) or a taxonomy drift, not a model failure.

Staff still reassign the queue

The classifier suggests. It does not lock. An operations queue owner needs a one-click reassign that writes the final category, sub-category, and team without fighting the original suggestion. Keep the model output visible as suggested so a later audit can tell prediction from decision. If you overwrite the suggestion in place, you cannot tell whether the model was wrong or whether the work changed after intake.

Reassignment is not a failure by default. Mixed requests, such as a facilities issue that is also an access exception, will split. Language that two teams share, such as access, invoice, or outage, will collide. Seasonal volume will shift who should own a type. Capture the reason when staff move a ticket if you can do it in two clicks: wrong category, wrong team, split request, or requester corrected. Those reasons are the training signal. Blind reassign counts only tell you that people disagree.

Do not auto-escalate or auto-close from a type label at this stage. Type is an intake aid. SLA, priority, and duplicate status are separate. A confident payroll tag is not permission to start a clock you have not validated.

How classification sits with parsing, SLA tags, and duplicates

Run unstructured request parsing first when the channel is messy. Parsed fields (what is asked, which asset, which site) make classification stabler than raw email. If parsing abstains, classification should usually abstain too.

SLA pre-tag from request content should consume type, not replace it. Contractual response times often depend on category. Pre-tagging SLA from keywords without a type creates two competing clocks. Once category and owning team are suggested, SLA pre-tag can apply the policy for that queue. If classification returned empty, do not invent an SLA tag from leftover phrases.

Duplicate request detection belongs next to classification, not after the ticket has bounced. Near-duplicates of an open item should inherit type from the surviving ticket instead of getting a fresh guess. A duplicate of a closed item may still need a new type if the ask changed. Sequence matters: detect duplicate, then classify only the surviving or truly new request. Classifying every copy inflates volume per queue and hides the merge.

Keep the jobs separate in the UI even if they run in one pass. Parsing answers what was said. Classification answers which queue. SLA pre-tag answers which clock. Duplicate detection answers whether this is already here. Mixing them into one opaque intake score makes reassignment harder, because staff cannot tell which part was wrong.

What to check before you trust the routing

Start with a frozen taxonomy: categories, sub-categories, and team IDs that match the queues you staff this quarter. Snapshot a week of first messages and score them offline against that map. Look at misroutes that would have crossed a team boundary, not at fine disagreements inside one team. Intra-team sub-category noise is cheaper than sending facilities work to payroll.

Watch three live rates: abstention (empty output), staff reassign within a short window after intake, and bounce-back (the second team sending it onward). Reassign without bounce-back often means the suggestion was close. Bounce-back means the requester waited while two queues argued. If bounce-back rises, tighten abstention: return empty more often rather than forcing a team.

Channel mix will fool you. Portal forms with a type field should not be re-classified unless the free text contradicts the form. Chat first messages are short. Email is long and polluted. Tune thresholds per channel instead of one global cutoff.

Keep a path for split work. When the first message contains two asks for two teams, empty output or a multiple holding type is safer than picking the louder sentence. Staff can clone and assign. A single forced owner hides the second ask until it becomes a complaint.

Is this worth automating for you?

Whether this pays back depends on how much time it takes your team today. Most teams estimate that from memory, and the estimate is usually wrong in one direction or the other.

DoneThat reconstructs where the time actually went, with no timers to forget, so you can measure the baseline before committing to a project and check the gain afterward.

Measure the baseline first