Skip to content
AI Dev Toolkit.
Esc
  • AI Token CounterCount tokens for GPT, Claude, Gemini, DeepSeek, Qwen and more.Tool
  • LLM API Cost CalculatorEstimate per-request, daily and monthly API costs.Tool
  • AI Model ComparisonCompare prices, context windows and features across models.Tool
  • AI Model Pricing PagesSpecs, real costs and cheaper alternatives for popular models.Tool
  • Context Window CheckerSee whether your text fits each model’s context window.Tool
  • Subscription vs API CalculatorFind out whether a chat plan or the API is cheaper for you.Tool
  • GPU / VRAM CalculatorCheck how much VRAM a local model needs and which GPUs fit.Tool
  • Prompt Caching CalculatorEstimate savings from prompt caching.Tool

Prompt template · LLM apps and evals

Text classification prompt template

Sort text into fixed labels with definitions, examples and an “unclear” option, returning JSON. Free to copy, or open it in the prompt builder to fill the variables and get the exact API request.

281 tokens unfilled · 356 with the example below · o200k_base (GPT-4o and later)

Template

The prompt

Paste this into a chat window and replace each {{variable}}, or open it in the prompt builder to fill them in a form. Sections are marked with XML tags, which every major model reads well.

Prompt (one message, plain text)
You classify {{item_type}} into exactly one category. You are consistent: the same text always gets the same label.

<examples>
<example>
<input>
I was charged twice for March and only have one account.
</input>
<output>
{"label": "billing", "reason": "Asks about a duplicate charge."}
</output>
</example>
<example>
<input>
The export button does nothing when I click it in Firefox.
</input>
<output>
{"label": "bug", "reason": "Reports a feature that doesn’t work."}
</output>
</example>
<example>
<input>
Hi
</input>
<output>
{"label": "unclear", "reason": "Too short to tell what the customer needs."}
</output>
</example>
</examples>

<constraints>
Categories:
{{labels}}
- unclear: the text doesn’t fit any category, fits several equally, or is too short to judge.

Rules:
- Choose by the main intent of the text, not by keywords that appear in it.
- Use “unclear” rather than forcing a weak match.
</constraints>

<output_format>
JSON only: {"label": "<one category>", "reason": "<one short sentence>"}
</output_format>

<task>
Classify this {{item_type}}:

<text>
{{text}}
</text>
</task>
For an API call: system prompt and user message

With a system prompt, the role, constraints and output format stay fixed across calls (and can be cached), while the context and task go in the user message.

System prompt
You classify {{item_type}} into exactly one category. You are consistent: the same text always gets the same label.

<constraints>
Categories:
{{labels}}
- unclear: the text doesn’t fit any category, fits several equally, or is too short to judge.

Rules:
- Choose by the main intent of the text, not by keywords that appear in it.
- Use “unclear” rather than forcing a weak match.
</constraints>

<output_format>
JSON only: {"label": "<one category>", "reason": "<one short sentence>"}
</output_format>

<examples>
<example>
<input>
I was charged twice for March and only have one account.
</input>
<output>
{"label": "billing", "reason": "Asks about a duplicate charge."}
</output>
</example>
<example>
<input>
The export button does nothing when I click it in Firefox.
</input>
<output>
{"label": "bug", "reason": "Reports a feature that doesn’t work."}
</output>
</example>
<example>
<input>
Hi
</input>
<output>
{"label": "unclear", "reason": "Too short to tell what the customer needs."}
</output>
</example>
</examples>
User message
<task>
Classify this {{item_type}}:

<text>
{{text}}
</text>
</task>

Variables

What to put in each variable

{{item_type}}
What is being classified, such as “support ticket”, “app review” or “commit message”.
{{text}}
The text to classify.
{{labels}}
One line per category with a definition, such as “- billing: charges, invoices, refunds, plan changes”. Definitions matter more than names.

Use

When to use it

Use it for routing and tagging at scale: support tickets to teams, reviews to themes, feedback by product area, log lines by type. It suits label sets of up to roughly a dozen categories with clear definitions.

Measure it before trusting it. Label a hundred real examples by hand, run the prompt over them and count agreements per label. The labels where it disagrees with you usually need a sharper definition or a better example, not a different model.

Structure

Why it’s structured this way

Each label has a definition because names alone are ambiguous: is “my card was declined” billing or a bug? The definitions are your policy, and the “main intent, not keywords” rule tells the model how to apply it.

The “unclear” option is a release valve. Without it, every input is forced into a category and the errors look like confident classifications. With it, ambiguous texts can go to a person or a default queue, and the rate of “unclear” becomes a useful metric.

The examples show the exact output shape and one of each kind of decision, including an “unclear” case. Anthropic recommends three to five varied examples, and Google recommends always including some for Gemini. They sit in the prompt rather than the conversation by default; the builder can move them into turns.

Example

A filled-in example

{{item_type}}
support ticket
{{text}}
Since yesterday I can’t sign in with Google, it just loops back to the login page. Other people on my team are fine.
{{labels}}
- billing: charges, invoices, refunds, plan or seat changes
- bug: something in the product doesn’t work as documented
- how-to: the customer wants to know how to do something that works
- account: login, password, SSO, deleting or merging accounts

What to look for. This one sits between “bug” and “account”. Under “main intent” it is most likely account (a login problem for one user), and the reason sentence should say so. If your team would route it to engineering instead, sharpen the definitions; that’s the policy decision the template makes visible.

The complete filled-in prompt (356 tokens)
Filled-in prompt
You classify support ticket into exactly one category. You are consistent: the same text always gets the same label.

<examples>
<example>
<input>
I was charged twice for March and only have one account.
</input>
<output>
{"label": "billing", "reason": "Asks about a duplicate charge."}
</output>
</example>
<example>
<input>
The export button does nothing when I click it in Firefox.
</input>
<output>
{"label": "bug", "reason": "Reports a feature that doesn’t work."}
</output>
</example>
<example>
<input>
Hi
</input>
<output>
{"label": "unclear", "reason": "Too short to tell what the customer needs."}
</output>
</example>
</examples>

<constraints>
Categories:
- billing: charges, invoices, refunds, plan or seat changes
- bug: something in the product doesn’t work as documented
- how-to: the customer wants to know how to do something that works
- account: login, password, SSO, deleting or merging accounts
- unclear: the text doesn’t fit any category, fits several equally, or is too short to judge.

Rules:
- Choose by the main intent of the text, not by keywords that appear in it.
- Use “unclear” rather than forcing a weak match.
</constraints>

<output_format>
JSON only: {"label": "<one category>", "reason": "<one short sentence>"}
</output_format>

<task>
Classify this support ticket:

<text>
Since yesterday I can’t sign in with Google, it just loops back to the login page. Other people on my team are fine.
</text>
</task>

Models

Tips by model family

  • All models

    Set the model’s output to a schema with an enum of your labels using the provider’s structured outputs. The model can then only return a label you defined.

  • Claude

    Anthropic notes that structured outputs don’t guarantee the capitalisation of enum values. Compare labels case-insensitively in your code, or keep them all lower-case as here.

  • OpenAI GPT

    For high-volume classification, a small, fast model is often enough once the examples are good. Price your volume with the cost calculator before choosing.

Related

Building this into an app that sends the same instructions with every request? Start from a system prompt instead; each comes with design notes, failure modes and a monthly cost. In the system prompt library: Support ticket triage and routing or Content moderation classifier.

Edited the template? Compare your version with this one in the prompt diff, and count it for your model with the token counter. In the glossary: few-shot prompting, structured outputs. Browse all 29 prompt templates.