Here are some key indicators that you should use an LLM like Claude instead of traditional ML approaches for your classification task:
Before diving into automation, it's crucial to understand your existing ticketing system. Start by investigating how your support team currently handles ticket routing.
Consider questions like:
The more you know about how humans handle certain cases, the better you will be able to work with Claude to do the task.
A well-defined list of user intent categories is crucial for accurate support ticket classification with Claude. Claude’s ability to route tickets effectively within your system is directly proportional to how well-defined your system’s categories are.
Here are some example user intent categories and subcategories.
In addition to intent, ticket routing and prioritization may also be influenced by other factors such as urgency, customer type, SLAs, or language. Be sure to consider other routing criteria when building your automated routing system.
Work with your support team to define clear success criteria with measurable benchmarks, thresholds, and goals.
Here are some standard criteria and benchmarks when using LLMs for support ticket routing:
Here are some common success criteria that may be useful regardless of whether an LLM is used:
The choice of model depends on the trade-offs between cost, accuracy, and response time.
Many customers have found claude-haiku-4-5-20251001 an ideal model for ticket routing, as it is the fastest and most cost-effective model in the Claude 4 family while still delivering excellent results. If your classification problem requires deep subject matter expertise or a large volume of intent categories complex reasoning, you may opt for the larger Sonnet model.
Ticket routing is a type of classification task. Claude analyzes the content of a support ticket and classifies it into predefined categories based on the issue type, urgency, required expertise, or other relevant factors.
Let’s write a ticket classification prompt. Our initial prompt should contain the contents of the user request and return both the reasoning and the intent.
Try the prompt generator on the Claude Console to have Claude write a first draft for you.
Here's an example ticket routing classification prompt:
def classify_support_request(ticket_contents):
# Define the prompt for the classification task
classification_prompt = f"""You will be acting as a customer support ticket classification system. Your task is to analyze customer support requests and output the appropriate classification intent for each request, along with your reasoning.
Here is the customer support request you need to classify:
<request>{ticket_contents}</request>
Please carefully analyze the above request to determine the customer's core intent and needs. Consider what the customer is asking for has concerns about.
First, write out your reasoning and analysis of how to classify this request inside <reasoning> tags.
Then, output the appropriate classification label for the request inside a <intent> tag. The valid intents are:
<intents>
<intent>Support, Feedback, Complaint</intent>
<intent>Order Tracking</intent>
<intent>Refund/Exchange</intent>
</intents>
A request may have ONLY ONE applicable intent. Only include the intent that is most applicable to the request.
As an example, consider the following request:
<request>Hello! I had high-speed fiber internet installed on Saturday and my installer, Kevin, was absolutely fantastic! Where can I send my positive review? Thanks for your help!</request>
Here is an example of how your output should be formatted (for the above example request):
<reasoning>The user seeks information in order to leave positive feedback.</reasoning>
<intent>Support, Feedback, Complaint</intent>
Here are a few more examples:
<examples>
<example 2>
Example 2 Input:
<request>I wanted to write and personally thank you for the compassion you showed towards my family during my father's funeral this past weekend. Your staff was so considerate and helpful throughout this whole process; it really took a load off our shoulders. The visitation brochures were beautiful. We'll never forget the kindness you showed us and we are so appreciative of how smoothly the proceedings went. Thank you, again, Amarantha Hill on behalf of the Hill Family.</request>
Example 2 Output:
<reasoning>User leaves a positive review of their experience.</reasoning>
<intent>Support, Feedback, Complaint</intent>
</example 2>
<example 3>
...
</example 8>
<example 9>
Example 9 Input:
<request>Your website keeps sending ad-popups that block the entire screen. It took me twenty minutes just to finally find the phone number to call and complain. How can I possibly access my account information with all of these popups? Can you access my account for me, since your website is broken? I need to know what the address is on file.</request>
Example 9 Output:
<reasoning>The user requests help accessing their web account information.</reasoning>
<intent>Support, Feedback, Complaint</intent>
</example 9>
Remember to always include your classification reasoning before your actual intent output. The reasoning should be enclosed in <reasoning> tags and the intent in <intent> tags. Return only the reasoning and the intent.
"""Let's break down the key components of this prompt:
ticket_contents to be inserted into the <request> tags.<reasoning> tags, followed by the appropriate classification label inside <intent> tags.The reason we want to have Claude split its response into various XML tag sections is so that we can use regular expressions to separately extract the reasoning and intent from the output. This allows us to create targeted next steps in the ticket routing workflow, such as using only the intent to decide which person to route the ticket to.
It’s hard to know how well your prompt works without deploying it in a test production setting and running evaluations.
Let’s build the deployment structure. Start by defining the method signature for wrapping our call to Claude. We'll take the method we’ve already begun to write, which has ticket_contents as input, and now return a tuple of reasoning and intent as output. If you have an existing automation using traditional ML, you'll want to follow that method signature instead.
import anthropic
import re
# Create an instance of the Claude API client
client = anthropic.Anthropic()
# Set the default model
DEFAULT_MODEL="claude-haiku-4-5-20251001"
def classify_support_request(ticket_contents):
# Define the prompt for the classification task
classification_prompt = f"""You will be acting as a customer support ticket classification system.
...
... The reasoning should be enclosed in <reasoning> tags and the intent in <intent> tags. Return only the reasoning and the intent.
"""
# Send the prompt to the API to classify the support request.
message = client.messages.create(
model=DEFAULT_MODEL,
max_tokens=500,
temperature=0,
messages=[{"role": "user", "content": classification_prompt}],
stream=False,
)
reasoning_and_intent = message.content[0].text
# Use Python's regular expressions library to extract `reasoning`.
reasoning_match = re.search(
r"<reasoning>(.*?)</reasoning>", reasoning_and_intent, re.DOTALL
)
reasoning = reasoning_match.group(1).strip() if reasoning_match else ""
# Similarly, also extract the `intent`.
intent_match = re.search(r"<intent>(.*?)</intent>", reasoning_and_intent, re.DOTALL)
intent = intent_match.group(1).strip() if intent_match else ""
return reasoning, intentThis code:
classify_support_request function that takes a ticket_contents string.ticket_contents to Claude for classification using the classification_promptreasoning and intent extracted from the response.Since we need to wait for the entire reasoning and intent text to be generated before parsing, we set stream=False (the default).
Prompting often requires testing and optimization for it to be production ready. To determine the readiness of your solution, evaluate performance based on the success criteria and thresholds you established earlier.
To run your evaluation, you will need test cases to run it on. The rest of this guide assumes you have already developed your test cases.
Our example evaluation for this guide measures Claude’s performance along three key metrics:
You may need to assess Claude on other axes depending on what factors that are important to you.
To assess this, we first have to modify the script we wrote and add a function to compare the predicted intent with the actual intent and calculate the percentage of correct predictions. We also have to add in cost calculation and time measurement functionality.
import anthropic
import re
# Create an instance of the Claude API client
client = anthropic.Anthropic()
# Set the default model
DEFAULT_MODEL="claude-haiku-4-5-20251001"
def classify_support_request(request, actual_intent):
# Define the prompt for the classification task
classification_prompt = f"""You will be acting as a customer support ticket classification system.
...
...The reasoning should be enclosed in <reasoning> tags and the intent in <intent> tags. Return only the reasoning and the intent.
"""
message = client.messages.create(
model=DEFAULT_MODEL,
max_tokens=500,
temperature=0,
messages=[{"role": "user", "content": classification_prompt}],
)
usage = message.usage # Get the usage statistics for the API call for how many input and output tokens were used.
reasoning_and_intent = message.content[0].text
# Use Python's regular expressions library to extract `reasoning`.
reasoning_match = re.search(
r"<reasoning>(.*?)</reasoning>", reasoning_and_intent, re.DOTALL
)
reasoning = reasoning_match.group(1).strip() if reasoning_match else ""
# Similarly, also extract the `intent`.
intent_match = re.search(r"<intent>(.*?)</intent>", reasoning_and_intent, re.DOTALL)
intent = intent_match.group(1).strip() if intent_match else ""
# Check if the model's prediction is correct.
correct = actual_intent.strip() == intent.strip()
# Return the reasoning, intent, correct, and usage.
return reasoning, intent, correct, usageLet’s break down the edits we’ve made:
actual_intent from our test cases into the classify_support_request method and set up a comparison to assess whether Claude’s intent classification matches our golden intent classification.A proper evaluation requires clear thresholds and benchmarks to determine what is a good result. The script above will give us the runtime values for accuracy, response time, and cost per classification, but we still would need clearly established thresholds. For example:
Having these thresholds allows you to quickly and easily tell at scale, and with impartial empiricism, what method is best for you and what changes might need to be made to better fit your requirements.
In complex scenarios, it may be helpful to consider additional strategies to improve performance beyond standard prompt engineering techniques & guardrail implementation strategies. Here are some common scenarios:
As the number of classes grows, the number of examples required also expands, potentially making the prompt unwieldy. As an alternative, you can consider implementing a hierarchical classification system using a mixture of classifiers.
For example, you might have a top-level classifier that broadly categorizes tickets into "Technical Issues," "Billing Questions," and "General Inquiries." Each of these categories can then have its own sub-classifier to further refine the classification.

Pros - greater nuance and accuracy: You can create different prompts for each parent path, allowing for more targeted and context-specific classification. This can lead to improved accuracy and more nuanced handling of customer requests.
Cons - increased latency: Be advised that multiple classifiers can lead to increased latency, and we recommend implementing this approach with our fastest model, Haiku.
Despite providing examples being the most effective way to improve performance, if support requests are highly variable, it can be hard to include enough examples in a single prompt.
In this scenario, you could employ a vector database to do similarity searches from a dataset of examples and retrieve the most relevant examples for a given query.
This approach, outlined in detail in our classification recipe, has been shown to improve performance from 71% accuracy to 93% accuracy.
Here are some scenarios where Claude may misclassify tickets (there may be others that are unique to your situation). In these scenarios,consider providing explicit instructions or examples in the prompt of how Claude should handle the edge case:
Proper integration requires that you make some decisions regarding how your Claude-based ticket routing script fits into the architecture of your greater ticket routing system.There are two ways you could do this:
For either of these approaches, you will need to wrap your script in a service. The choice of approach depends on what APIs your support ticketing system provides.
Visit our classification cookbook for more example code and detailed eval guidance.