Classification and routing rules grow into switch statements.
Every new category, queue or exception adds another case, keyword list or condition to a method only developers can change. With IntentSharp the policy is written in plain words in an intent file, and the answer comes back as values of your own enums, checked before your code routes anything.
What it costs today
Routing starts as a switch on a few keywords. Then come the exceptions: an outage that only matters when it stops a whole site, a billing question that is really a sign-in problem, a customer whose tickets always go to one team. Each one is another branch, keyword list or regular expression, and each misses the phrasings nobody thought of.
The policy lives in code the support team cannot read, so every change to it is a ticket, a build and a deployment, and nobody outside development can check the rules the queues follow.
How IntentSharp handles it
The policy is in Support.Route.intent.yaml, in plain words, with one example. Its shape is TicketRoute, a record of two enums your application registers. Three tickets go through the same call; the third ticket's first answer names a queue the enum does not have, so it fails the check, and the second attempt routes it to Product.
name: Support.Routeversion: 4owner: support-opsintent: >- Read this support request and set its category, then its queue. Billing goes to Finance, Access to Identity, Feature to Product and Outage to Engineering, except an outage that stops a whole site, which goes to Escalations.shape: { clrType: TicketRoute }examples: - input: "Since the update nobody in our team can sign in." output: { category: Access, queue: Identity }// TicketRoute holds your two enums. A file may name it as its// shape because your application registered it.var types = new IntentTypeRegistry().Add<TicketRoute>();var intents = new IntentRuntime(client, catalog, types: types);var queues = Enum.GetValues<SupportQueue>() .ToDictionary(queue => queue, _ => new List<string>()); foreach (var ticket in tickets){ var route = await ticket.RunIntentAsync<TicketRoute>( intents, "Support.Route"); // No switch: a successful answer is a value of your enum. if (route.Success) queues[route.Value!.Queue].Add(ticket); results.Add(route);}"We were charged twice for invoice INV-2291." Success: true, after 1 attempt Category: Billing, queue: Finance"The scanners in our whole warehouse cannot reach your service. Nothing ships." Success: true, after 1 attempt Category: Outage, queue: Escalations"Could you add an export to Excel on the orders page?" Attempt 1 passed: false, one Verification finding Success: true, after 2 attempts Category: Feature, queue: Product Queues: Finance 1, Product 1, Escalations 1TicketRoute is (TicketCategory Category, SupportQueue Queue): Billing, Outage, Access or Feature, and Finance, Engineering, Identity, Product or Escalations. Compiled and run with every build of this site; the model's answers are scripted, and a pass means the answer met the checks, not that the judgement is right.
What stays in your control
The file holds the policy. The enums, the queues and what happens to a ticket stay in your code.
- Your enums are the only answers. Enum values are read by name. A name that is not a member of your enum fails the check and goes back to the model with the finding, and
Valueholds only an answer that passed. - The policy in plain words. The file's
intentandexamplessteer the answer, and a saved edit applies to the next call. A reply that copies an example and breaks a rule still fails. - More checks where a rule can say it. The file can add
rules, and your application can register C# checks that the file switches on undervalidators. - What a failure looks like. When the attempts run out,
Successis false,Issuessays why, and the ticket is yours to handle: in the program above, only a successful answer puts a ticket in a queue. - A pass is not a proof. A pass means the checks passed, not that the judgement is right. Each ticket is a model call, plus one per retry; for a fixed set of labels at high volume, a classifier you train yourself may cost less per call.
Read next
Intent files
Judgement in plain words, limits as data and checks in code, with a keyword classifier beside the intent that replaces it.
Intent file reference
The shapes an intent can return, a registered .NET type among them.
Running intents from files
Register the types and checks a file may name.
More problems and their answers: Solutions.
Route your next ticket from a file.
dotnet add package IntentSharp --prereleasedotnet add package IntentSharp.Catalog --prerelease