DEV Community

shashank ms
shashank ms

Posted on

Sentiment Analysis Model Building with Oxlo

We are building a production-ready sentiment analysis pipeline that classifies customer feedback, extracts aspect-level sentiment, and returns structured JSON for downstream dashboards. This helps support teams and product managers prioritize issues without reading thousands of tickets manually.

What you'll need

Python 3.10 or higher, the OpenAI SDK, and an Oxlo.ai API key. Sign up at https://portal.oxlo.ai and grab your key. Install the SDK with pip.

pip install openai

Step 1: Configure the Oxlo.ai client

I start by pointing the OpenAI SDK at Oxlo.ai. Because Oxlo.ai is fully OpenAI API compatible, this is a drop-in replacement. I use llama-3.3-70b as the general-purpose flagship model.

from openai import OpenAI
import os

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

# Verify connectivity
response = client.chat.completions.create(
    model="llama-3.3-70b",
    messages=[{"role": "user", "content": "Say connected"}],
    max_tokens=5
)
print(response.choices[0].message.content)

Step 2: Define the system prompt

The system prompt constrains the model to act as a classifier and emit only valid JSON. I keep it strict so downstream parsers never break.

SYSTEM_PROMPT = """You are a sentiment analysis engine. Analyze the user-provided text and return a JSON object with exactly these keys:
- sentiment: one of "positive", "negative", "neutral", or "mixed"
- confidence: a float between 0.0 and 1.0
- aspects: a list of objects, each with "topic" and "sentiment" keys describing specific product aspects mentioned
- summary: a one-sentence explanation of the overall sentiment

Return only valid JSON. Do not include markdown formatting or explanation."""

Step 3: Build the core analyzer function

I wrap the API call in a reusable function that enables JSON mode. This guarantees structured output and keeps the temperature low to reduce variance.

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}
        ],
        response_format={"type": "json_object"},
        temperature=0.1
    )
    return json.loads(response.choices[0].message.content)

Step 4: Process a batch of reviews

Real workloads process hundreds of records. Because Oxlo.ai uses flat request-based pricing, long customer reviews do not inflate costs the way token-based providers charge. See https://oxlo.ai/pricing for details.

reviews = [
    "The battery life on this laptop is incredible, but the fan noise is unbearable during video calls.",
    "Shipping was fast and the packaging was great. No complaints.",
    "I waited three weeks for delivery and the screen arrived cracked. Extremely disappointed."
]

results = []
for review in reviews:
    result = analyze_sentiment(review)
    result["source_text"] = review
    results.append(result)

print(json.dumps(results, indent=2))

Step 5: Evaluate with a labeled set

Before deploying, I validate the pipeline against a small hand-labeled set to measure accuracy. If scores drop, I tune the prompt or swap to a stronger reasoning model like kimi-k2.6 without changing client code.

validation_set = [
    ("I love this product, it works perfectly.", "positive"),
    ("Terrible experience, would not recommend.", "negative"),
    ("It is a tool. It functions.", "neutral")
]

correct = 0
for text, expected in validation_set:
    predicted = analyze_sentiment(text)["sentiment"]
    if predicted == expected:
        correct += 1
    print(f"Expected: {expected} | Predicted: {predicted}")

print(f"\nAccuracy: {correct}/{len(validation_set)}")

Run it

Save the complete script as sentiment.py, export your key, and run it.

export OXLO_API_KEY="YOUR_OXLO_API_KEY"
python sentiment.py

Complete script:

from openai import OpenAI
import os
import json

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

SYSTEM_PROMPT = """You are a sentiment analysis engine. Analyze the user-provided text and return a JSON object with exactly these keys:
- sentiment: one of "positive", "negative", "neutral", or "mixed"
- confidence: a float between 0.0 and 1.0
- aspects: a list of objects, each with "topic" and "sentiment" keys describing specific product aspects mentioned
- summary: a one-sentence explanation of the overall sentiment

Return only valid JSON. Do not include markdown formatting or explanation."""

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}
        ],
        response_format={"type": "json_object"},
        temperature=0.1
    )
    return json.loads(response.choices[0].message.content)

if __name__ == "__main__":
    reviews = [
        "The battery life on this laptop is incredible, but the fan noise is unbearable during video calls.",
        "Shipping was fast and the packaging was great. No complaints.",
        "I waited three weeks for delivery and the screen arrived cracked. Extremely disappointed."
    ]

    for review in reviews:
        result = analyze_sentiment(review)
        print(f"Review: {review}")
        print(f"Result: {json.dumps(result, indent=2)}")
        print()

Example output:

Review: The battery life on this laptop is incredible, but the fan noise is unbearable during video calls.
Result: {
  "sentiment": "mixed",
  "confidence": 0.91,
  "aspects": [
    {"topic": "battery life", "sentiment": "positive"},
    {"topic": "fan noise", "sentiment": "negative"}
  ],
  "summary": "Strong battery life is undermined by excessive fan noise during calls."
}

Review: Shipping was fast and the packaging was great. No complaints.
Result: {
  "sentiment": "positive",
  "confidence": 0.96,
  "aspects": [
    {"topic": "shipping speed", "sentiment": "positive"},
    {"topic": "packaging", "sentiment": "positive"}
  ],
  "summary": "Customer is fully satisfied with shipping and packaging."
}

Review: I waited three weeks for delivery and the screen arrived cracked. Extremely disappointed.
Result: {
  "sentiment": "negative",
  "confidence": 0.95,
  "aspects": [
    {"topic": "delivery time", "sentiment": "negative"},
    {"topic": "screen condition", "sentiment": "negative"}
  ],
  "summary": "Customer is extremely disappointed due to long wait and damaged product."
}

Wrap-up and next steps

Wrap the analyze_sentiment function in a FastAPI endpoint to classify tickets in real time. If you need to analyze multilingual feedback, swap the model string to qwen-3-32b or kimi-k2.6 without touching any other client code. Oxlo.ai supports 45+ models, so you can iterate on model choice while keeping the same flat per-request cost structure.

Top comments (0)