Understanding the GPT model family is essential for any AI engineer. This lesson covers GPT-4o, the o-series reasoning models, the OpenAI API, and how to choose between GPT and Claude for different tasks.
GPT-4o is OpenAI’s flagship multimodal model, processing text, images, and audio natively.
| Model | Input (per MTok) | Output (per MTok) | Context |
|---|---|---|---|
| GPT-4o | $2.50 | $10 | 128K |
| GPT-4o-mini | $0.15 | $0.60 | 128K |
| GPT-4.1 | $2.00 | $8.00 | 1M |
| GPT-4.1-mini | $0.40 | $1.60 | 1M |
Key strengths: Strong at coding, broad knowledge, fast inference, mature ecosystem with large third-party library support, extensive fine-tuning options.
OpenAI’s o-series models use reasoning tokens — hidden chain-of-thought tokens the model generates internally before producing its visible response.
You pay for reasoning tokens at the output token rate, even though you never see them. A simple question might use 500 reasoning tokens internally before producing a 50-token answer. This means o-series models can be significantly more expensive per request than GPT-4o for simple tasks.
Both APIs follow similar patterns but have important structural differences.
| Feature | OpenAI | Anthropic |
|---|---|---|
| System prompt | messages array (role: system) | Separate system parameter |
| Tool calling | function_calling / tools | tool_use content blocks |
| Streaming | Server-sent events | Server-sent events |
| Response format | choices[0].message | content[0].text |
| Stop reason | finish_reason | stop_reason |
| Vision | Image URLs or base64 in messages | Image blocks in content array |
| Caching | Automatic (no user control) | Explicit cache_control |
OpenAI’s Assistants API provides server-side conversation state, code execution, and file handling — a managed stateful layer on top of the chat completions API.
from openai import OpenAI
client = OpenAI()
assistant = client.beta.assistants.create(
name="Data Analyst",
instructions="You are a data analyst. Use code interpreter to analyze data.",
model="gpt-4o",
tools=[{"type": "code_interpreter"}],
)
thread = client.beta.threads.create()
client.beta.threads.messages.create(thread_id=thread.id,
role="user", content="Analyze this CSV...")
run = client.beta.threads.runs.create(
thread_id=thread.id, assistant_id=assistant.id)
Neither model family is universally better. The choice depends on the task.
| Task Type | GPT-4o Edge | Claude Edge |
|---|---|---|
| Coding | Broader language coverage | Longer code reasoning, fewer hallucinations |
| Creative writing | More varied style | Better instruction following, less refusal |
| Analysis | Code Interpreter for data | 200K context, prompt caching |
| Safety-critical | Established safety tooling | Constitutional AI, less sycophancy |
| Multimodal | Audio input/output, DALL-E | PDF/document understanding |
| Cost-sensitive | GPT-4o-mini is very cheap | Haiku 3.5 competitive on price |
Best practice: Prototype with both. Run your specific tasks on each and measure quality, latency, and cost. The benchmarks tell you averages; your use case may differ significantly.
Live demonstration: send the same prompt to both GPT-4o and Claude Sonnet, then compare outputs.
openai.OpenAI() and anthropic.Anthropic())from openai import OpenAI
import anthropic
openai_client = OpenAI()
claude_client = anthropic.Anthropic()
prompt = "Explain the CAP theorem in distributed systems."
gpt_resp = openai_client.chat.completions.create(
model="gpt-4o", messages=[{"role": "user", "content": prompt}], max_tokens=300)
claude_resp = claude_client.messages.create(
model="claude-sonnet-4-20250514",
messages=[{"role": "user", "content": prompt}], max_tokens=300)
print("GPT-4o:", gpt_resp.choices[0].message.content[:200])
print("Claude:", claude_resp.content[0].text[:200])
LLMClient class