OpenAI SDK: Models, parameters & tokens
Which model you call decides quality, speed and cost more than any prompt trick.
In this post
What this post covers
Which model you call decides quality, speed and cost more than any prompt trick. A small, fast model is
often right for extraction and classification, and a flagship reasoning model for multi-step analysis. This
part covers how to choose, the parameters that matter (reasoning,
max_output_tokens, temperature), and how to count tokens and estimate cost
before you ship.
1. The model line-up (September 2026)
| Model ID | Positioned as | Use it for |
|---|---|---|
gpt-6-astra | most capable, hardest end-to-end work | complex agents, difficult reasoning, when quality dominates cost |
gpt-5.6-sol | general-purpose flagship | complex professional tasks |
gpt-5.6-terra | balance of intelligence and cost | most production features |
gpt-5.6-luna | optimised for cost-sensitive workloads | classification, extraction, routing, high volume. The default in this guide |
The table reflects OpenAI's models page when this was written. New models appear every few months and old ones are deprecated on published schedules. Keep the model name in configuration (an environment variable or settings file), not scattered through code, and re-run your evals (part 18) before switching.
2. How to choose: start small, measure, move up
3. The parameters that matter
from fake_openai import fake_client
client = fake_client(script=["Positive"])
r = client.responses.create(
model="gpt-5.6-luna",
instructions="Classify the sentiment as Positive, Negative or Neutral. Reply with one word.",
input="The delivery was late but the support team sorted it out brilliantly.",
reasoning={"effort": "low"}, # how much the model thinks before answering (reasoning models)
max_output_tokens=50, # hard cap on output (includes reasoning tokens on reasoning models)
store=False, # don't keep this response on OpenAI's side (lesson 15)
metadata={"feature": "review-sentiment"},
)
print(r.output_text)
print(client.fake.requests[0]["body"]["reasoning"], client.fake.requests[0]["body"]["max_output_tokens"])
Output
Positive
{'effort': 'low'} 50
| Parameter | Effect | Guidance |
|---|---|---|
reasoning.effort | how many (billed) reasoning tokens the model may spend before answering | low for simple tasks; raise only when evals show it helps |
max_output_tokens | caps output; the response may be incomplete if hit | always set one in production, to bound cost and latency |
temperature / top_p | randomness of sampling (classic chat models) | some reasoning models do not accept them. Check the model's docs; prefer instructions and structured outputs for consistency |
text.verbosity | how long answers tend to be (newer models) | a cheap way to shorten outputs |
store, metadata | server-side retention and tags for your own tracking | see parts 15–16 |
Reasoning models think in hidden tokens that appear in usage.output_tokens_details.reasoning_tokens
and are billed as output. A short visible answer can still use hundreds of reasoning tokens.
max_output_tokens counts them too, so a cap set too low produces an incomplete response
with no visible text.
4. Counting tokens and estimating cost
exact counts with tiktoken (pip install tiktoken)
import tiktoken
enc = tiktoken.get_encoding("o200k_base") # the encoding family used by recent OpenAI models
text = "Delivery to Thiruvananthapuram was delayed by two days."
tokens = enc.encode(text)
print(len(tokens), [enc.decode([t]) for t in tokens][:8])
a cost estimator you can run before launching a feature
# Prices per 1M tokens (USD) from the models page when this was written; keep them in config.
PRICES = {"gpt-5.6-luna": {"input": 0.20, "output": 1.20}}
def estimate_monthly_cost(model, requests_per_day, input_tokens, output_tokens, days=30):
p = PRICES[model]
per_request = (input_tokens * p["input"] + output_tokens * p["output"]) / 1_000_000
return per_request, per_request * requests_per_day * days
def rough_tokens(text): # ~4 characters per token for English; use tiktoken for accuracy
return max(1, len(text) // 4)
prompt = "Classify this review as Positive, Negative or Neutral: " + "great product " * 40
per_req, monthly = estimate_monthly_cost("gpt-5.6-luna", requests_per_day=20_000,
input_tokens=rough_tokens(prompt), output_tokens=5)
print(f"~{rough_tokens(prompt)} input tokens → ${per_req:.6f} per request, ${monthly:,.2f} per month")
# the same feature with a 2,000-token output (e.g. a long summary) instead of one word:
_, monthly_long = estimate_monthly_cost("gpt-5.6-luna", 20_000, rough_tokens(prompt), 2_000)
print(f"with 2,000 output tokens: ${monthly_long:,.2f} per month")
Output
~153 input tokens → $0.000037 per request, $21.96 per month
with 2,000 output tokens: $1,458.36 per month
Output length dominates. Asking for a one-word label instead of a paragraph can cut the cost of a
feature by orders of magnitude. After launch, track real usage from every response (part 13).
Recap
- Start with the smallest model, evaluate, upgrade only where needed, and route by difficulty.
- Keep model names in configuration; they change often.
reasoning.effortandmax_output_tokensare your main cost and latency levers.- Estimate cost before launch with token counts × prices; output length matters most.
Get the free RAG production checklist
25 checks to run before real users see your RAG feature: exact-match misses, invented citations, prompt injection through documents, quality that slips after a prompt change. Confirm your email and the PDF comes with the welcome email, plus each new experiment.