Skip to main content
Classification is one of the simplest structured output tasks, but the details matter. An unconstrained classifier might return "Billing", "billing", "billing issue", or "BILLING", all meaning the same thing but breaking your routing rules, analytics aggregations, and dashboard filters. An enum constraint eliminates this by restricting the output to exactly the values your system recognizes. Adding an evidence field turns a bare label into an actionable decision. Evidence gives reviewers the specific input observations that drove the classification, so they can verify quickly instead of re-reading the full ticket.

Goal

Classify support tickets into a routing queue with a label, priority, and grounded evidence.

Schema contract

{
  "oneOf": [
    {
      "type": "object",
      "properties": {
        "label": {
          "type": "string",
          "enum": ["billing", "technical", "account", "shipping"]
        },
        "priority": { "type": "string", "enum": ["low", "medium", "high", "urgent"] },
        "evidence": {
          "type": "array",
          "items": { "type": "string", "minLength": 10, "maxLength": 160 },
          "minItems": 1,
          "maxItems": 3
        }
      },
      "required": ["label", "priority", "evidence"],
      "additionalProperties": false
    },
    {
      "type": "object",
      "properties": {
        "label": { "type": "string", "const": "other" },
        "other_label": { "type": "string", "minLength": 3, "maxLength": 60 },
        "priority": { "type": "string", "enum": ["low", "medium", "high", "urgent"] },
        "evidence": {
          "type": "array",
          "items": { "type": "string", "minLength": 10, "maxLength": 160 },
          "minItems": 1,
          "maxItems": 3
        }
      },
      "required": ["label", "other_label", "priority", "evidence"],
      "additionalProperties": false
    }
  ]
}

Example input

My card was charged twice for order ORD-9842. Need refund today.

Example output

{
  "label": "billing",
  "priority": "high",
  "evidence": [
    "User reports duplicate card charge.",
    "Explicit refund request indicates financial impact."
  ]
}

Implementation tips

  • Enum labels are non-negotiable. Every label value should map directly to a routing queue, a dashboard filter, or a database category. If the label isn’t in the enum, it can’t reach your system.
  • Evidence grounds the decision. The bounded evidence array (1-3 items, 10-160 characters each) forces the model to cite specific observations from the input. This makes quality audits fast: reviewers check evidence against the ticket text instead of guessing why the model chose a label.
  • Fallback for taxonomy drift. The second oneOf branch requires other_label when label is "other". This captures novel categories without polluting your main enum. Review other_label values periodically and promote frequent ones into the enum. See Enum with Fallback.