DEV Community

shashank ms
shashank ms

Posted on

LLMs for Natural Language Understanding: A Comprehensive Guide

We are building a customer feedback parsing agent that reads unstructured support tickets and returns structured JSON with intent, sentiment, product mentions, and urgency. This helps support teams route tickets automatically instead of reading every message manually. We will run it on Oxlo.ai, where flat per-request pricing keeps costs predictable even when tickets run long.

What you'll need

Grab an Oxlo.ai API key from https://portal.oxlo.ai. You will also need Python 3.10 or newer and the OpenAI SDK.

pip install openai

Step 1: Connect to Oxlo.ai and verify the endpoint

First, we instantiate the OpenAI-compatible client pointing at Oxlo.ai and make a quick health check call to confirm the key is active.

from openai import OpenAI
import os

client = OpenAI(
    base_url="https://api.oxlo.ai/v1",
    api_key=os.environ.get("OXLO_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": "Reply with OK"},
    ],
)
print(response.choices[0].message.content)

Step 2: Write the system prompt that defines our NLU schema

The system prompt is the contract. It tells the model exactly what entities and labels to extract from free text.

SYSTEM_PROMPT = """You are an NLU engine that parses customer support tickets into structured JSON.

Extract these fields:
- intent: one of [billing_issue, technical_problem, feature_request, complaint, other]
- sentiment: one of [positive, neutral, negative, very_negative]
- products_mentioned: list of product names, or empty list
- urgency: one of [low, medium, high, critical]
- summary: one concise sentence describing the problem

Rules:
- Output ONLY a JSON object.
- Never wrap the JSON in markdown code fences.
- Never return null for a required field. If unsure, infer the best fit."""

Step 3: Parse a single ticket with JSON mode

We call the model with response_format set to json_object so the output is predictable, then load it into a Python dict.

import json

ticket = ("I was charged twice for my Pro plan last month and now the API dashboard "
          "returns 403 errors for every request. This is blocking our entire team.")

response = client.chat.completions.create(
    model="llama-3.3-70b",
    messages=[
        {"role": "system", "content": SYSTEM_PROMPT},
        {"role": "user", "content": ticket},
    ],
    response_format={"type": "json_object"},
)

result = json.loads(response.choices[0].message.content)
print(json.dumps(result, indent=2))

Step 4: Harden the pipeline with validation

Production NLU needs to survive malformed outputs and missing keys. We add a thin validation layer that catches parsing errors and schema gaps.

REQUIRED_KEYS = {"intent", "sentiment", "products_mentioned", "urgency", "summary"}

def parse_ticket(text: str) -> dict:
    try:
        resp = client.chat.completions.create(
            model="llama-3.3-70b",
            messages=[
                {"role": "system", "content": SYSTEM_PROMPT},
                {"role": "user", "content": text},
            ],
            response_format={"type": "json_object"},
        )
        data = json.loads(resp.choices[0].message.content)
        missing = REQUIRED_KEYS - data.keys()
        if missing:
            raise ValueError(f"Missing keys: {missing}")
        return data
    except Exception as exc:
        return {"error": str(exc), "raw_input": text[:200]}

# edge case test
print(parse_ticket(""))

Step 5: Batch process tickets and aggregate urgency

Now we process multiple tickets and surface a simple metric for the support queue.

tickets = [
    "Love the new design, but the export button is missing on mobile.",
    "URGENT: our webhook endpoint is returning 500s since 2am and we are losing orders.",
    "Can you add dark mode to the dashboard? Would be a nice touch.",
    "I do not understand the invoice from March. Please explain the overage charges.",
]

results = [parse_ticket(t) for t in tickets]

for r in results:
    print(r)

critical = sum(1 for r in results if r.get("urgency") == "critical")
print(f"\nTickets needing immediate attention: {critical}")

Run it

Save the complete script as feedback_parser.py and run it from your terminal.

export OXLO_API_KEY="YOUR_OXLO_API_KEY"
python feedback_parser.py

Expected output looks like this:

{'intent': 'feature_request', 'sentiment': 'positive', 'products_mentioned': ['mobile'], 'urgency': 'low', 'summary': 'Customer likes the new design but the export button is missing on mobile.'}
{'intent': 'technical_problem', 'sentiment': 'very_negative', 'products_mentioned': ['webhook endpoint'], 'urgency': 'critical', 'summary': 'Webhook endpoint has been returning 500s since 2am, causing order loss.'}
{'intent': 'feature_request', 'sentiment': 'positive', 'products_mentioned': ['dashboard'], 'urgency': 'low', 'summary': 'Customer requests dark mode for the dashboard.'}
{'intent': 'billing_issue', 'sentiment': 'negative', 'products_mentioned': [], 'urgency': 'medium', 'summary': 'Customer does not understand the overage charges on the March invoice.'}

Tickets needing immediate attention: 1

Wrap-up

You now have a working NLU pipeline that turns raw text into structured ticket data. Two concrete next steps: deploy this as a FastAPI endpoint that ingests webhooks from your support inbox, or swap in kimi-k2.6 on Oxlo.ai for more nuanced reasoning when you start seeing complex multi-issue tickets.

Top comments (0)