DEV Community

shashank ms
shashank ms

Posted on

Unlocking Natural Language Processing with LLMs

We are going to build a support ticket triage agent that reads raw customer messages and returns structured NLP output: sentiment, product mentions, urgency, and a one-line summary. If your team wastes hours manually categorizing inbound text, this turns an LLM into a drop-in classifier and extractor.

What you'll need

Step 1: Connect to Oxlo.ai

I start by initializing the OpenAI SDK against Oxlo.ai and making a smoke test. I pick llama-3.3-70b because it follows instructions reliably for structured tasks.

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": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Reply with exactly the word: pong"},
    ],
)

print(response.choices[0].message.content)

Step 2: Write the system prompt

The system prompt is the contract. It tells the model to act as a JSON-only parser and sets the schema for sentiment, entities, urgency, and summary. I keep it strict so downstream code does not need fuzzy parsing.

SYSTEM_PROMPT = """You are a support ticket NLP engine. Analyze the user message and respond with a single JSON object. Do not include markdown fences, explanations, or greetings.

Required schema:
- sentiment: string, one of [angry, frustrated, neutral, satisfied]
- product: string, the product mentioned or "unknown"
- urgency: string, one of [low, medium, high, critical]
- summary: string, max 12 words describing the core issue
- entities: list of objects with keys "text" and "type" (person, company, feature)

Rules:
- If no product is mentioned, use "unknown".
- Urgency is critical if words like "down", "broken", "outage", "security" appear.
- Output must be valid, minified JSON.
"""

Step 3: Build the analysis function

Now I wrap the API call in a function that takes raw ticket text and returns a Python dict. I set temperature low to keep output deterministic.

import json

def analyze_ticket(ticket_text: str) -> dict:
    response = client.chat.completions.create(
        model="llama-3.3-70b",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": ticket_text},
        ],
        temperature=0.1,
        max_tokens=256
    )

    raw = response.choices[0].message.content.strip()
    if raw.startswith("

```"):
        raw = raw.split("```

")[1].replace("json", "").strip()

    return json.loads(raw)

Step 4: Process tickets in batch

In production, tickets arrive as a list. I process them sequentially here. Oxlo.ai has no cold starts on popular models, so the loop runs without lag.

tickets = [
    "Our API integration with your platform stopped responding this morning. We are losing transactions. Please escalate immediately. - Sarah, AcmeCorp",
    "Can you add dark mode to the dashboard? It would be nice to have.",
    "Invoice #9922 is wrong. We were charged for 3 seats but only have 2. Not urgent, just fix before next billing cycle.",
    "SECURITY: we noticed an exposed token in your public docs. Rotate it now."
]

results = []
for t in tickets:
    try:
        parsed = analyze_ticket(t)
        results.append(parsed)
        print(f"Processed: {parsed['summary']}")
    except Exception as e:
        results.append({"error": str(e), "raw": t})
        print(f"Failed to parse ticket: {e}")

print(f"\nSuccessfully analyzed {len([r for r in results if 'error' not in r])} of {len(tickets)} tickets.")

Step 5: Handle multilingual input

If your queue contains non-English text, Oxlo.ai hosts qwen-3-32b, which handles multilingual reasoning well. You can swap the model string without changing any other code because the API is fully OpenAI compatible.

def analyze_ticket_multilingual(ticket_text: str) -> dict:
    response = client.chat.completions.create(
        model="qwen-3-32b",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": ticket_text},
        ],
        temperature=0.1,
        max_tokens=256
    )
    raw = response.choices[0].message.content.strip()
    return json.loads(raw)

Run it

Save the full script below as ticket_triage.py, replace YOUR_OXLO_API_KEY, and run python ticket_triage.py.

from openai import OpenAI
import json

client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")

SYSTEM_PROMPT = """You are a support ticket NLP engine. Analyze the user message and respond with a single JSON object. Do not include markdown fences, explanations, or greetings.

Required schema:
- sentiment: string, one of [angry, frustrated, neutral, satisfied]
- product: string, the product mentioned or "unknown"
- urgency: string, one of [low, medium, high, critical]
- summary: string, max 12 words describing the core issue
- entities: list of objects with keys "text" and "type" (person, company, feature)

Rules:
- If no product is mentioned, use "unknown".
- Urgency is critical if words like "down", "broken", "outage", "security" appear.
- Output must be valid, minified JSON.
"""

def analyze_ticket(ticket_text: str, model: str = "llama-3.3-70b") -> dict:
    response = client.chat.completions.create(
        model=model,
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": ticket_text},
        ],
        temperature=0.1,
        max_tokens=256
    )
    raw = response.choices[0].message.content.strip()
    if raw.startswith("

```"):
        raw = raw.split("```

")[1].replace("json", "").strip()
    return json.loads(raw)

if __name__ == "__main__":
    tickets = [
        "Our API integration with your platform stopped responding this morning. We are losing transactions. Please escalate immediately. - Sarah, AcmeCorp",
        "Can you add dark mode to the dashboard? It would be nice to have.",
        "Invoice #9922 is wrong. We were charged for 3 seats but only have 2. Not urgent, just fix before next billing cycle.",
        "SECURITY: we noticed an exposed token in your public docs. Rotate it now."
    ]

    for t in tickets:
        try:
            out = analyze_ticket(t)
            print(json.dumps(out, indent=2))
        except Exception as e:
            print(f"Error: {e}")

Example output:

{"sentiment": "angry", "product": "API integration", "urgency": "critical", "summary": "API integration down, losing transactions", "entities": [{"text": "Sarah", "type": "person"}, {"text": "AcmeCorp", "type": "company"}]}
{"sentiment": "neutral", "product": "dashboard", "urgency": "low", "summary": "Request for dark mode on dashboard", "entities": [{"text": "dark mode", "type": "feature"}]}
{"sentiment": "frustrated", "product": "unknown", "urgency": "medium", "summary": "Incorrect invoice for seat count", "entities": [{"text": "Invoice #9922", "type": "feature"}]}
{"sentiment": "frustrated", "product": "unknown", "urgency": "critical", "summary": "Exposed security token in public docs", "entities": [{"text": "token", "type": "feature"}]}

Wrap up

Two concrete next steps. First, wire this function into a webhook so new tickets are scored as they arrive in your CRM. Second, if your volume grows, compare Oxlo.ai request-based pricing against your current token-based bill. For long tickets, the flat per-request cost often drops the price significantly. You can check the latest rates at https://oxlo.ai/pricing.

Top comments (0)