Build a Multimodal GPT App
The GPT-6 tiers, what reasoning effort replaced, when to use the Responses API over Chat Completions, how the bill is calculated, and what is different on Azure.
Prerequisites
- Python 3.11+Required
python --version
- openai >= 1.30Required
pip install openai
- OPENAI_API_KEYRequired
export OPENAI_API_KEY=...
Build with GPT-6: vision, JSON mode, and streaming
Use the GPT-6 family for vision, structured JSON output, streaming, and function calling.
Tasks
🎯 What You'll Learn
- ▸Send images to a GPT-6 model for visual question answering
- ▸Use response_format json_object for structured output
- ▸Stream responses and measure TTFT
Code
1 import os 2 import json 3 import time 4 import openai 5 from pydantic import BaseModel 6 7 client = openai.OpenAI(api_key=os.environ["OPENAI_API_KEY"]) 8 9 # ── 1. Structured Outputs with Pydantic ──────────────────────────── 10 class TechStack(BaseModel): 11 languages: list[str] 12 frameworks: list[str] 13 databases: list[str] 14 cloud: list[str] 15 16 response = client.beta.chat.completions.parse( 17 model="gpt-6-luna", reasoning_effort="none", 18 messages=[{ 19 "role": "user", 20 "content": "What tech stack does Netflix likely use? List specific technologies.", 21 }], 22 response_format=TechStack, 23 ) 24 stack = response.choices[0].message.parsed 25 print("=== Structured Output ===") 26 print(f"Languages: {stack.languages}") 27 print(f"Databases: {stack.databases}") 28 29 # ── 2. Streaming with TTFT measurement ───────────────────────────── 30 print("\n=== Streaming ===") 31 start = time.perf_counter() 32 ttft = None 33 full_response = [] 34 35 stream = client.chat.completions.create( 36 model="gpt-6-luna", reasoning_effort="none", 37 messages=[{"role": "user", "content": "Write a short poem about machine learning."}], 38 max_completion_tokens=150, 39 stream=True, 40 ) 41 42 for chunk in stream: 43 delta = chunk.choices[0].delta.content 44 if delta: 45 if ttft is None: 46 ttft = (time.perf_counter() - start) * 1000 47 full_response.append(delta) 48 print(delta, end="", flush=True) 49 50 total = (time.perf_counter() - start) * 1000 51 print(f"\nTTFT: {ttft:.0f}ms, Total: {total:.0f}ms") 52 53 # ── 3. Parallel Function Calling ─────────────────────────────────── 54 tools = [ 55 { 56 "type": "function", 57 "function": { 58 "name": "get_stock_price", 59 "description": "Get current stock price", 60 "parameters": { 61 "type": "object", 62 "properties": {"ticker": {"type": "string"}}, 63 "required": ["ticker"], 64 }, 65 }, 66 }, 67 { 68 "type": "function", 69 "function": { 70 "name": "get_news", 71 "description": "Get latest news for a company", 72 "parameters": { 73 "type": "object", 74 "properties": {"company": {"type": "string"}}, 75 "required": ["company"], 76 }, 77 }, 78 }, 79 ] 80 81 response = client.chat.completions.create( 82 model="gpt-6-luna", reasoning_effort="none", 83 messages=[{"role": "user", "content": "Get AAPL stock price and latest Apple news"}], 84 tools=tools, 85 tool_choice="auto", 86 ) 87 88 print("\n=== Parallel Tool Calls ===") 89 if response.choices[0].finish_reason == "tool_calls": 90 for tc in response.choices[0].message.tool_calls: 91 print(f"Tool: {tc.function.name}({tc.function.arguments})") 92
💡 Pro Tips
- ▸Structured Outputs (not just JSON mode) guarantees schema conformance — use it for extraction
- ▸gpt-6-luna handles most tasks at 1/20th the cost of gpt-6.1-sol, and with reasoning_effort="none" it still accepts tools and temperature on Chat Completions; Sol and Astra need the Responses API for tool calling
Continue reading
All LLM Model Landscape articles →Claude: Anthropic's Model Family in Practice
The four Claude tiers, adaptive thinking and effort, the tool-use rules that differ from other providers, prompt caching, and where you can run it.
Llama: Open-Weight Models for Production
The Llama lineup and licence, serving with Ollama and vLLM, GPU memory sizing, and an honest look at when a hosted API is still the better choice.
Evals for Choosing a Model
Why public benchmarks do not transfer to your workload, how to build a model-selection eval, and why cost per successful task beats price per token.
Discussion
Sign in to share your feedback and join the discussion.

