Here is a concrete pipeline I shipped last quarter to process inbound customer feedback transcripts. It answers specific questions, produces an executive summary, and flags sentiment in a single pass. We will build the same thing against Oxlo.ai so you can run it on any text-heavy workload without token-based cost surprises.
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: Initialize the Oxlo.ai client
We start with the standard OpenAI SDK pointed at Oxlo.ai's endpoint. This is a drop-in replacement, so the only difference is the base URL and key.
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")
)
Step 2: Answer questions from a context document
The QA module takes a document and a question, then returns a grounded answer. I use Llama 3.3 70B because it follows instructions tightly and sticks to the provided context.
QA_SYSTEM_PROMPT = """You are a precise reading comprehension engine.
Answer the user's question using only the provided context.
If the answer is not in the context, reply "Not mentioned in the text."
Keep your answer to one or two sentences."""
def answer_question(context: str, question: str) -> str:
user_message = f"Context:\n{context}\n\nQuestion: {question}"
response = client.chat.completions.create(
model="llama-3.3-70b",
messages=[
{"role": "system", "content": QA_SYSTEM_PROMPT},
{"role": "user", "content": user_message},
],
)
return response.choices[0].message.content.strip()
Step 3: Summarize long text
For summarization I route the full document to Kimi K2.6. Its 131K context window handles long transcripts without truncation, and Oxlo.ai's per-request pricing means the cost does not balloon as the input grows.
SUMMARY_SYSTEM_PROMPT = """You are a concise summarization engine.
Read the full text and produce a 3-bullet summary.
Each bullet must be under 20 words.
Capture the main points, not minor details."""
def summarize_text(text: str) -> str:
response = client.chat.completions.create(
model="kimi-k2.6",
messages=[
{"role": "system", "content": SUMMARY_SYSTEM_PROMPT},
{"role": "user", "content": text},
],
)
return response.choices[0].message.content.strip()
Step 4: Analyze sentiment and tone
The sentiment module classifies overall tone and extracts the emotional driver. I use Qwen 3 32B for this because it handles classification reasoning cleanly.
SENTIMENT_SYSTEM_PROMPT = """You are a sentiment classifier.
Analyze the text and return exactly this JSON structure:
{"sentiment": "positive|negative|neutral|mixed", "confidence": "high|medium|low", "key_phrase": "the single phrase that most indicates the sentiment"}
Do not include markdown or explanation outside the JSON."""
import json
def analyze_sentiment(text: str) -> dict:
response = client.chat.completions.create(
model="qwen-3-32b",
messages=[
{"role": "system", "content": SENTIMENT_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)
Step 5: Wire everything into a single pipeline
Now we connect the three modules. The pipeline accepts a document and a question, then prints the summary, sentiment, and answer.
def analyze_document(text: str, question: str):
print("=== Summary ===")
print(summarize_text(text))
print()
print("=== Sentiment ===")
print(json.dumps(analyze_sentiment(text), indent=2))
print()
print("=== Answer ===")
print(answer_question(text, question))
Run it
Save the complete script as pipeline.py, set your key, and run it. I test it with a short internal status report and one follow-up question. Here is the full output:
if __name__ == "__main__":
SAMPLE_DOC = """
Our Q3 rollout was delayed by two weeks due to a third-party API outage.
Customers expressed frustration in the support queue, though the post-mortem
communication was well received. Engineering has added redundant fallback
providers and expects Q4 to be on schedule. Leadership is cautiously optimistic.
"""
QUESTION = "What caused the Q3 delay?"
analyze_document(SAMPLE_DOC, QUESTION)
$ export OXLO_API_KEY="sk-..."
$ python pipeline.py
=== Summary ===
- Q3 rollout delayed two weeks by a third-party API outage.
- Customers were frustrated, but post-mortem communication was well received.
- Engineering added redundant fallbacks and leadership is cautiously optimistic.
=== Sentiment ===
{
"sentiment": "mixed",
"confidence": "medium",
"key_phrase": "frustration in the support queue"
}
=== Answer ===
The Q3 rollout was delayed by a third-party API outage.
Wrap-up
Two concrete next steps. First, add streaming responses by passing stream=True to each chat completion and yielding chunks to the console as they arrive. Second, connect the sentiment output to a function call that opens a PagerDuty incident when confidence is high and the tone is negative.
Top comments (0)