DEV Community

shashank ms
shashank ms

Posted on

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 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.

Top comments (0)