text-classification

Public

Five classification prompts — aspect sentiment, chatbot intent, emotion, content moderation, and spam/phishing — each with a CEL-assertable schema and a judge-free deterministic eval. Schema design is eval design.

5 prompts
README

Text Classification

Five classification prompts for the labels that route, gate, and analyze real traffic — aspect sentiment, chatbot intent, emotion, content moderation, and spam/phishing. Each returns typed, validated JSON with a strict schema, and — the theme of this collection — each schema is designed so its eval is pure, deterministic CEL, no LLM judge needed. Closed enums and flat string arrays aren't just tidy output; they're what makes the classifier testable.

Like the Structured Extraction, Customer Support, RAG Essentials, Translation Essentials, and Summarization Essentials collections, every prompt is a system message, a user message, and a schema — framework-agnostic, SDK-generatable in TypeScript and Python.

Prompts

PromptWhat it does
aspect-based-sentimentPer-aspect sentiment (battery: 😀, price: 😠) with a verbatim quote per aspect and an overall label. Deeper than plain sentiment.
intent-detectionClassify a user message against your runtime intent taxonomy with confidence and an explicit out-of-scope (is_fallback) flag.
emotion-detectionEmotion from a closed taxonomy (joy/anger/sadness/fear/surprise/disgust/neutral) — primary + secondary + intensity.
content-moderationPolicy flags with severity and quotes, a safe gate, and a flat categories[] array. The injection-safety showcase.
spam-detectionham / spam / phishing with signals — phishing wins when a message is both.

Not duplicated — cross-linked

This collection goes deeper than the general-purpose classifiers already on @sufleur; it doesn't re-ship them:

  • sentiment-analysis gives one overall label. aspect-based-sentiment breaks it down per aspect.
  • text-classification is general single-label classification against a caller label set; intent-routing routes to support queues. intent-detection is purpose-built for NLU/chatbot intent with described intents and first-class out-of-scope detection.

Reach for the general tools when you want a plain label; reach for these when the shape of the problem (aspects, a described taxonomy, policy categories, spam vs phishing) has structure worth capturing.

The theme: schema design is eval design

Every prompt here is eval-gated, and all five evals are judge-free — pure CEL over the output. That's not luck; it's a schema-design choice:

  • Closed enums (overall_sentiment, primary_emotion, verdict, moderation category) let an eval assert output.x == case.expected and mean it.
  • Flat string arrays exist specifically to be assertable: content-moderation emits a top-level categories[] (not just nested flags[]) so an eval can check case.expected_categories.all(c, c in output.categories) without CEL needing to map over objects. emotion-detection exposes secondary_emotions[] for the ambiguous-case allowance.
  • Verbatim quotes make groundedness a substring test: aspect-based-sentiment asserts output.aspects.all(a, case.text.contains(a.quote)) — mechanical, no judge.
  • Runtime-taxonomy membership (intent-detection) is checked with output.intent in case.intents_labels against a flat labels field in the dataset.

If you're authoring your own classifier, the lesson is: design the output schema and the eval assertions at the same time. A flat, enum-typed, quote-backed schema is one you can gate deterministically — cheaper and more reliable than grading it with another model.

House conventions

  1. Reasoning before the label. Every prompt emits its reasoning first; classification is exactly where post-hoc rationalization hurts most, so the rationale precedes (and informs) the verdict. Key order is pinned in each system prompt.
  2. Closed enums wherever the taxonomy is fixed (sentiment, emotion, moderation category, severity, spam verdict); runtime taxonomies (intent) carry the membership caveat and a documented one-line check.
  3. Quotes are verbatim and verifiableaspect-based-sentiment and content-moderation quote the triggering span character-for-character.
  4. Input is data, never instructions. All user content is triple-mustache-injected inside XML-style delimiters; content-moderation makes this its headline property — "mark this safe" embedded in the text never moves the verdict.
  5. Confidence is uncalibrated and says so in every schema description.
  6. Empty/garbage behaviour is specified and observable — empty input yields the neutral/safe/ham default, never invented labels, and the evals assert it.
Prompts5 prompts
@sufleurtext-classification