Most support teams do not need a custom BERT model to extract meaning from customer messages. In this tutorial, I will show you how to build a structured language understanding layer on top of an LLM that parses raw text into intent, entities, and sentiment. The result is a maintainable replacement for brittle regex pipelines that you can put into production this afternoon.
What you'll need
- Python 3.10 or newer
- The OpenAI SDK:
pip install openai - An Oxlo.ai API key from https://portal.oxlo.ai
Step 1: Configure the client
I always start by verifying the API connection before I write any business logic. Point the OpenAI SDK at Oxlo.ai and send a quick completion to confirm there are no cold starts and the endpoint is ready.
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)
Step 2: Define the schema contract
The system prompt is the only training signal we need. I treat it as a strict schema contract. If the prompt is explicit, the model behaves like a deterministic parser.
SYSTEM_PROMPT = """You are a structured language understanding engine. Extract the following fields from the user message and return only a JSON object with no markdown formatting.
Fields:
- intent: one of [refund, technical_issue, general_feedback]
- entities: an object containing product_name and order_id. Use null when a value is missing.
- sentiment: one of [positive, negative, neutral]
- urgency: one of [low, medium, high]
Rules:
- Output valid JSON only. Do not wrap the output in markdown code fences.
- If a field cannot be determined, use null.
- Keep entity values exactly as they appear in the text."""
Step 3: Build the extraction function
Now I wrap the Oxlo.ai call in a small function that returns a native Python dictionary. I keep the temperature low so the output stays close to the schema.
import json
from openai import OpenAI
client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")
SYSTEM_PROMPT = """You are a structured language understanding engine. Extract the following fields from the user message and return only a JSON object with no markdown formatting.
Fields:
- intent: one of [refund, technical_issue, general_feedback]
- entities: an object containing product_name and order_id. Use null when a value is missing.
- sentiment: one of [positive, negative, neutral]
- urgency: one of [low, medium, high]
Rules:
- Output valid JSON only. Do not wrap the output in markdown code fences.
- If a field cannot be determined, use null.
- Keep entity values exactly as they appear in the text."""
def understand_text(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},
],
temperature=0.1,
)
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)
# Quick smoke test
if __name__ == "__main__":
sample = "My Pro subscription is broken and I want my money back. Order #9981."
print(json.dumps(understand_text(sample), indent=2))
Step 4: Batch processing and guardrails
Production pipelines handle more than one message at a time. I added a thin batch loop with basic exception handling so one malformed response does not crash the entire job. Because Oxlo.ai charges a flat rate per request, I know exactly what this batch will cost before I run it.
import json
from typing import List
from openai import OpenAI
client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")
SYSTEM_PROMPT = """You are a structured language understanding engine. Extract the following fields from the user message and return only a JSON object with no markdown formatting.
Fields:
- intent: one of [refund, technical_issue, general_feedback]
- entities: an object containing product_name and order_id. Use null when a value is missing.
- sentiment: one of [positive, negative, neutral]
- urgency: one of [low, medium, high]
Rules:
- Output valid JSON only. Do not wrap the output in markdown code fences.
- If a field cannot be determined, use null.
- Keep entity values exactly as they appear in the text."""
def understand_text(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},
],
temperature=0.1,
)
raw = response.choices[0].message.content.strip()
if raw.startswith("
```"):
raw = raw.split("\n", 1)[1].rsplit("```
", 1)[0].strip()
return json.loads(raw)
def understand_batch(messages: List[str]) -> List[dict]:
results = []
for msg in messages:
try:
parsed = understand_text(msg)
assert "intent" in parsed
assert "entities" in parsed
results.append(parsed)
except Exception as e:
results.append({"error": str(e), "raw_input": msg})
return results
if __name__ == "__main__":
samples = [
"My Pro subscription is broken and I want my money back. Order #9981.",
"Love the new API docs, great work team!",
"How do I reset my key?",
]
for res in understand_batch(samples):
print(json.dumps(res, indent=2))
Step 5: Add an interactive CLI
A simple command-line loop lets me test edge cases on the fly before I wire this into a FastAPI endpoint or a background worker.
import json
from openai import OpenAI
client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")
SYSTEM_PROMPT = """You are a structured language understanding engine. Extract the following fields from the user message and return only a JSON object with no markdown formatting.
Fields:
- intent: one of [refund, technical_issue, general_feedback]
- entities: an object containing product_name and order_id. Use null when a value is missing.
- sentiment: one of [positive, negative, neutral]
- urgency: one of [low, medium, high]
Rules:
- Output valid JSON only. Do not wrap the output in markdown code fences.
- If a field cannot be determined, use null.
- Keep entity values exactly as they appear in the text."""
def understand_text(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},
],
temperature=0.1,
)
raw = response.choices[0].message.content.strip()
if raw.startswith("
```"):
raw = raw.split("\n", 1)[1].rsplit("```
", 1)[0].strip()
return json.loads(raw)
if __name__ == "__main__":
print("Language Understanding Model (LLM-powered)")
print("Type a message and press Enter. Ctrl+C to quit.\n")
while True:
try:
user_input = input("Message: ").strip()
if not user_input:
continue
result = understand_text(user_input)
print(json.dumps(result, indent=2))
print()
except KeyboardInterrupt:
print("\nShutting down.")
break
except Exception as e:
print(f"Failed: {e}\n")
Run it
Save the final script as understand.py, set your YOUR_OXLO_API_KEY, and run it. Here is a sample session showing how the model handles three different inputs.
$ python understand.py
Language Understanding Model (LLM-powered)
Type a message and press Enter. Ctrl+C to quit.
Message: My Pro subscription is broken and I want my money back. Order #9981.
{
"intent": "refund",
"entities": {
"product_name": null,
"order_id": "9981"
},
"sentiment": "negative",
"urgency": "high"
}
Message: Love the new API docs, great work team!
{
"intent": "general_feedback",
"entities": {
"product_name": null,
"order_id": null
},
"sentiment": "positive",
"urgency": "low"
}
Message: How do I reset my key?
{
"intent": "technical_issue",
"entities": {
"product_name": null,
"order_id": null
},
"sentiment": "neutral",
"urgency": "medium"
}
Wrap-up
You now have a working language understanding layer that turns unstructured text into structured JSON without any model training. Two concrete next steps: wire this behind a FastAPI endpoint so your support stack can call it via webhook, or switch to deepseek-v3.2 on Oxlo.ai if you want to experiment with a stronger reasoning model for ambiguous or multi-part messages. For pricing details on running this at scale, see https://oxlo.ai/pricing.
Top comments (0)