DEV Community

shashank ms
shashank ms

Posted on

Introduction to LLMs for Text Analysis

We are going to build a working feedback analyzer that reads unstructured customer text, scores sentiment, and extracts key themes. This saves product and support teams from manually reading hundreds of responses. We will wire it directly to Oxlo.ai using the OpenAI SDK so you can run it against real data in minutes.

What you'll need

Before starting, grab an Oxlo.ai API key from https://portal.oxlo.ai. You also need Python 3.10 or newer and the OpenAI SDK installed.

pip install openai

1. Configure the client

I always start by verifying the connection. This snippet initializes the client and asks Llama 3.3 70B for a quick sanity check.

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": "Say 'Connection OK' and nothing else."},
    ],
)

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

2. Design the system prompt

The model needs strict instructions to return structured data. I lock the output format to JSON and define the fields I want: sentiment, themes, and urgency.

SYSTEM_PROMPT = """You are a text-analysis engine. Read the user message and return a single JSON object with no markdown formatting.

Required fields:
- sentiment: one of Positive, Neutral, or Negative
- themes: an array of up to three short topic labels
- urgency: Low, Medium, or High

Be concise. Do not include explanations outside the JSON."""

3. Analyze a single feedback entry

Now we can send a real piece of text. I wrap the call in a small function so it is reusable, and I strip any accidental markdown fences from the response.

import json

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

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

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

sample = "The checkout process was smooth, but shipping took two weeks and the box was damaged."
result = analyze_feedback(sample)
print(json.dumps(result, indent=2))

4. Batch process a list

Most teams do not analyze one comment at a time. Here is a loop that processes a list of strings and collects results, with a small delay to stay polite to the API.

import time

feedback_list = [
    "Love the new dashboard. It is fast and intuitive.",
    "I cannot export my reports to PDF. This is blocking my workflow.",
    "It is okay. Nothing special, but it works.",
]

results = []
for item in feedback_list:
    try:
        parsed = analyze_feedback(item)
        parsed["source_text"] = item
        results.append(parsed)
    except Exception as e:
        print(f"Failed on item: {item[:50]}... Error: {e}")
    time.sleep(0.5)

print(f"Processed {len(results)} of {len(feedback_list)} items.")

5. Write results to a file

Finally, we persist the structured output so it can be loaded into a spreadsheet or BI tool.

with open("feedback_analysis.json", "w", encoding="utf-8") as f:
    json.dump(results, f, indent=2, ensure_ascii=False)

print("Saved to feedback_analysis.json")

Run it

Here is the complete script in one block. Drop your Oxlo.ai key into the client initialization and run it.

from openai import OpenAI
import json
import time

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

SYSTEM_PROMPT = """You are a text-analysis engine. Read the user message and return a single JSON object with no markdown formatting.

Required fields:
- sentiment: one of Positive, Neutral, or Negative
- themes: an array of up to three short topic labels
- urgency: Low, Medium, or High

Be concise. Do not include explanations outside the JSON."""

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

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

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

feedback_list = [
    "Love the new dashboard. It is fast and intuitive.",
    "I cannot export my reports to PDF. This is blocking my workflow.",
    "It is okay. Nothing special, but it works.",
]

results = []
for item in feedback_list:
    try:
        parsed = analyze_feedback(item)
        parsed["source_text"] = item
        results.append(parsed)
    except Exception as e:
        print(f"Failed on item: {item[:50]}... Error: {e}")
    time.sleep(0.5)

with open("feedback_analysis.json", "w", encoding="utf-8") as f:
    json.dump(results, f, indent=2, ensure_ascii=False)

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

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

[
  {
    "sentiment": "Positive",
    "themes": ["dashboard", "performance", "usability"],
    "urgency": "Low",
    "source_text": "Love the new dashboard. It is fast and intuitive."
  },
  {
    "sentiment": "Negative",
    "themes": ["export", "PDF", "workflow blocker"],
    "urgency": "High",
    "source_text": "I cannot export my reports to PDF. This is blocking my workflow."
  },
  {
    "sentiment": "Neutral",
    "themes": ["general feedback"],
    "urgency": "Low",
    "source_text": "It is okay. Nothing special, but it works."
  }
]

Wrap-up

This pipeline turns raw text into structured data without any training or fine-tuning. If you want to go further, try swapping in deepseek-v3.2 or qwen-3-32b on Oxlo.ai to see which model gives the most consistent JSON for your domain. Another solid next step is wiring the output into a SQLite database or a Slack webhook so new feedback is analyzed automatically.

Top comments (0)