> Source: https://builder.ema.ai/v2/agent-reference/intent-classification
> Title: Intent Classifier Agent

# Intent Classifier Agent

The Intent Classifier Agent (`intent_classification`) reads the input and classifies it into **exactly one** of a set of labels you configure. Its output feeds the conditional edges on your workflow, so the rest of the workflow can branch based on what the input is about — sending billing questions down one path and technical questions down another, for example.

The label decision stays in the agent; the routing decision stays in the workflow engine. The agent emits a label and the workflow's edge conditions act on it. That separation is what lets one classification node fan out to any number of downstream branches.

The Intent Classifier Agent belongs to the **Frequently Used** group in the agent library.

## Configuration

You configure the agent through `agent_config.type_config`. The one required field is `intents`.

### Intents

`intents` is a list of the labels the agent can choose from. Each entry is either a plain string label or a rich object — and you can mix both in one list.

```json
{
  "intents": [
    "billing",
    {
      "label": "technical_support",
      "description": "Questions about errors, outages, or how to use the product.",
      "examples": ["my dashboard won't load", "how do I reset my API key"]
    },
    {
      "label": "sales",
      "description": "Pricing, plans, and upgrade questions."
    }
  ]
}
```

Field

Required

Purpose

`label`

Yes (for object form)

The label value the agent returns.

`description`

No

A one-line guide that disambiguates the label for the model. Improves accuracy on ambiguous input.

`examples`

No

Sample utterances that should classify to this label. An exact (case-insensitive) match to a single intent's example short-circuits to that label without an LLM call.

`rule`

No

An eligibility condition evaluated before classification. See [per-intent eligibility rules](#per-intent-eligibility-rules).

### Default intent

Set an optional `default_intent` so the agent has a safety net when the model returns a label that isn't in your list:

```json
{
  "intents": ["billing", "technical_support", "sales"],
  "default_intent": "billing"
}
```

If the model's label doesn't match a configured intent and no `default_intent` is set, the run fails with an output-validation error instead of returning an unroutable label.

### Per-intent eligibility rules

An intent can carry an optional `rule` — a condition that must hold for the intent to be eligible at all. Rules are evaluated against the request's `user_context` _before_ the prompt is built, so an ineligible intent never reaches the model. This is useful for gating an intent on who the user is — for example, only offering an "internal\_escalation" label to employees.

Field paths in a rule are rooted at `user_context` (for example, `user_context.attributes.department`). Rules use the canonical condition shape shared with workflow edge conditions:

```json
{
  "intents": [
    {
      "label": "internal_escalation",
      "description": "Route to the internal escalation queue.",
      "rule": {
        "type": "field",
        "field": "user_context.attributes.is_employee",
        "operator": "eq",
        "value": true
      }
    },
    "general_support"
  ]
}
```

If every intent's rule fails, the agent returns a graceful "no intent matched" response rather than invoking the model. Legacy rule payloads (the `{condition, expressions}` shape with SCREAMING\_CASE operators) are accepted and normalized to the canonical form automatically; write canonical going forward.

## Inputs and output

The agent expects the text to classify on the `instructions` input key. Wire whatever the upstream node produces — a user message, a ticket body, an extracted field — to `instructions` via the node's `input_mapping`.

**Input**

```json
{ "instructions": "My last invoice looks wrong, who do I talk to?" }
```

**Output**

```json
{
  "reasoning": "The user is asking about an invoice, which relates to billing.",
  "intent": "billing"
}
```

The output's implicit schema in the catalog is:

```json
{
  "properties": { "intent": { "type": "string" } },
  "required": ["intent"]
}
```

The model also produces a `reasoning` field (chain-of-thought to improve accuracy on ambiguous input); it is parsed for tracing but `intent` is the value downstream edges act on.

## Routing on the result

Downstream edges typically condition on the output label, for example `{output.intent eq "billing"}`. Add one outgoing branch per label you care about, plus a fallback for anything that maps to your `default_intent`. Because classification is a single-label decision, exactly one branch fires per run.

## Validation behavior

-   The returned label is matched case-insensitively against your configured intents and normalized to the configured casing.
-   Code fences and minor formatting noise around the JSON are stripped before parsing; the agent also recovers a JSON object embedded in surrounding prose.
-   An unmatched label falls back to `default_intent` if set, otherwise fails the run.

## Notes and limits

-   A classification node returns one label per run. For inputs that could match several categories at once, model that as separate classification nodes or a [Custom Agent](/builder/v2/agent-reference/custom) with a structured output schema.
-   The intents list must contain at least one entry.

## What's next

-   [Agent Reference overview](/builder/v2/agent-reference) — how agents work, the catalog, the four builder groups, and the shared execution engine.
-   [Search & Respond Agent](/builder/v2/agent-reference/search-and-respond) — answer from knowledge bases with citations.
