DEV Community

shashank ms
shashank ms

Posted on

Sentiment Analysis with LLM: A Step-by-Step Guide

We are going to build a production-ready sentiment analysis pipeline that reads raw customer feedback and returns structured labels with confidence scores and short explanations. This helps support and product teams prioritize issues without maintaining a dedicated NLP infrastructure or worrying about token costs scaling with long complaint emails.

What you'll need

Step 1: Configure the Oxlo.ai client

Import the SDK and point it at Oxlo.ai. Because the platform is fully OpenAI-compatible, the only changes are the base URL and your Oxlo.ai API key.

import os
from openai import OpenAI

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

Step 2: Define the system prompt

The prompt enforces strict output formatting so we can parse it reliably. I describe a JSON schema inside the prompt and ask for a single valid JSON object with no markdown fences.

SYSTEM_PROMPT = """You are a sentiment analysis engine.
Analyze the sentiment of the user message and respond with a single valid JSON object containing exactly these keys:
- label: one of "positive", "negative", "neutral"
- confidence: a float between 0.0 and 1.0
- reasoning: one concise sentence explaining why

Rules:
- Output only the JSON object, with no markdown code fences and no extra text.
- If the message is mixed, choose the dominant sentiment.
- Be conservative with confidence; 1.0 means absolute certainty."""

Step 3: Build the analyzer function

This function sends feedback text to Llama 3.3 70B on Oxlo.ai, then parses the JSON response. I use Llama 3.3 70B here because it follows structured formatting instructions reliably for classification work.

import json

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

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

    # Guard against occasional markdown fences.
    if raw.startswith("

```"):
        raw = raw.split("\n", 1)[1].rsplit("```

", 1)[0].strip()

    return json.loads(raw)

Step 4: Add batch processing

In production you will analyze more than one message at a time. This wrapper iterates over a list, handles API or JSON errors gracefully, and preserves order.

from typing import List

def analyze_batch(texts: List[str]) -> List[dict]:
    results = []
    for idx, text in enumerate(texts):
        try:
            result = analyze_sentiment(text)
            result["index"] = idx
            result["input"] = text
            results.append(result)
        except Exception as e:
            results.append({
                "index": idx,
                "input": text,
                "label": "error",
                "confidence": 0.0,
                "reasoning": str(e),
            })
    return results

Step 5: Test harness

Here is a short list of realistic support messages. We will run them through the pipeline and print a simple table.

if __name__ == "__main__":
    samples = [
        "The new export feature saved me three hours this week. Great work.",
        "I waited 20 minutes for the invoice page to load and then it crashed.",
        "Your pricing page is okay but I wish there was an annual discount.",
        "Absolutely love the dark mode. Best update in months.",
        "I am frustrated that the mobile app still lacks offline support.",
    ]

    for row in analyze_batch(samples):
        print(f"{row['label']:10} | {row['confidence']:.2f} | {row['input'][:50]}...")

Run it

Export your key and execute the script.

export OXLO_API_KEY="YOUR_OXLO_API_KEY"
python sentiment.py

Expected output:

positive   | 0.95 | The new export feature saved me three hours this ...
negative   | 0.92 | I waited 20 minutes for the invoice page to load...
neutral    | 0.78 | Your pricing page is okay but I wish there was a...
positive   | 0.96 | Absolutely love the dark mode. Best update in mo...
negative   | 0.88 | I am frustrated that the mobile app still lacks ...

Wrap-up and next steps

Because Oxlo.ai uses flat per-request pricing, running this pipeline on long customer emails or multi-turn chat transcripts costs the same as a one-word message. For a live deployment, wire the analyze_batch function into a webhook that scores incoming support tickets before they hit your CRM.

Another practical extension is to switch the model to kimi-k2.6 or qwen-3-32b for multilingual feedback, or to deepseek-v3.2 if you also want the model to extract specific product sub-features mentioned in the text. See the Oxlo.ai pricing page to estimate volume costs for your expected traffic.

Top comments (0)