We are building a synthetic dataset generator that produces structured instruction-response pairs for fine-tuning open-source LLMs. It uses Oxlo.ai to run an agentic pipeline that generates, critiques, and formats examples. This is useful for ML engineers who need domain-specific data but want to avoid manual annotation costs.
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: Set up the Oxlo.ai client and define the dataset schema
I start by initializing the client and creating a dataclass to keep every row consistent. I also load my API key from the environment so I do not hardcode secrets.
import os
import json
from dataclasses import dataclass, asdict
from openai import OpenAI
@dataclass
class TrainingExample:
instruction: str
input: str
output: str
category: str
client = OpenAI(
base_url="https://api.oxlo.ai/v1",
api_key=os.getenv("OXLO_API_KEY")
)
Step 2: Generate instruction-response pairs
I use Qwen 3 32B because it handles agentic workflows and strict formatting reliably. The system prompt forces valid JSON so I can parse the response directly without regex.
GENERATION_SYSTEM_PROMPT = """You are a dataset engineer. Given a domain topic, generate a diverse, high-quality instruction-response pair for training an LLM.
Rules:
- The instruction must be clear, specific, and require domain knowledge.
- The output must be accurate, concise, and helpful.
- Respond ONLY with a JSON object in this exact schema:
{"instruction": "...", "input": "...", "output": "...", "category": "..."}
- Do not include markdown code fences or explanatory text."""
def generate_example(topic: str) -> TrainingExample:
user_message = f"Generate one training example for the topic: {topic}"
response = client.chat.completions.create(
model="qwen-3-32b",
messages=[
{"role": "system", "content": GENERATION_SYSTEM_PROMPT},
{"role": "user", "content": user_message},
],
temperature=0.8,
)
raw = response.choices[0].message.content.strip()
data = json.loads(raw)
return TrainingExample(**data)
Step 3: Critique and filter low-quality examples
Not every sample is worth keeping. I run a second pass with Llama 3.3 70B to score each example on accuracy and clarity, discarding anything below a 4 out of 5.
CRITIQUE_SYSTEM_PROMPT = """You are a data quality reviewer. Review the provided training example and rate it from 1 to 5 based on accuracy, clarity, and usefulness for fine-tuning.
Respond with ONLY a JSON object: {"score": int, "reason": "..."}"""
def critique_example(ex: TrainingExample) -> dict:
user_message = json.dumps(asdict(ex), ensure_ascii=False)
response = client.chat.completions.create(
model="llama-3.3-70b",
messages=[
{"role": "system", "content": CRITIQUE_SYSTEM_PROMPT},
{"role": "user", "content": user_message},
],
temperature=0.2,
)
return json.loads(response.choices[0].message.content.strip())
def is_quality_passed(ex: TrainingExample) -> bool:
result = critique_example(ex)
return result.get("score", 0) >= 4
Step 4: Export to JSONL for training frameworks
Once I have a clean list, I write the records to JSONL in Alpaca format. This loads directly into training frameworks like LLaMA-Factory or Axolotl.
def save_dataset(examples: list[TrainingExample], path: str = "dataset.jsonl"):
with open(path, "w", encoding="utf-8") as f:
for ex in examples:
record = {
"instruction": ex.instruction,
"input": ex.input,
"output": ex.output,
"category": ex.category,
}
f.write(json.dumps(record, ensure_ascii=False) + "\n")
print(f"Saved {len(examples)} examples to {path}")
Run it
This pipeline generates five examples about Python debugging, filters them through the critique agent, and exports the survivors. Because Oxlo.ai uses flat per-request pricing, long system prompts and multi-turn critique loops do not inflate costs the way token-based billing would. See https://oxlo.ai/pricing for current plan details.
if __name__ == "__main__":
topic = "Python debugging with pdb"
raw_examples = [generate_example(topic) for _ in range(5)]
clean_examples = [ex for ex in raw_examples if is_quality_passed(ex)]
save_dataset(clean_examples)
for ex in clean_examples[:2]:
print("Instruction:", ex.instruction)
print("Output:", ex.output[:120] + "...")
print()
Example output:
Saved 4 examples to dataset.jsonl
Instruction: How do I set a conditional breakpoint in pdb that only triggers when a variable exceeds 100?
Output: Use the condition command. First set a breakpoint with b 15, then condition 1 x > 100. The debugger will pause only when the condition is met...
Instruction: Explain the difference between the 'step' and 'next' commands in pdb.
Output: The 'step' command executes the current line and pauses at the first opportunity, which may enter a function call. The 'next' command runs...
Wrap-up and next steps
Feed the JSONL into Unsloth or LLaMA-Factory to fine-tune a model on your domain. After training, evaluate the fine-tuned model by running inference back through Oxlo.ai, where request-based pricing keeps long-prompt evaluation costs predictable.
Top comments (0)