Skip to content

classify

Ask an LLM to bucket free-text input into one of a fixed set of cases. The verdict drives outgoing edges by case:.

Sourceinternal/agents/workflow/nodes/classify.go
BranchingYes — emits verdict
When to useInput is free text and needs to be routed into a small set of cases.

Schema

FieldTypeRequiredNotes
output_casesarrayEnum labels the LLM must pick from. Each becomes a JSON Schema enum value passed to the provider's structured output.
inputtemplateText to classify. Use a template expression like {{index .Event.Payload "text"}}.
providerstringProvider name. Optional — falls back to the default.
fuzzy_matchboolAllow Levenshtein / substring fallback when the model returns a variant (e.g. "bugs" for bug).
retry_on_mismatchintRetry count when the LLM returns an unrecognized label. Each retry tightens the system prompt — costs tokens. Keep ≤ 2.

Output

FieldTypeWhat
verdictstringMatched output_cases label. Edge case: filters route on this. Falls back to "default" after retries fail.
confidencefloat0.0–1.0 score from the provider's structured output. 0 when the provider didn't return one.
reasoningstringShort explanation. Useful as Slack reply or audit; not a routing input.
rawanyRaw provider response — debugging only.
fuzzybooltrue when verdict resolved via fuzzy match instead of exact.

Example

json
{
  "id": "triage",
  "type": "classify",
  "output_cases": ["bug", "feature", "question"],
  "input": "{{index .Event.Payload \"text\"}}",
  "provider": "claude"
}

Reliability stack

Six layers, in order:

  1. Structured output — provider returns one of output_cases directly.
  2. Normalize — strip whitespace, lowercase, collapse to enum.
  3. Exact match vs output_cases.
  4. Fuzzy match (if fuzzy_match: true) — Levenshtein + substring.
  5. Retry on mismatch — re-prompt with a tightened system message.
  6. Confidence threshold fallback → emit "default" so the downstream branch can catch it.

Add a "default" case in your downstream branch to handle the "model gave up" path — otherwise the run dead-ends.

The outgoing edges that route each verdict carry a case: label you can set directly in the canvas editor — see branch ▶ Setting edge cases in the canvas.

Pair with

  • branch / switch — route the verdict.
  • agent — hand the input to a more capable model once routed.

Common pitfalls

  • Forgetting a "default" edge → run dead-ends when the LLM can't decide.
  • High retry_on_mismatch (>2) — burns tokens for diminishing returns. Better to widen output_cases or add fuzzy_match.
Built with ❤️ by a developer, for developers.