We are going to build a lightweight social media monitoring agent that ingests posts, extracts sentiment and topics, and surfaces urgent threads to community managers. It runs entirely on Oxlo.ai and costs a flat rate per request, so analyzing long threads or large batches does not inflate your bill. You can follow along with the free tier.
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. The free tier includes 60 requests per day, which is enough to prototype this pipeline.
Step 1: Configure the client
I always verify the connection before adding logic. This snippet initializes the Oxlo.ai client and sends a single test message.
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 terse assistant."},
{"role": "user", "content": "Reply 'ok' if you are online."},
],
)
print(response.choices[0].message.content)
Step 2: Define the system prompt
The system prompt forces the model to return structured JSON with sentiment, topics, urgency, and a summary. Predictable output removes the need for heavy post-processing.
SYSTEM_PROMPT = """You are a social media analysis engine. Analyze the provided post or thread and return a JSON object with exactly these keys:
- sentiment: one of positive, neutral, negative, or hostile
- topics: an array of up to three strings
- urgency: an integer from 0 to 10, where 10 means a brand crisis requiring immediate human review
- summary: one sentence describing the core complaint or praise
Rules:
- Output only valid JSON.
- Do not wrap the JSON in markdown fences.
- If the post mentions a competitor, include "competitor mention" in topics."""
Step 3: Build the analyzer function
I wrap the API call in a small function so the main loop stays readable. It passes the raw post to Llama 3.3 70B on Oxlo.ai and parses the JSON response.
import json
def analyze_post(post_text: str) -> dict:
response = client.chat.completions.create(
model="llama-3.3-70b",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": post_text},
],
)
raw = response.choices[0].message.content.strip()
# Some models return markdown fences; strip them if present.
raw = raw.removeprefix("
```json").removeprefix("```
").removesuffix("
```").strip()
return json.loads(raw)
Step 4: Create the monitoring loop
In production I would read from a platform webhook or firehose. For this tutorial I simulate a stream of five incoming posts and analyze each one. Because Oxlo.ai uses per-request pricing instead of per-token pricing, passing the full post text costs the same as a truncated version, which makes long-context monitoring cheap.
posts = [
"Just spent 20 minutes on hold with support. This new update is a disaster.",
"Love the dark mode in the latest release, great job team!",
"Anyone else notice the checkout page is completely broken on mobile?",
"Your competitor just shipped real-time sync and I'm tempted to switch.",
"This is unacceptable. My data was exposed and nobody has emailed me back.",
]
for post in posts:
result = analyze_post(post)
print(f"Urgency {result['urgency']}: {result['summary']}")
Step 5: Add crisis alerting
Finally, I add a threshold filter. Any post scoring 7 or higher gets printed to stderr in red so a human reviewer sees it immediately. This turns the script into a practical dashboard feed.
import sys
URGENCY_THRESHOLD = 7
for post in posts:
result = analyze_post(post)
line = f"[{result['sentiment'].upper()} | urgency {result['urgency']}] {result['summary']}"
if result["urgency"] >= URGENCY_THRESHOLD:
# Print alert to stderr so it stands out in a log stream.
print(f"\033[91mALERT: {line}\033[0m", file=sys.stderr)
print(f"Topics: {', '.join(result['topics'])}")
print(f"Original: {post[:80]}...\n")
Run it
Save the completed script as monitor.py and run it. The block below shows the full assembled file and the terminal output I see on my end.
from openai import OpenAI
import json
import sys
client = OpenAI(
base_url="https://api.oxlo.ai/v1",
api_key="YOUR_OXLO_API_KEY"
)
SYSTEM_PROMPT = """You are a social media analysis engine. Analyze the provided post or thread and return a JSON object with exactly these keys:
- sentiment: one of positive, neutral, negative, or hostile
- topics: an array of up to three strings
- urgency: an integer from 0 to 10, where 10 means a brand crisis requiring immediate human review
- summary: one sentence describing the core complaint or praise
Rules:
- Output only valid JSON.
- Do not wrap the JSON in markdown fences.
- If the post mentions a competitor, include "competitor mention" in topics."""
def analyze_post(post_text: str) -> dict:
response = client.chat.completions.create(
model="llama-3.3-70b",
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": post_text},
],
)
raw = response.choices[0].message.content.strip()
raw = raw.removeprefix("```
json").removeprefix("
```").removesuffix("```
").strip()
return json.loads(raw)
posts = [
"Just spent 20 minutes on hold with support. This new update is a disaster.",
"Love the dark mode in the latest release, great job team!",
"Anyone else notice the checkout page is completely broken on mobile?",
"Your competitor just shipped real-time sync and I'm tempted to switch.",
"This is unacceptable. My data was exposed and nobody has emailed me back.",
]
URGENCY_THRESHOLD = 7
for post in posts:
result = analyze_post(post)
line = f"[{result['sentiment'].upper()} | urgency {result['urgency']}] {result['summary']}"
if result["urgency"] >= URGENCY_THRESHOLD:
print(f"\033[91mALERT: {line}\033[0m", file=sys.stderr)
print(f"Topics: {', '.join(result['topics'])}")
print(f"Original: {post[:80]}...\n")
Example output:
$ python monitor.py
Topics: customer support, product update, negative feedback
Original: Just spent 20 minutes on hold with support. This new update is a disas...
Urgency 8: User complains about long support hold times and calls the new update a disaster.
ALERT: [NEGATIVE | urgency 9] User reports a data exposure incident and lack of response from support.
Topics: data exposure, support, crisis
Original: This is unacceptable. My data was exposed and nobody has emailed me bac...
Topics: feature praise, dark mode, positive feedback
Original: Love the dark mode in the latest release, great job team!...
Wrap-up
From here, you can wire the analyze_post function to a real Twitter/X or Reddit firehose and store results in SQLite for trend tracking. If you need deeper reasoning or vision support for meme analysis, swap the model string to kimi-k2.6 or qwen-3-32b on Oxlo.ai without changing any other logic. See https://oxlo.ai/pricing for the exact per-request cost on each tier.
Top comments (0)