AI Adoption GuideSupportAssign
Skill-based agent matching
Embedding search matches ticket content to agent skill profiles built from past resolutions.
Support processIntakeTriageAssignInvestigateResolveConfirmClose
By Don, DoneThat’s AI coach · updated
The match runs on wording, not on a tag anybody applied
Support leads know the gap between a category and a problem. Two tickets tagged integrations can need completely different people. Embedding search reads the ticket text and compares it against text each agent has resolved before. The output is a short ranked list of agents with a similarity score and the past tickets behind each name.
Similarity is not competence. A high score means this agent has written about problems that look like this one. It does not mean they are free, senior enough, or the right person for an angry customer. The match narrows a floor of thirty people to four.
The strength of this approach is that new vocabulary needs no setup. When a product ships a feature nobody has a tag for, tickets about it still find the agents who have worked nearby. Tag-driven routing has to wait for someone to define a category. Embeddings do not.
The mechanism is shared with retrieval. The same index that supports surfacing resolved tickets that match the current issue can be grouped by agent instead of by ticket. One embedding pipeline, two products, and a good reason to get the text quality right once.
Build each profile from resolution text the agent actually wrote
Profiles are made of text, so the choice of text decides everything. Use the resolution note and the internal comments, not the customer's original message. The customer describes symptoms. The agent describes what was wrong and what fixed it, which is the part worth matching on.
Filter before embedding. Tickets closed by macro, tickets closed as duplicate, and tickets the agent only touched once contribute noise. Keep the ones where the agent wrote a real explanation. A profile built from two hundred substantive tickets beats one built from four thousand mixed ones.
One vector per agent is too coarse. Averaging everything an agent has ever solved produces a blur that sits near the middle of the corpus and matches nothing well. Cluster each agent's resolutions and keep several vectors per person, one per area they work in. Match against the closest cluster, not the average.
Set a floor and honor it. If the best similarity in the room is weak, the ticket has no match and should go to the general queue. A ranked list always returns names, including when the ticket is about something nobody has seen. Returning nothing is the correct answer more often than teams expect.
New hires have no text, and no trick fixes that. Seed their profile from training modules and shadowed tickets if that material exists, and mark it as seeded. Otherwise route them by rule for the first weeks. A profile with three tickets in it will match strongly on all three and badly on everything else.
Rank on similarity, then let the constraints do their work
The ticket side needs cleaning too. Strip signatures, quoted threads, and boilerplate before embedding, or every ticket from one company will match every other ticket from that company. Long log dumps overwhelm the prose. A vision and parsing step that pulls error codes out of attachments gives the matcher a compact string to work with instead.
Availability filters after the ranking, never before. Take the top handful of matches, then drop anyone off shift, over cap, or without the right permission. If that leaves nobody, widen the list rather than lowering the floor. Language coverage and shift overlap belong in the same filter pass.
Show the matching tickets, always. A name with three linked resolutions is checkable in thirty seconds. A similarity number on its own means nothing to a shift lead and will be treated as decoration. The linked tickets also let the assigned agent start reading before they start working.
Match an inverter communication failure at a solar monitoring vendor
The case below is made up for illustration. A vendor sells monitoring hardware and software to commercial solar installers. Support handles thirty agents and a product line spanning three generations of gateway hardware. Tickets arrive from installers standing on roofs, so they are short and full of model numbers.
A ticket reads that a second-generation gateway stopped reporting after a site changed its cellular carrier, with two inverters still showing production locally. The category is connectivity, which covers a third of the queue and helps nobody. Embedding search finds four agents whose past resolutions cluster near carrier changes and gateway provisioning.
Two of the four are unavailable. One is on leave and one is at cap with nine open tickets. The remaining two are Elena, with six close matches from the last four months, and Tomas, with two older ones. Routing assigns Elena and attaches her three nearest resolutions to the ticket.
The lead intervenes for a reason unrelated to skill. Elena is the only person on shift who can approve firmware rollbacks, and an outage is running in another region. He moves the gateway ticket to Tomas and adds a note pointing at Elena's matched resolutions. Tomas closes it the same afternoon.
That close changes the profiles. Tomas gains a recent, well-written resolution in a cluster where he was thin. The next carrier-change ticket will rank him higher without anybody editing a skill list. Matching on text means the profiles update as a side effect of doing the work.
Where embedding matches quietly go wrong
Wording similarity is not problem similarity. Two tickets can share vocabulary and have nothing in common, especially in a product where every message contains the same six nouns. Check a sample of matches by hand each month. If the linked resolutions do not read as relevant, the index needs better source text rather than a bigger model.
Stale profiles route on obsolete knowledge. An agent who mastered the first-generation gateway will keep matching those tickets long after the fleet has moved on. Rebuild the index on a schedule and weight recent resolutions more heavily. Two years of unweighted history describes a team that no longer exists.
Verbose agents dominate the index. Someone who writes long, detailed resolution notes generates more text and more chances to match. Someone equally skilled who writes three lines disappears. Normalize by document count, and consider whether the note template is the real problem.
Repeated defects distort the picture. When one bug produces hundreds of near-identical tickets, whoever worked that week owns the cluster forever. Grouping tickets that share an underlying defect lets the profile count the cluster once instead of three hundred times.
Agents read their own profiles, and the lead makes the call
Every agent should be able to open their profile and see what it says about them. The view needs to list the clusters, name the areas, and link the tickets underneath. Agents will find mistakes nobody else can find, including tickets they were credited with but barely touched.
Give them a way to remove a ticket from their own profile and a way to declare an interest. A removed ticket drops out of the index at the next rebuild. A declared interest does not create a match on its own, but it puts the agent into the exploration pool for that area.
The lead decides who develops into what. Matching describes the past, and left alone it will keep describing it. Deliberately assigning tickets outside an agent's clusters is how the past stops being the plan. Budget a share of the queue for that and protect it when volume spikes.
Skill profiles are routing input and nothing else. They do not belong in a promotion case, a performance conversation, or a headcount argument. An explicit statement of that, written once and repeated, is what keeps agents willing to write honest resolution notes. Profiles built from text stop working the moment people start writing for the index.
Where the match and other signals disagree, the lead breaks the tie. The record of topics an agent has already closed may point elsewhere, and that disagreement is worth reading rather than resolving automatically.
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