I needed to pick a backend model for a short-fiction generator. Rather than trust leaderboard scores, I wrote a small Python harness that sends the same creative prompt to several Oxlo.ai models and prints the results side by side. In this guide, I will walk through that script so you can run it yourself and choose the best writer for your genre.
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 and model slate
I start with the OpenAI SDK pointed at Oxlo.ai and a list of four models that cover different prose strengths.
from openai import OpenAI
import concurrent.futures
client = OpenAI(base_url="https://api.oxlo.ai/v1", api_key="YOUR_OXLO_API_KEY")
MODELS = {
"llama-3.3-70b": "general-purpose flagship",
"kimi-k2.6": "advanced reasoning and long context",
"qwen-3-32b": "multilingual and agentic",
"deepseek-v3.2": "coding and reasoning",
}
Step 2: Define the creative writing system prompt
The system prompt is the only agent logic. It constrains every model to the same voice, tense, and output format so we compare prose quality, not prompt adherence.
SYSTEM_PROMPT = """You are a creative writing assistant.
Write the user-requested scene in third-person limited perspective.
Use vivid sensory details.
Output exactly two paragraphs.
Do not include preambles or meta commentary."""
Step 3: Build the batch generator
To keep the test fair, I send identical messages to every model concurrently and collect the text.
def generate(model_id: str, user_message: str) -> dict:
response = client.chat.completions.create(
model=model_id,
messages=[
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_message},
],
temperature=0.9,
max_tokens=512,
)
return {
"model": model_id,
"text": response.choices[0].message.content.strip(),
}
def run_batch(user_message: str) -> list:
with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor:
futures = {
executor.submit(generate, m, user_message): m
for m in MODELS.keys()
}
results = []
for future in concurrent.futures.as_completed(futures):
try:
results.append(future.result())
except Exception as e:
results.append({"model": futures[future], "text": f"Error: {e}"})
return results
Step 4: Add a critique layer
I also want a single model to review all four outputs for style, pacing, and imagery. I use kimi-k2.6 because its reasoning capabilities handle comparative analysis well.
def critique(outputs: list, original_prompt: str) -> str:
combined = "\n\n---\n\n".join(
f"### {o['model']}\n{o['text']}" for o in outputs
)
critique_prompt = (
f"Original prompt: {original_prompt}\n\n"
f"Below are four generated scenes. Rank them from best to worst "
f"for imagery, pacing, and voice consistency. Explain each ranking "
f"in one sentence.\n\n{combined}"
)
response = client.chat.completions.create(
model="kimi-k2.6",
messages=[
{"role": "system", "content": "You are a literary editor. Be concise."},
{"role": "user", "content": critique_prompt},
],
temperature=0.3,
max_tokens=512,
)
return response.choices[0].message.content.strip()
Step 5: Wire the CLI
The main block ties the batch generator and the critique layer together and prints clean Markdown.
if __name__ == "__main__":
user_prompt = (
"Write the opening of a cyberpunk story. A detective discovers "
"a sentient violin in a rain-soaked pawn shop."
)
print("Generating scenes...\n")
results = run_batch(user_prompt)
for r in results:
print(f"## {r['model']}\n")
print(r["text"])
print()
print("Running critique...\n")
review = critique(results, user_prompt)
print(review)
Run it
Save the file as compare_writers.py, export your key, and run it. On my last execution with the cyberpunk prompt, the output looked like this.
$ export OXLO_API_KEY="sk-oxlo.ai-..."
$ python compare_writers.py
Generating scenes...
## llama-3.3-70b
Rain hammered the neon above Ouyang's Pawn. Detective Mara Voss pushed through the door, bell chiming flat against the damp. In the back corner, beneath a tarp that smelled of ozone and regret, a violin hummed a chord that matched her heartbeat. She reached for it, and the strings tightened without a touch.
## kimi-k2.6
The pawn shop breathed through cracked vents. Voss wiped condensation from her collar and saw the instrument. It was not dusty. The wood gleamed as if recently varnished, and when she exhaled, the bridge seemed to lean toward her breath. A sentience, quiet and waiting, nested in the f-holes.
## qwen-3-32b
Water dripped from Voss's coat onto linoleum that had seen better decades. The violin sat on a shelf of dead electronics, its finish unmarred by time. As she approached, it played a single D-note that resonated in her fillings. She knew then that the case reports had not been hallucinations.
## deepseek-v3.2
Voss entered Ouyang's at 02:00. The rain followed her in. Among the dead phones and counterfeit watches, the violin rested in an open case. No bow. No rosin. Yet the strings vibrated at 440 Hz exactly, modulating when she shifted her weight. She logged it as evidence. The violin logged her.
Running critique...
1. kimi-k2.6: Strongest sensory immersion and subtext.
2. deepseek-v3.2: Precise, technical voice fits cyberpunk; slightly clinical.
3. llama-3.3-70b: Good atmosphere; ending feels slightly rushed.
4. qwen-3-32b: Solid imagery; "fillings" detail is vivid but slightly jarring.
Wrap-up and next steps
That script gives you a repeatable way to audition models for your own genre. From here, add a temperature sweep to test consistency across 0.7, 0.9, and 1.1. You could also wrap the harness in a small Gradio app and let your editorial team vote on the outputs.
Because Oxlo.ai uses flat per-request pricing, running hundreds of these comparison calls for long short stories will not balloon your bill the way token-based pricing would. See the details at https://oxlo.ai/pricing.
Top comments (0)