Prompt Engineering & Output Quality

Prompt Patterns for Text Classification

Ticket routing, content tagging, sentiment scoring — classification is the workload where one stray synonym ("Billing" vs. "billing" vs. "Payments") breaks a downstream system. The fix is in how you ask.

Claude 3P 101 · Updated July 2026 · Unofficial guide

Classification looks like the easiest LLM task: read text, pick a label. In practice it fails in a distinctive way — not with wrong answers, but with almost-right ones. The model returns "Billing question" when your router expects BILLING, or invents a perfectly sensible category you never defined. Consistent labels at scale come from closing every degree of freedom the model doesn't need.

Constrain the output, don't request it

Older classification recipes relied on prefilling the assistant's response to force a bare label. That door has closed: per Anthropic's docs, prefilled responses are not supported starting with the Claude 4.6 generation of models and return a 400 error. The recommended migrations are exactly what a classifier wants anyway — structured outputs, or tool/enum classification.

With structured outputs, put your label set in a schema enum so the API constrains generation to one of your exact strings. Strict tool use is the equivalent for routing flows: define a tool per action (or one tool with an enum parameter), set "strict": true on the definition, and the docs guarantee tool names and inputs match your schema exactly.

from anthropic import AnthropicVertex

client = AnthropicVertex(project_id="my-project", region="global")
schema = {"type": "object", "additionalProperties": False,
          "properties": {"label": {"type": "string",
              "enum": ["BILLING", "TECH_SUPPORT", "SALES", "OTHER"]}},
          "required": ["label"]}
msg = client.messages.create(
    model="claude-haiku-4-5", max_tokens=256,
    output_config={"format": {"type": "json_schema", "schema": schema}},
    messages=[{"role": "user", "content": f"Classify this ticket:\n{ticket}"}],
)

Define the labels like you'd brief a new hire

Anthropic's core prompting principle is to treat Claude like a brilliant but brand-new employee: if a colleague with minimal context would be confused by your category definitions, Claude will be too. Applied to classification, that means each label gets one sentence of definition, boundary rules for the confusable pairs ("a refund request about a technical failure is TECH_SUPPORT, not BILLING"), and an explicit catch-all with instructions for when to use it.

Then show the boundaries in action. The official guidance recommends 3–5 relevant, diverse examples in <example> tags. For classifiers, spend those examples on the hard cases — the ambiguous ticket, the sarcastic review, the message that mentions two categories — rather than five easy ones from the same class.

Rule of thumb: every classification prompt needs a defined behavior for "none of the above." If you don't give Claude an OTHER bucket and a rule for using it, it will stretch your real categories to fit — and stretched categories are how routing quietly degrades.

Consistency levers beyond the prompt

Teams often reach for temperature: 0 to make classifiers deterministic. Know that on the newest models — including Claude Opus 4.8 and Sonnet 5 — non-default temperature, top_p, and top_k are rejected with a 400 error. The modern determinism lever is the schema constraint above, plus label definitions tight enough that the "right" answer doesn't move between runs. (More in Temperature, Top-P, and When to Touch Them.)

Classification is also where the cheapest model tier earns its keep. Short inputs, tiny outputs, and a constrained label space play to Claude Haiku 4.5 ($1 input / $5 output per million tokens) — evaluate it before defaulting to a bigger model, and see model tier differences for how prompts travel between tiers.

Classification at volume

Backfilling labels over an archive is batch work. On the Claude API and Claude Platform on AWS, the Message Batches API takes up to 100,000 requests per batch at 50% of standard prices, and most batches finish in under an hour; each request carries its own custom_id so you can join labels back to source records. On Bedrock and Vertex AI, Anthropic's Batches API isn't available — use AWS's or Google's own batch inference for Claude instead.

Finally, measure before you trust. A classifier is the easiest LLM system to evaluate — labels are either right or wrong — so build a small ground-truth set and track accuracy per label whenever the prompt changes. Anthropic's own prompt-engineering guidance puts success criteria and empirical evals ahead of any prompt tweaking.

Where to go next

Set up that measurement loop with a prompt evaluation framework and prompt regression testing. For the routing side, see escalation patterns.

Sources