Skip to content

Triage a support ticket

Send each incoming ticket to the right team, flag refund requests, and put urgent ones first, with one call.

Keyword rules miss tickets written in Yorùbá, Pidgin or plain frustration, and a chain of LLM prompts is slow and gives answers you can’t threshold. A decision call asks all three questions in one pass and returns a calibrated probability for each, so you can act automatically when the model is sure and hand the rest to a person.

Terminal window
pip install requests
export OLAVERSE_KEY="your-key" # from https://console.olaverselab.com
python triage.py
triage.py
import os
import requests
URL = os.environ.get("OLAVERSE_URL", "https://api.olaverselab.com")
HEADERS = {"Authorization": f"Bearer {os.environ['OLAVERSE_KEY']}"}
def call(path, body):
r = requests.post(f"{URL}{path}", json=body, headers=HEADERS, timeout=120)
r.raise_for_status()
return r.json()
# The questions asked about every ticket. Option keys are yours; the descriptions are what the model reads.
QUESTIONS = {
"team": {"type": "choice", "instructions": "Which team should handle this?",
"criteria": {"billing": "payments, charges and refunds",
"delivery": "orders in transit, late or missing parcels",
"account": "sign-in, profile and security"}},
"refund": {"type": "noul", "instructions": "The customer is asking for money back."},
"urgency": {"type": "score", "instructions": "How urgent is this?",
"criteria": ["can wait", "normal queue", "today", "immediately"]},
}
SURE = 0.9 # act automatically at or above this probability; below it, a person decides
def triage(ticket):
answers = call("/v1/decide", {"state": ticket, "questions": QUESTIONS})["answers"]
team = answers["team"]["choice"]
return {
"queue": team if answers["team"]["probabilities"][team] >= SURE else "triage",
"priority": "high" if answers["urgency"]["score"] >= 2 else "normal",
"refund_review": answers["refund"]["noul"] >= SURE,
}
if __name__ == "__main__":
tickets = [
{"id": "T-1001", "channel": "whatsapp",
"message": "Ẹ jọ̀ọ́, wọ́n ti yọ owó lẹ́ẹ̀mejì lórí káàdì mi. Mo fẹ́ kí ẹ dá owó mi padà."},
{"id": "T-1002", "channel": "email", "message": "Where is my parcel? It was due on Monday."},
{"id": "T-1003", "channel": "chat", "message": "I can't log in since I changed my phone number."},
]
for ticket in tickets:
print(ticket["id"], triage(ticket)) # hand the result to your helpdesk here
Terminal window
curl -X POST "https://api.olaverselab.com/v1/decide" \
-H "Authorization: Bearer $OLAVERSE_KEY" -H "Content-Type: application/json" \
-d '{"state": {"channel": "email", "message": "I was charged twice for order 1182, please refund me today"},
"questions": {
"team": {"type": "choice", "instructions": "Which team should handle this?",
"criteria": {"billing": "payments, charges and refunds", "delivery": "orders in transit", "account": "sign-in and security"}},
"refund": {"type": "noul", "instructions": "The customer is asking for money back."},
"urgency": {"type": "score", "instructions": "How urgent is this?",
"criteria": ["can wait", "normal queue", "today", "immediately"]}}}'

What /v1/decide returns for the first ticket. Values are illustrative.

{
"model": "purplemist-mini-2.0",
"answers": {
"team": {"type": "choice", "choice": "billing",
"probabilities": {"billing": 0.97, "delivery": 0.02, "account": 0.01}, "confidence": 0.88},
"refund": {"type": "noul", "noul": 0.96},
"urgency": {"type": "score", "score": 2.1,
"probabilities": {"0": 0.03, "1": 0.17, "2": 0.46, "3": 0.34},
"legend": {"0": "can wait", "1": "normal queue", "2": "today", "3": "immediately"},
"confidence": 0.14}
},
"usage": {"input_tokens": 312, "output_tokens": 0, "decisions": 3}
}

So the script prints T-1001 {'queue': 'billing', 'priority': 'high', 'refund_review': True}.

  • Thresholds mean what they say. Probabilities are calibrated, so 0.9 (SURE) is right about 9 times in 10. Start there and tune it against a week of your own tickets.
  • Uncertain goes to a person. A team below SURE lands in a triage queue instead of the wrong team.
  • score is the expected level: 2.1 is “around today”, so the ticket is high priority. For the single most likely level, take the highest entry in probabilities.
  • Connect your helpdesk where the script prints: create or update the ticket with the queue, priority and refund flag.
  • More teams: a choice question takes up to 255 options.
  • More questions: add sentiment, language or “mentions a competitor” to QUESTIONS; questions share one pass over the state, so they add no time.
  • A backlog: POST /v1/decide/batch takes 32 tickets per call ({"cases": [{"id": ..., "state": ..., "questions": ...}]}) and counts as one request against your rate limit.