We are going to build a support ticket triage CLI that classifies incoming customer messages by urgency and category, then drafts an internal summary and next action. It helps small support teams route requests automatically instead of reading every thread manually. I will wire it to Oxlo.ai so each classification costs one flat request, which keeps pricing predictable even when customers paste long logs or conversation histories.
What you'll need
Python 3.10 or newer, the OpenAI SDK installed with pip install openai, and an Oxlo.ai API key from https://portal.oxlo.ai. Export the key in your shell before running the script.
Step 1: Configure the client
First I create an OpenAI client pointed at Oxlo.ai and verify connectivity with a single call to the general-purpose Llama 3.3 70B model.
from openai import OpenAI
client = OpenAI(
base_url="https://api.oxlo.ai/v1",
api_key="YOUR_OXLO_API_KEY"
)
response = client.chat.completions.create(
model="llama-3.3-70b",
messages=[{"role": "user", "content": "Reply with OK if you are live."}],
)
print(response.choices[0].message.content)
Step 2: Define the system prompt
The agent needs a strict persona and output format so we can parse the result reliably. I prompt for a JSON object with four fields.
SYSTEM_PROMPT = """You are a tier-1 support analyst triaging incoming tickets.
Read the customer message and return a single JSON object with these keys:
- urgency: one of low, medium, high, critical
- category: one of billing, technical, account, general
- summary: a one-sentence internal summary
- action: the single next step the team should take
Return only valid JSON. Do not wrap it in markdown."""
Step 3: Build the triage function
Next I wrap the API call in a small function. I use JSON mode to constrain the model output, then parse the result with the standard library.
import json
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.oxlo.ai/v1",
api_key=os.environ.get("OXLO_API_KEY")
)
def triage(text: str) -> dict:
response = client.chat.completions.create(
model="llama-3.3-70b",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": text},
],
response_format={"type": "json_object"},
temperature=0.2,
)
raw = response.choices[0].message.content
return json.loads(raw)
Step 4: Batch process tickets
Finally I define a list of raw customer messages and loop through them. In production you might read these from a webhook or mailbox, but a static list is enough to prove the pipeline.
TICKETS = [
"I was charged twice for my subscription this month. Please refund the extra $49.",
"The API returns a 500 error every time I send a request with Unicode characters. Here is my curl log...",
"How do I change the profile picture on my account? I looked in settings but could not find it.",
]
for ticket in TICKETS:
result = triage(ticket)
print(f"---\nTicket: {ticket[:60]}...")
print(json.dumps(result, indent=2))
Run it
Save the full script as triage.py, export your key, and run it.
export OXLO_API_KEY="sk-oxlo.ai-..."
python triage.py
On my machine the output looks like this:
---
Ticket: I was charged twice for my subscription this month. Please ref...
{
"urgency": "high",
"category": "billing",
"summary": "Customer reports a duplicate subscription charge and requests a refund.",
"action": "Verify the duplicate charge in Stripe and issue a refund for $49."
}
---
Ticket: The API returns a 500 error every time I send a request with ...
{
"urgency": "critical",
"category": "technical",
"summary": "API crashes on requests containing Unicode characters.",
"action": "Escalate to the engineering team with the attached curl log."
}
---
Ticket: How do I change the profile picture on my account? I looked i...
{
"urgency": "low",
"category": "account",
"summary": "Customer needs help locating the profile picture upload feature.",
"action": "Send a link to the account settings docs with screenshot instructions."
}
Next steps
Replace the static TICKETS list with a FastAPI endpoint that receives webhooks from your helpdesk, or swap the model string to kimi-k2.6 if you want to process vision tickets that include screenshots. Because Oxlo.ai uses request-based pricing (see https://oxlo.ai/pricing), adding longer context or switching to a larger reasoning model does not inflate the per-call cost.
Top comments (0)