Insurge
AI Automation

How Do You Automatically Classify Sales Replies With AI?

By Saif Khan · 2026.07.06

Sales reply classification is not a sentiment-analysis problem. It is a workflow-routing problem. Learn how to design an intent taxonomy, extract multiple commercial signals, validate structured outputs, route uncertainty to humans, and evaluate the system before it controls CRM state.

A prospect replies to your sales email:

Sounds interesting, but we're buried until August. Can you send pricing and try me after the 15th?

Was that a positive reply?

Yes.

Was it a timing objection?

Also yes.

Did the prospect ask a pricing question?

Yes.

Did they give you a callback instruction?

Yes.

A classifier that returns positive has technically classified the message correctly and still destroyed most of the commercially useful information in it.

This is the central problem with many AI sales-reply workflows.

They treat reply classification as sentiment analysis.

Sales reply classification is not a sentiment-analysis problem. It is a workflow-routing problem.

The purpose of classification is not to describe how a message feels. The purpose is to convert an unstructured reply into enough reliable state for the rest of the sales system to decide what happens next.

That changes how you design the taxonomy, the model output, the confidence policy, the human-review path, and the evaluation dataset.

Start with the action the system needs to take

Before creating labels, list the downstream actions your sales workflow can perform.

For example:

  • stop automated follow-up
  • route to the account owner
  • create a callback task
  • schedule a future lead evaluation
  • send a permitted informational response
  • place the contact on a suppression list
  • request human review
  • update a CRM field
  • leave the lead in its current state

Now work backwards.

What information must be extracted from a reply to choose between those actions?

You may need to know:

  • whether there is commercial interest
  • whether the lead is explicitly declining
  • whether the lead wants no further contact
  • whether timing is the blocker
  • whether a callback date was stated
  • whether a question requires an answer
  • whether pricing was requested
  • whether the person is referring you to someone else
  • whether they are out of office
  • whether the message is an automated system response
  • whether the reply is too ambiguous for automation

This is a better starting point than copying a generic positive / negative / neutral taxonomy from a sentiment-analysis tutorial.

Your intent taxonomy should be derived from workflow decisions.

One sales reply can contain multiple intents

Real messages are compositional.

Consider:

Not this quarter. Budget is frozen, but send the case study you mentioned and ping me in October.

A single-label classifier is forced to compress that reply into one category.

negative loses the future opportunity.

positive ignores the current timing constraint.

callback_requested loses the content request.

A more useful representation separates the dimensions of the reply:

```json{ "primary_intent": "follow_up_later", "secondary_intents": [ "budget_constraint", "content_requested" ], "commercial_state": "interested_not_ready", "callback_date": "2026-10-01", "requested_information": ["case_study"], "do_not_contact": false, "requires_response": true, "recommended_route": "sales_owner"}```

This is a multi-label classification problem, not merely a single-label one. Research on LLM multi-label classification has found that autoregressive models behave differently when several relevant labels must be generated, including a tendency to suppress all but one label at each generation step. That does not mean LLMs cannot perform the task. It means you should evaluate the task you actually have rather than assuming single-intent performance transfers cleanly to multi-intent sales replies.

```mermaidflowchart LR A[Inbound Reply] --> B[Interpretation] B --> C[Primary Intent] B --> D[Secondary Intents] B --> E[Entities and Dates] B --> F[Commercial State] B --> G[Safety / Suppression Signals] C --> H[Policy Layer] D --> H E --> H F --> H G --> H H --> I[Route / Schedule / Stop / Review]```

The model interprets the message.

The workflow policy decides what those interpretations are allowed to trigger.

Separate interpretation from decision authority

This is the most important architectural boundary in the system.

Suppose the model returns:

```json{ "primary_intent": "positive_interest", "commercial_state": "qualified_interest", "requires_response": true}```

Should the model now update the opportunity to Qualified, send pricing, book a meeting, and assign the deal to an enterprise salesperson?

Not necessarily.

The classifier has produced an interpretation.

Your business still needs a decision layer.

```mermaidflowchart TD A[Reply] --> B[AI Interpretation] B --> C[Schema Validation] C --> D[Deterministic Policy] D --> E{Action risk} E -- Low --> F[Permitted automated action] E -- Medium --> G[Propose action] E -- High --> H[Human approval] F --> I[CRM / Workflow State Transition] G --> J[Review Queue] H --> J```

For example:

  • do_not_contact = true may deterministically suppress future automated outreach.
  • callback_date may create a future evaluation, provided the date passes validation.
  • pricing_question may route the reply to the owner.
  • positive_interest may stop the current sequence and create a sales task.
  • a request for a custom discount may always require a human.

The prompt should not quietly become your sales policy.

Let the model interpret language. Let your application enforce business rules.

Use structured outputs, not prose you hope to parse

A production workflow should not ask the model:

Tell me what this prospect means.

and then feed a paragraph into a Switch node looking for the word positive.

Define an output contract.

Modern model APIs support schema-constrained structured outputs. OpenAI's current Structured Outputs documentation, for example, explicitly describes defining a JSON schema that model responses must adhere to. The implementation details vary by provider, but the architectural principle is provider-independent: downstream workflow control should consume typed fields with a known shape.

A simplified schema might include:

```json{ "primary_intent": "callback_requested", "secondary_intents": ["pricing_question"], "commercial_state": "interested_not_ready", "callback_date": "2026-08-15", "requested_information": ["pricing"], "do_not_contact": false, "requires_response": true, "recommended_route": "sales_owner"}```

Schema adherence solves one class of failure: malformed or unpredictable output shape.

It does not prove that the classification is correct.

A perfectly valid JSON object can contain the wrong intent.

That distinction is easy to miss.

Format reliability and semantic accuracy are separate evaluation problems.

Design the taxonomy around commercial state

A useful taxonomy is specific enough to drive action but small enough to evaluate.

You might start with primary intents such as:

| Intent | Meaning | Typical workflow effect || --- | --- | --- || positive_interest | Prospect indicates current interest | Stop sequence and route to sales || follow_up_later | Interest may exist but timing is deferred | Extract timing and schedule reevaluation || negative_interest | Prospect declines the offer | Stop current follow-up || do_not_contact | Explicit request for no further contact | Suppress according to policy || question | Prospect requires information before progressing | Route or answer under an approved policy || referral | Prospect points to another person | Extract referral context and route || out_of_office | Automated absence response | Defer evaluation || automated_response | Non-human system message | Do not treat as sales intent || ambiguous | Meaning is insufficiently clear | Human review |

Then add secondary labels for commercially useful details:

  • pricing question
  • integration question
  • budget constraint
  • timing constraint
  • competitor mention
  • security concern
  • procurement requirement
  • content requested
  • callback requested

Do not create 80 labels on day one because the model can theoretically return them.

Every label creates an evaluation and policy burden.

If two labels always trigger the same action and nobody uses the distinction analytically, ask whether you need both.

Dates and entities need validation after extraction

A prospect writes:

Try me after the 15th.

The model may extract a date.

But which month?

What timezone?

Does “after the 15th” mean the 16th at 9:00 AM, the next business day, or merely a broad timing signal?

The classifier should be allowed to express uncertainty or incomplete information.

For example:

```json{ "callback_requested": true, "callback_date": null, "callback_date_text": "after the 15th", "date_resolution": "ambiguous"}```

A deterministic date parser or a second resolution step can then use message timestamp, locale, CRM geography, and business rules.

The same principle applies to:

  • currency
  • quantities
  • product names
  • company names
  • phone numbers
  • named salespeople

Do not assume that because the model emitted a typed field, the value is operationally valid.

Validate values at the application boundary.

Be careful with model-generated confidence scores

It is tempting to ask the model to return:

```json{ "intent": "positive_interest", "confidence": 0.94}```

and then automate everything above 0.90.

That number looks scientific.

It may not be calibrated to the real probability that the classification is correct.

Recent research continues to show that LLM confidence calibration is a distinct technical problem, particularly when tasks permit multiple valid answers. For a multi-intent reply, disagreement between plausible label sets can make naive confidence interpretation especially difficult.

Treat self-reported confidence as a signal to evaluate, not a universal probability.

A stronger routing policy can combine several factors:

  • intent class
  • action risk
  • known hard rules
  • model agreement or repeated evaluation where justified
  • historical error rate for that class
  • presence of ambiguous dates or entities
  • whether the message contains multiple intents
  • whether the reply falls outside the known taxonomy

For example:

```textexplicit do-not-contact phrase→ deterministic suppression rule + audit

out-of-office with return date→ low-risk automated defer

positive intent + pricing question→ stop sequence + route to owner

custom commercial request→ mandatory human review

unknown / conflicting intents→ human review```

The decision boundary should reflect the cost of being wrong.

Misclassifying an out-of-office reply may delay a follow-up.

Misclassifying “do not contact me again” as a timing objection can create a much more serious problem.

Deterministic rules still have a place

Using an LLM does not mean every message should be interpreted only by an LLM.

Some signals are explicit enough to handle deterministically or use as overrides.

Examples may include:

  • provider-specific bounce events
  • known auto-reply headers
  • explicit suppression records
  • structured form responses
  • CRM state that makes the reply irrelevant to the current sequence

You may also use deterministic pre-processing to remove quoted thread history, normalize signatures, identify the newest reply segment, and attach CRM context before classification.

A useful system is often a composition of rules and models.

The question is not “Can AI classify this?”

The question is “Which component gives us the most reliable interpretation at an acceptable operational cost?”

Build a human review queue for ambiguity

ambiguous is not a failed classification.

It is a valid system outcome.

Consider:

Maybe. Send something over and I'll take a look when things calm down.

There is weak interest, no clear timing, a content request with unspecified content, and no obvious next action.

Forcing this into positive or negative creates false certainty.

A review queue should show the human:

  • the latest reply
  • relevant thread context
  • CRM owner and opportunity
  • model interpretation
  • extracted entities
  • proposed action
  • reason for review

The reviewer should be able to correct the classification and choose the action.

Those corrections are valuable evaluation data.

```mermaidflowchart LR A[Ambiguous Reply] --> B[Review Queue] B --> C[Human Corrects Intent] B --> D[Human Approves Action] C --> E[Evaluation Dataset] D --> F[Workflow Execution] E --> G[Prompt / Model Evaluation]```

Do not hide uncertainty from operations. Design a place for it to go.

Evaluate on your real reply distribution

A prompt that correctly classifies ten hand-written examples is not a production evaluation.

Build a dataset from historical replies, with appropriate data handling and access controls.

Include the ugly cases:

  • one-word replies
  • sarcasm
  • forwarded messages
  • long quoted threads
  • replies containing two or three intents
  • out-of-office messages
  • angry opt-outs
  • soft rejections
  • vague timing
  • referral replies
  • non-English replies if your sales process receives them
  • misspellings
  • signatures that contain misleading keywords

OpenAI's current evaluation guidance recommends defining the objective, collecting a representative dataset, defining metrics, running and comparing evals, and continuously evaluating changes. It also explicitly warns against “vibe-based evals” and notes that classification or scoring tasks are often easier to evaluate reliably than open-ended generation.

For reply classification, measure per-class performance.

Overall accuracy can hide dangerous errors.

Suppose 70% of your replies are no_response_context or automated messages. A classifier can look impressive overall while performing badly on the rare do_not_contact class that carries a much higher error cost.

Track:

  • precision by intent
  • recall by intent
  • F1 by intent where useful
  • confusion between commercially important classes
  • extraction accuracy for dates and requested information
  • human-review rate
  • false automation rate
  • percentage of replies outside the taxonomy

For multi-label intents, evaluate the label set, not just the primary label.

Most importantly, maintain a cost-weighted error view.

A false positive on positive_interest is not necessarily equivalent to missing a suppression request.

Version the classifier like production logic

If a classification can change CRM state or trigger sales actions, track what produced it.

Persist at least:

  • classifier version
  • prompt or policy version
  • model identifier
  • input message reference
  • relevant context reference
  • raw structured output
  • validated output
  • final routed action
  • whether a human corrected it

When the sales team says, “The system started routing weird replies last week,” you need more than the current prompt in an n8n node.

You need to know what changed.

This is also how you compare a new classifier against the previous version before rollout.

Run both on a fixed evaluation set. Compare the confusion matrix. Inspect the disagreements. Pay particular attention to high-cost classes.

A model upgrade is not automatically a classifier upgrade.

The minimum viable sales reply classification system

A credible first version needs:

  1. 1.
    Reply ingestion from the channels you support.
  2. 2.
    Thread normalization so the classifier sees the relevant reply and useful context.
  3. 3.
    A defined intent taxonomy derived from downstream workflow decisions.
  4. 4.
    Structured classification output with a validated schema.
  5. 5.
    Entity extraction for dates, requested information, referrals, and other useful signals.
  6. 6.
    Deterministic overrides for explicit or provider-level signals where appropriate.
  7. 7.
    A policy layer that maps interpretation to permitted actions.
  8. 8.
    Human review for ambiguous and higher-risk cases.
  9. 9.
    CRM state transitions and write-back so sales sees the result.
  10. 10.
    An evaluation dataset built from representative historical replies.
  11. 11.
    Versioning and audit history for the classifier and routed actions.

```mermaidflowchart TD A[Email / SMS / Messaging Reply] --> B[Normalize Thread] B --> C[Attach Relevant CRM Context] C --> D[Structured AI Classification] D --> E[Schema and Value Validation] E --> F[Deterministic Overrides] F --> G[Workflow Policy] G --> H{Safe to automate?} H -- Yes --> I[Execute Permitted Action] H -- No --> J[Human Review] I --> K[CRM Write-Back] J --> K J --> L[Evaluation Dataset] K --> M[Audit History]```

Classify for the workflow, not for the dashboard

The easiest sales reply classifier to build is one that puts every message into positive, negative, or neutral and produces a clean chart.

The more useful system understands that a single reply can contain interest, a timing constraint, a question, and an instruction at the same time.

Start with the decisions your workflow needs to make.

Design the taxonomy around those decisions. Extract multiple commercial signals where they coexist. Require structured outputs. Validate operational values. Route uncertainty somewhere. Evaluate on real replies. Weight errors by their business cost.

If you are building the broader execution layer around your CRM, read How Do I Automatically Follow Up With Leads Without Replacing My CRM?.

If you are using this classifier to revive old opportunities, read How Do You Revive Dormant Leads Already Sitting in Your CRM?.

The goal is not to make AI understand whether an email sounds happy or sad.

The goal is to turn an unstructured reply into controlled, inspectable commercial state that your revenue workflow can safely act on.

Sources and further reading

  • OpenAI API documentation: Structured model outputs
  • OpenAI API documentation: Evaluation best practices
  • Ma et al. (2025), “Large Language Models Do Multi-Label Classification Differently”
  • Wang et al. (2026), “Evaluating and Calibrating LLM Confidence on Questions with Multiple Correct Answers”
Author
Saif Khan, Principal Consultant at Insurge

Saif Khan

Principal Consultant, AI Systems & Automation

Saif Khan is the Principal Consultant at Insurge, where he designs AI automation systems, digital products, and operational infrastructure for service businesses and growth teams. With more than a decade of experience across digital marketing, analytics, marketing technology, and software implementation, his work sits at the intersection of business operations and technical systems. He focuses on turning repetitive workflows, fragmented data, and product ideas into practical automation systems and software that teams can actually operate and scale.