Skip to content
TheThinkLoop

Template - Support

Predicate

Support escalation

Whether a conversation should move from a frontline agent to a senior one.

A predicate decision that catches conversations going wrong, such as repeated contacts, rising frustration, and legal threats, before the customer asks for a manager.

The decision

PredicateA probability from 0 to 1 that the condition holds.

Should this conversation be escalated to a senior agent?

Evidence checks (asked in the same request)

  • Repeat contact: The customer has contacted us about this before.
  • Negative sentiment: The customer expresses frustration or dissatisfaction.
  • Legal or chargeback risk: The customer mentions a chargeback, bank dispute, or legal action.

Expected output: A probability from 0 to 1 that the conversation should be escalated, plus one probability per evidence check.

Input

The Decisions API reads one input. Combine these fields into it as labeled text so the model sees the facts the decision depends on.

Input fields
FieldTypeRequiredDescription
conversationstringYesThe customer's latest message, ideally with the previous two or three turns.
contact_countnumberNoHow many times the customer has contacted you about this issue.

Worked examples

  1. Third contact, asking for a manager

    This is the third time I'm asking. Nobody has replied in two weeks and this is unacceptable. I want to speak to a manager today.

    A careful reviewer would say: Yes. Repeated contact, clear frustration, and an explicit request for a manager.

    Run this example
  2. A thank-you after a fix

    Thanks for the quick fix yesterday. Everything works now. Appreciate it!

    A careful reviewer would say: No. The issue is resolved and the customer is satisfied.

    Run this example

Expected answers are human judgments written for this template, not model output.

How it works

Customers who ask for a manager have usually been unhappy for a while. Escalating one contact earlier, before the demand, tends to cost less than recovering afterwards.

Include conversation history in the input when you can. A single message rarely shows that this is the third attempt unless the customer says so.

Human review and thresholds

Recommended review policy

Because escalation only hands the conversation to a senior agent, automating "Yes" carries little risk. Guard against the opposite failure by reviewing a sample of conversations that were not escalated and ended badly.

Choosing thresholds

Set the bar by your senior team's capacity. Start high, measure how many escalations were warranted, and lower it until the queue is as full as you want it.

Starting automation threshold
80%
Starting don’t-decide threshold
55%

Starting points for the playground, not recommendations. The right values depend on your costs and on how the model’s confidence tracks accuracy on your data. Calibrate them.

Limitations

  • Without history, the model relies on the customer mentioning previous contacts.
  • Some customers write forcefully about small problems. Sentiment alone over-escalates; the repeat-contact check is the more reliable signal.
  • Escalation capacity is finite. If everything escalates, nothing has.

Use it in your code

The template definition is plain JSON: the question, the evidence checks, the input fields, and the starting policy. The SDK call below sends the same question and checks to the Decisions API from your server.

support-escalation.jsonjson
{
  "$format": "thethinkloop.template/v1",
  "slug": "support-escalation",
  "title": "Support escalation",
  "decides": "Whether a conversation should move from a frontline agent to a senior one.",
  "question": {
    "name": "decision",
    "type": "predicate",
    "instructions": "Should this conversation be escalated to a senior agent?"
  },
  "evidenceChecks": [
    {
      "name": "factor_1",
      "label": "Repeat contact",
      "type": "predicate",
      "instructions": "The customer has contacted us about this before."
    },
    {
      "name": "factor_2",
      "label": "Negative sentiment",
      "type": "predicate",
      "instructions": "The customer expresses frustration or dissatisfaction."
    },
    {
      "name": "factor_3",
      "label": "Legal or chargeback risk",
      "type": "predicate",
      "instructions": "The customer mentions a chargeback, bank dispute, or legal action."
    }
  ],
  "inputs": [
    {
      "name": "conversation",
      "type": "string",
      "required": true,
      "description": "The customer's latest message, ideally with the previous two or three turns."
    },
    {
      "name": "contact_count",
      "type": "number",
      "required": false,
      "description": "How many times the customer has contacted you about this issue."
    }
  ],
  "expectedOutput": "A probability from 0 to 1 that the conversation should be escalated, plus one probability per evidence check.",
  "examples": [
    {
      "title": "Third contact, asking for a manager",
      "input": "This is the third time I'm asking. Nobody has replied in two weeks and this is unacceptable. I want to speak to a manager today.",
      "expected": "Yes"
    },
    {
      "title": "A thank-you after a fix",
      "input": "Thanks for the quick fix yesterday. Everything works now. Appreciate it!",
      "expected": "No"
    }
  ],
  "startingPolicy": {
    "automateAt": 0.8,
    "abstainBelow": 0.55,
    "note": "A starting point for exploration, not a recommendation. Calibrate against your own labeled examples."
  }
}
Equivalent SDK calljavascript
import OpenAI from "openai"; // openai >= 7.30.0

const client = new OpenAI(); // reads OPENAI_API_KEY on the server

const decision = await client.decisions.create({
  model: "gpt-6-luna",
  input: "This is the third time I'm asking. Nobody has replied in two weeks and this is unacceptable. I want to speak to a manager today.",
  questions: [
    {
      type: "predicate",
      name: "decision",
      instructions: "Should this conversation be escalated to a senior agent?"
    },
    {
      type: "predicate",
      name: "factor_1",
      instructions: "The customer has contacted us about this before."
    },
    {
      type: "predicate",
      name: "factor_2",
      instructions: "The customer expresses frustration or dissatisfaction."
    },
    {
      type: "predicate",
      name: "factor_3",
      instructions: "The customer mentions a chargeback, bank dispute, or legal action."
    }
  ],
});

// Answers come back in question order. A question can also be refused.
const [main, ...checks] = decision.answers;
if (main.type === "refusal") throw new Error("The model declined to answer.");
if (main.type === "predicate") {
  console.log(main.probability); // 0–1 estimate that the condition is true
}

Download it as support-escalation.json, or browse all developer resources.

Need this decision tuned to your policy?

We are running a small number of pilots with B2B teams: your policy, your examples, your thresholds. Request early access.