AI Adoption GuideSupportInvestigate
Similar-ticket retrieval
RAG surfaces top resolved tickets matching the current issue along with their fixes, using tools like Twig or eesel.
Support processIntakeTriageAssignInvestigateResolveConfirmClose
By Don, DoneThat’s AI coach · updated
Retrieval returns precedents, and a precedent is not an answer
Most tickets have been solved before by somebody on the team. Retrieval finds those tickets. It takes the current issue, searches the resolved archive, and returns the closest matches with the fix that was applied to each one. The agent gets three or four cases, ranked, with links to the originals.
The result is a set of candidates. A past ticket that resembles this one is a lead worth ten seconds of reading, not a conclusion about the current customer's account. Retrieval systems such as Twig and eesel work over an existing corpus. They surface what was done before. They do not know whether this account is on the same plan, the same version, or the same integration.
Each result needs three things visible without a click. What the customer reported. What the fix was. Whether it held. That third field is the one teams forget, and it is the difference between a precedent and a warning. A ticket that reopened twice after the same fix should be presented as evidence against that approach.
Curate the archive before pointing a search at it
An archive contains bad resolutions as well as good ones. Tickets closed by silence. Tickets closed with a workaround that stopped working two releases ago. Tickets where the recorded cause was a guess nobody revisited. Indexing all of it teaches the retrieval to repeat the team's worst days alongside its best.
Filter the index on outcome. Include resolutions that were confirmed, that did not reopen inside the follow-up window, and that carry a written cause. Exclude auto-closed tickets and anything where the resolution field is empty or copied from a macro. A smaller index of clean cases outranks a complete one every time.
Retrieval also depends on how the archive was written. A closed ticket holding a full conversation and no summary is hard to match against. Structured problem, cause, and fix records make far better index entries, which is why summarization at close pays off in this stage rather than that one.
Attach structured filters to every entry. Product version, plan, region, integration, and close date. Without them, search returns a fix that only ever worked on a version this customer does not run. Personal data has to come out at the same time, since a retrieved ticket shows one customer's history to an agent working on another account.
Match on the failure, then filter on the environment
Semantic search on ticket text finds tickets that sound alike. That is a useful start and a poor finish. Two customers can describe the same symptom while running completely different products underneath. Weight the extracted signals higher than the prose: error codes, exception types, failing endpoints, and the product surface named in the ticket.
Apply the structured filters as hard limits, not as tie-breakers. If the current account runs version 5, a candidate resolution that applied only to version 3 does not qualify. Exclude it, or mark it clearly as out of scope. A stale fix that ranks first because the wording matched leads somewhere bad. The agent sends instructions for a screen that no longer exists.
Let recency count. A fix from last month is more likely to still work than one from two years ago. That holds even when the older ticket reads closer. Show the close date next to each result and let it influence the order. Where several recent tickets match tightly, that pattern is worth passing to grouping across the corpus, because repeated precedents often mean an unfixed defect.
Return nothing when nothing qualifies. An empty result is a clear signal that this issue is new to the archive. Padding the panel with three loose matches wastes the agent's attention and slowly trains the team to ignore it.
Retrieve precedents for a spam-folder complaint at an email platform
The walkthrough here is imaginary. A vendor runs a transactional email platform for online stores. A customer writes that order confirmations started landing in the spam folder for recipients at one large mailbox provider, beginning four days ago. Everything else appears to send normally.
Retrieval returns three candidates. The first is a ticket from seven weeks ago with the same symptom at the same provider. It was resolved by fixing a DMARC record that listed a subdomain incorrectly. The customer confirmed the fix, and the ticket never reopened. The second is from last year, resolved by warming a new sending IP, and it reopened once. The third mentions the same provider but concerns bounced messages rather than spam placement.
The panel shows all three with their filters. The first candidate ran on the same product tier and a shared sending pool. The second involved a dedicated IP, which this customer does not have. That mismatch is displayed rather than hidden, so the agent can drop it in a glance.
The agent starts with the DMARC precedent because it matches the environment as well as the wording. Checking this customer's actual DNS records takes two minutes and confirms a similar misconfiguration. Until that check, the precedent was a hypothesis. The record lookup makes it a finding, and only the finding goes into the cause field.
Confident matches on the wrong problem
Retrieval fails in ways that feel helpful, which is what makes them expensive.
Surface similarity outranks real similarity. Two tickets that both say nothing is sending can involve an expired API key and a suspended account. Requiring an error code or endpoint match before a candidate ranks first prevents most of these.
The archive learns from itself. When agents copy a retrieved fix into a reply without checking, that ticket closes with the same recorded cause and joins the index. Wrong precedents then multiply quietly. Sampling closed tickets that cite a retrieved case, and asking whether the fix actually applied, is the only reliable way to catch it.
Popular fixes crowd out correct ones. A resolution applied five hundred times will match loosely against almost anything and keep appearing. Cap how often a single resolution can be recommended, or require a stronger similarity score for high-frequency entries.
Retrieval gets used as diagnosis. A matching precedent is evidence about other customers, not about this one. When the evidence sits in the current ticket's attachments, reading it is a separate compression job that answers a different question.
The agent decides whether the precedent applies here
Nothing retrieved should reach the customer unverified. The agent opens the candidate, reads what was actually done, and checks the current account against the conditions that made the old fix work. That check takes less time than writing an apology for advice that broke something.
Suspected and confirmed stay separate on the ticket. Writing this looks like the DMARC issue from ticket 4417 is honest and useful. Writing the cause is a DMARC misconfiguration, on the strength of a match alone, hands the next reader a fact that nobody established. The cause field belongs to whoever verified it.
Retrieval feeds the reply but does not write it. Turning a precedent into customer-facing wording is a grounded drafting step with its own review, and the draft should cite the sources it used. An agent who cannot see where a sentence came from cannot approve it.
Repeated retrieval of the same case is a signal for the knowledge team. When one resolved ticket answers thirty new ones, the fix belongs in an article rather than in a search result. Promoting it is a documented content step, and the support lead decides which cases earn it. The archive stays the record of what happened; the knowledge base holds what the team recommends.
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