Generate a small synthetic dataset with ordinary Chat Completions requests, validate each record, and resume from a local JSONL file. This recipe has not been live-tested. Every submitted generation uses normal API credits; it does not use a Batch API or a discounted background job.
Install and define a bounded job
python -m pip install openai
export REDROUTER_API_KEY="your-redrouter-api-key"
Save as generate.py:
import hashlib
import json
import os
from pathlib import Path
from openai import OpenAI
MODEL = "red-cyber-1"
PROMPT_VERSION = "qa-v1"
OUTPUT = Path("examples.jsonl")
topics = ["HTTP conditional requests", "database transactions", "bounded queues"]
completed = set()
if OUTPUT.exists():
for line in OUTPUT.read_text().splitlines():
record = json.loads(line)
completed.add(record["task_id"])
with OpenAI(
api_key=os.environ["REDROUTER_API_KEY"],
base_url="https://redrouter.org/v1",
max_retries=0,
timeout=120,
) as client, OUTPUT.open("a") as output:
for topic in topics:
task_id = hashlib.sha256(
f"{MODEL}:{PROMPT_VERSION}:{topic}".encode()
).hexdigest()
if task_id in completed:
continue
result = client.chat.completions.create(
model=MODEL,
messages=[
{"role": "system", "content": (
"Return a JSON object with exactly two nonempty string fields: "
"question and answer. Create one factual introductory training "
"example about the supplied topic. No personal data."
)},
{"role": "user", "content": topic},
],
response_format={"type": "json_object"},
max_tokens=1024,
temperature=0.7,
)
choice = result.choices[0]
if choice.finish_reason != "stop":
raise RuntimeError(f"Incomplete generation for {task_id}")
example = json.loads(choice.message.content or "")
if not isinstance(example, dict) or set(example) != {"question", "answer"}:
raise ValueError(f"Invalid fields for {task_id}")
if any(not isinstance(v, str) or not v.strip() for v in example.values()):
raise ValueError(f"Invalid values for {task_id}")
record = {
"task_id": task_id,
"model": MODEL,
"prompt_version": PROMPT_VERSION,
"topic": topic,
"response_id": result.id,
"usage": result.usage.model_dump() if result.usage else None,
"example": example,
}
output.write(json.dumps(record, ensure_ascii=False) + "\n")
output.flush()
os.fsync(output.fileno())
completed.add(task_id)
print(f"Saved {task_id}")
Run python generate.py. Expected result: three validated JSONL records, each with its input topic and generation metadata. Run it again to skip saved tasks. A malformed existing file fails visibly; back it up and inspect any partial final line before resuming. Do not run multiple writers against the same file.
Separate validity from quality
The selected model supports JSON output, but valid JSON is only the first check. The script validates required fields and nonempty values before saving. For richer records, use JSON schema output and validate the returned object in your application.
Review factual accuracy, duplicate questions, answer leakage, topic balance, and suitability for the intended task. Hold out evaluation sources before generation; splitting near-duplicate generated examples afterward can inflate evaluation scores. Record human review decisions separately rather than treating generated records as approved training data.
Scale without losing control
The example runs sequentially with at most three requests and no retries. Increase volume only after estimating input/output costs and checking rate limits. Bound concurrency, queue length, attempts, and the total spend. Shorten or split tasks that hit the output cap; never save truncated JSON as a successful record.
Resume skips completed local records, but it does not provide exactly-once billing. A process or network failure after generation and before the file write can lead to another paid request on the next run. Treat that as an ambiguous outcome and review it before resubmitting. See production guidance.
red-cyber-1 is text-only. For document or image datasets, extract appropriate text or select a catalog model with image input. Confirm source rights and your own data policy before sending private material; data handling explains request retention and Zero Data Retention.
Reference: OpenAI Python SDK interface, used with the RedRouter endpoint above.