C.W.K.
Stream
Lesson 03 of 07 · published

Chat Completions

~22 min · chat-completions, sync, messages

Level 0Tokenizer
0 XP0/54 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

The client.chat.completions.create() method is the workhorse for text generation. You pass a model name, a messages array, and optional parameters.

Async Version

The messages array preserves conversation context. For multi-turn chats, append each assistant response and new user message to the array before the next call.

The shape that doesn't change

Every chat.completions.create call has three required arguments: model, messages, and (for Responses-class models) max_completion_tokens. Every response has id, choices, usage, and created. Knowing this skeleton from memory pays back fast — you stop reaching for docs for the obvious shape and only look up the unusual parameters.

The trap of conversational ergonomics

Because the API is stateless, building a chat UI on top is the developer's responsibility. The most common bug is to keep growing the message array forever — by week three, every request sends 20K tokens of history for a 50-token user message. The trim-by-tokens exercise below is the canonical fix.

Code

Single-turn completion·python
from openai import OpenAI

client = OpenAI()

completion = client.chat.completions.create(
    model="gpt-5.4",
    messages=[
        {"role": "developer", "content": "You are a helpful assistant."},
        {"role": "user", "content": "Explain black holes in one paragraph."},
    ],
    temperature=0.5,
    max_completion_tokens=300,
    reasoning_effort="low",
)

# Access the response
text = completion.choices[0].message.content
usage = completion.usage  # .prompt_tokens, .completion_tokens, .total_tokens
print(text)
print(f"Used {usage.total_tokens} tokens")
Multi-turn with explicit history·python
import asyncio
from openai import AsyncOpenAI

async_client = AsyncOpenAI()

async def get_completion():
    completion = await async_client.chat.completions.create(
        model="gpt-5.4",
        messages=[{"role": "user", "content": "Hello!"}],
    )
    return completion.choices[0].message.content

result = asyncio.run(get_completion())

External links

Exercise

Build a small REPL that maintains conversation history. Add token-budget trimming so the request never exceeds 8K total input tokens — drop oldest non-system messages first.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.