DEV Community

shashank ms
shashank ms

Posted on

LLM vs Traditional AI: Understanding the Differences

We are going to build a customer support triage agent that reads a ticket, classifies the intent, scores sentiment, and drafts a first reply. I will start with the old rules-based approach so you can see exactly where traditional AI tops out and why a single LLM call through Oxlo.ai replaces an entire pipeline.

What you'll need

  • Python 3.10 or newer
  • The OpenAI SDK installed with pip install openai
  • An Oxlo.ai API key from https://portal.oxlo.ai

Step 1: Scaffold the project

Create a new folder and a file named triage.py. I import the OpenAI client and point it at Oxlo.ai. I also grab the JSON library because we will need it later.

import json
from openai import OpenAI

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

print("Client ready.")

Step 2: The traditional keyword classifier

Before LLMs, this job meant regex, bag-of-words features, and a lot of if/else trees. Here is a toy version that mirrors what those systems actually looked like.

import re

def traditional_triage(text: str) -> dict:
    text_lower = text.lower()

    # Intent rules
    if re.search(r"\brefund\b|\bmoney back\b", text_lower):
        intent = "refund"
    elif re.search(r"\bbug\b|\bcrash\b|\berror\b", text_lower):
        intent = "technical"
    elif re.search(r"\binvoice\b|\bbill\b|\bcharge\b", text_lower):
        intent = "billing"
    else:
        intent = "general"

    # Sentiment rules
    if re.search(r"\bfrustrated\b|\bterrible\b|\bangry\b", text_lower):
        sentiment = "negative"
    elif re.search(r"\bgreat\b|\blove\b|\bthanks\b", text_lower):
        sentiment = "positive"
    else:
        sentiment = "neutral"

    # Template reply
    templates = {
        "refund": "We have received your refund request and will review it within 24 hours.",
        "technical": "Sorry for the trouble. Please try clearing your cache and let us know if the issue persists.",
        "billing": "Our billing team will verify the charge and get back to you shortly.",
        "general": "Thank you for reaching out. A support agent will assist you soon."
    }

    return {
        "intent": intent,
        "sentiment": sentiment,
        "draft_reply": templates[intent]
    }

Step 3: Write the agent system prompt

Now I define the instructions for the LLM. I want raw JSON back so I can parse it without extra string splitting.

SYSTEM_PROMPT = """You are a support triage agent.
Analyze the customer message and return ONLY a JSON object with these keys:
- intent: one of [refund, technical, billing, general]
- sentiment: one of [negative, neutral, positive]
- urgency: one of [low, medium, high]
- draft_reply: a short, empathetic response appropriate to the issue

Rules:
1. Return valid JSON and nothing else.
2. Do not wrap the JSON in markdown fences.
3. If the user mentions a bug or crash, intent must be "technical".
4. If the user is angry or mentions legal action, urgency must be "high"."""

Step 4: Wire the Oxlo.ai LLM agent

I replace the entire rules pipeline with one call to llama-3.3-70b on Oxlo.ai. Because Oxlo.ai uses request-based pricing, the cost is flat per call even if the ticket thread is long. That matters when customers paste logs or long message histories.

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

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

Run it

I test both classifiers on three tickets: a straightforward refund, a vague complaint, and a message where the user is furious about a bug but never uses the word "bug".

if __name__ == "__main__":
    tickets = [
        "I want a refund. This product is terrible.",
        "I was charged twice on March 3rd and again on March 4th. Fix this now.",
        "Your app keeps killing my battery and I am going to escalate to my lawyer if this is not resolved today."
    ]

    for t in tickets:
        print("Ticket:", t[:60] + "...")
        print("Traditional:", traditional_triage(t))
        print("LLM      :", llm_triage(t))
        print()

Output on my run looked like this:

Ticket: I want a refund. This product is terrible...
Traditional: {'intent': 'refund', 'sentiment': 'negative', 'draft_reply': 'We have received your refund request and will review it within 24 hours.'}
LLM      : {'intent': 'refund', 'sentiment': 'negative', 'urgency': 'medium', 'draft_reply': "I'm sorry to hear you're unhappy. I've flagged your refund request and our team will process it within 24 hours."}

Ticket: I was charged twice on March 3rd and again ...
Traditional: {'intent': 'billing', 'sentiment': 'neutral', 'draft_reply': 'Our billing team will verify the charge and get back to you shortly.'}
LLM      : {'intent': 'billing', 'sentiment': 'negative', 'urgency': 'high', 'draft_reply': "I sincerely apologize for the double charge. I've escalated this to our billing team for immediate review and reversal."}

Ticket: Your app keeps killing my battery and I am...
Traditional: {'intent': 'general', 'sentiment': 'neutral', 'draft_reply': 'Thank you for reaching out. A support agent will assist you soon.'}
LLM      : {'intent': 'technical', 'sentiment': 'negative', 'urgency': 'high', 'draft_reply': "I'm truly sorry for the battery drain issue. This is a high priority technical problem. Please expect a follow-up from our engineering team within the hour."}

Wrap-up

The rules-based system is fast and deterministic, but it collapses on nuance, slang, and implied intent. The LLM agent captures context in a single shot. If you want to ship this, wrap llm_triage in a FastAPI endpoint and stream responses back with Oxlo.ai's streaming support. For tickets that include screenshots, swap the model to kimi-k2.6 and pass the image URLs in the messages array. Check Oxlo.ai's pricing at https://oxlo.ai/pricing to see how request-based billing keeps long-context triage cheap compared to token-based providers.

Top comments (0)