Dev.to AI πŸ€– Ai πŸ‘ 0 πŸ“– 5 min read

Unlocking the Power of LLM for Text Analysis

We are going to build a batch feedback analyzer that reads raw customer support tickets, scores sentiment, extracts topics, and flags urgent issues. It helps support teams prioritize their queue without reading every mes

We are going to build a batch feedback analyzer that reads raw customer support tickets, scores sentiment, extracts topics, and flags urgent issues. It helps support teams prioritize their queue without reading every message manually. I will use Oxlo.ai and the OpenAI SDK so the code is fully runnable against a flat per-request endpoint.

What you'll need

You need Python 3.10 or newer, the OpenAI SDK, and an Oxlo.ai API key. Grab the key from https://portal.oxlo.ai. Install the dependencies with pip.

pip install openai pandas

Step 1: Set up the client

I initialize the OpenAI client pointing at Oxlo.ai. Because Oxlo.ai is fully OpenAI SDK compatible, this is the only change needed from a standard setup.

import os
from openai import OpenAI

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

Step 2: Define the schema and system prompt

I want structured JSON back so I can feed results directly into a dataframe. The system prompt forces exactly three fields: sentiment, topics, and urgent.

SYSTEM_PROMPT = """You are a support ticket analyst. Read the ticket and return ONLY a JSON object with this exact shape:
{
  "sentiment": "positive" | "neutral" | "negative",
  "topics": ["topic_one", "topic_two"],
  "urgent": true | false
}
Rules:
- urgent is true only if the customer mentions a security breach, data loss, payment failure, or service outage.
- topics must be lowercase, one or two words each.
- Do not include markdown or explanation outside the JSON."""

Step 3: Build the analysis function

This function wraps the Oxlo.ai call. I use Llama 3.3 70B because it handles instruction following reliably, and I set the response format to JSON to lock output structure.

import json
from openai import OpenAI

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

SYSTEM_PROMPT = """You are a support ticket analyst. Read the ticket and return ONLY a JSON object with this exact shape:
{
  "sentiment": "positive" | "neutral" | "negative",
  "topics": ["topic_one", "topic_two"],
  "urgent": true | false
}
Rules:
- urgent is true only if the customer mentions a security breach, data loss, payment failure, or service outage.
- topics must be lowercase, one or two words each.
- Do not include markdown or explanation outside the JSON."""

def analyze_ticket(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.1,
    )
    return json.loads(response.choices[0].message.content)

Step 4: Process a batch

I will create a small inline dataset so the script is runnable without external files. In production you would swap this for a CSV read with pandas.

import pandas as pd

tickets = [
    {"id": 101, "body": "I love the new dashboard, but my export failed twice today."},
    {"id": 102, "body": "URGENT: customer credit cards are being double charged since the 2 AM deploy."},
    {"id": 103, "body": "How do I change my notification settings? Thanks."},
]

df = pd.DataFrame(tickets)

df["analysis"] = df["body"].apply(analyze_ticket)

# Flatten the JSON into columns
df = pd.concat([df.drop(columns=["analysis"]), df["analysis"].apply(pd.Series)], axis=1)

print(df[["id", "sentiment", "topics", "urgent"]])

Step 5: Surface urgent issues

Finally, I filter for anything marked urgent and negative sentiment, then print a priority list. This is the exact view I send to the on-call lead each morning.

flagged = df[(df["urgent"] == True) & (df["sentiment"] == "negative")]

if flagged.empty:
    print("No urgent negative tickets.")
else:
    for _, row in flagged.iterrows():
        print(f"Ticket {row['id']}: {row['body']}")
        print(f"  Topics: {', '.join(row['topics'])}")
        print()

Run it

Here is the complete script. Save it as feedback_analyzer.py, export your key, and run it.

import json
import os
import pandas as pd
from openai import OpenAI

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

SYSTEM_PROMPT = """You are a support ticket analyst. Read the ticket and return ONLY a JSON object with this exact shape:
{
  "sentiment": "positive" | "neutral" | "negative",
  "topics": ["topic_one", "topic_two"],
  "urgent": true | false
}
Rules:
- urgent is true only if the customer mentions a security breach, data loss, payment failure, or service outage.
- topics must be lowercase, one or two words each.
- Do not include markdown or explanation outside the JSON."""

def analyze_ticket(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.1,
    )
    return json.loads(response.choices[0].message.content)

tickets = [
    {"id": 101, "body": "I love the new dashboard, but my export failed twice today."},
    {"id": 102, "body": "URGENT: customer credit cards are being double charged since the 2 AM deploy."},
    {"id": 103, "body": "How do I change my notification settings? Thanks."},
]

df = pd.DataFrame(tickets)
df["analysis"] = df["body"].apply(analyze_ticket)
df = pd.concat([df.drop(columns=["analysis"]), df["analysis"].apply(pd.Series)], axis=1)

print(df[["id", "sentiment", "topics", "urgent"]])
print()

flagged = df[(df["urgent"] == True) & (df["sentiment"] == "negative")]

if flagged.empty:
    print("No urgent negative tickets.")
else:
    for _, row in flagged.iterrows():
        print(f"Ticket {row['id']}: {row['body']}")
        print(f"  Topics: {', '.join(row['topics'])}")
        print()

Execute it from your terminal:

export OXLO_API_KEY="sk-oxlo.ai-..."
python feedback_analyzer.py

When I ran this against Oxlo.ai, the output looked like this:

    id sentiment                 topics  urgent
0  101  negative  [export, dashboard]   False
1  102  negative    [payment, billing]    True
2  103   neutral       [notifications]   False

Ticket 102: URGENT: customer credit cards are being double charged since the 2 AM deploy.
  Topics: payment, billing

Wrap up

This pipeline gives you a working text analysis layer in under fifty lines of code. Two concrete ways to extend it: first, schedule the script as a nightly cron job and POST flagged tickets to a Slack webhook so the team sees them first thing. Second, swap in DeepSeek V3.2 or Kimi K2.6 if you want heavier reasoning for multi-step classification tasks. Because Oxlo.ai uses flat per-request pricing, you can process large backlogs without the cost scaling on ticket length. See the details at https://oxlo.ai/pricing.

πŸ“° Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes β€” full credit and traffic to the original publisher.