🔥 0
0
Lesson 2 of 6 15 min +75 XP

Calling LLM APIs

Time to write code. We'll use OpenAI's API (the most common), but the concepts apply to Claude, Gemini, and others.

Prerequisites:

Get an OpenAI API key from platform.openai.com. You'll need a few cents of credit to follow along.

---

Setup

pip install openai python-dotenv

Create a .env file:

OPENAI_API_KEY=sk-your-key-here

---

Your First API Call

from openai import OpenAI
from dotenv import load_dotenv

load_dotenv()
client = OpenAI()  # Automatically reads OPENAI_API_KEY

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[
        {"role": "user", "content": "What is Python?"}
    ]
)

print(response.choices[0].message.content)

That's it. You just called an LLM.

---

Understanding the Request

Your Code Request model messages[] temperature max_tokens OpenAI

Key Parameters

response = client.chat.completions.create(
    model="gpt-4o-mini",          # Which model to use
    messages=[...],               # Conversation history
    temperature=0.7,              # Creativity (0-2)
    max_tokens=500,               # Max response length
)
Parameter What it does Typical value
model Which LLM to use "gpt-4o-mini" (cheap), "gpt-4o" (smart)
messages Conversation history [{role, content}, ...]
temperature Randomness/creativity 0 = focused, 1 = creative
max_tokens Response length limit 500-2000 for most tasks

---

The Messages Array

This is the most important part. Messages have three roles:

system

Sets behavior, personality, rules. "You are a helpful assistant..."

user

The human's input. Questions, requests, data.

assistant

The AI's previous responses. For conversation history.

messages = [
    {
        "role": "system",
        "content": "You are a senior Python developer. Be concise."
    },
    {
        "role": "user",
        "content": "How do I read a JSON file?"
    }
]

---

Understanding the Response

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Hi!"}]
)

# The response object
print(response.choices[0].message.content)  # The actual text
print(response.choices[0].finish_reason)    # "stop" = completed normally
print(response.usage.prompt_tokens)         # Tokens in your request
print(response.usage.completion_tokens)     # Tokens in response
print(response.usage.total_tokens)          # Total (for billing)
What are tokens?

Tokens are chunks of text (roughly 4 characters or 0.75 words). You pay per token. "Hello world" = 2 tokens. Always monitor usage.total_tokens in production.

---

A Practical Example: Ticket Classifier

Let's build something real - a support ticket classifier:

from openai import OpenAI
import json

client = OpenAI()

def classify_ticket(ticket_text: str) -> dict:
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        temperature=0,  # Deterministic for classification
        messages=[
            {
                "role": "system",
                "content": """Classify support tickets into categories.
                Return JSON with: category, priority, summary
                Categories: billing, technical, account, general
                Priorities: low, medium, high, urgent"""
            },
            {
                "role": "user",
                "content": ticket_text
            }
        ],
        response_format={"type": "json_object"}  # Ensures valid JSON
    )

    return json.loads(response.choices[0].message.content)

# Test it
ticket = "I've been charged twice for my subscription this month!"
result = classify_ticket(ticket)
print(result)
# {"category": "billing", "priority": "high", "summary": "Duplicate charge"}

---

Error Handling

Production code needs proper error handling:

from openai import OpenAI, APIError, RateLimitError, APITimeoutError
import time

client = OpenAI()

def call_llm_with_retry(messages, max_retries=3):
    for attempt in range(max_retries):
        try:
            response = client.chat.completions.create(
                model="gpt-4o-mini",
                messages=messages,
                timeout=30.0  # 30 second timeout
            )
            return response.choices[0].message.content

        except RateLimitError:
            # Wait and retry
            wait_time = 2 ** attempt  # Exponential backoff
            print(f"Rate limited. Waiting {wait_time}s...")
            time.sleep(wait_time)

        except APITimeoutError:
            print("Request timed out. Retrying...")
            continue

        except APIError as e:
            print(f"API error: {e}")
            raise

    raise Exception("Max retries exceeded")

---

Cost Management Tips

1. Use the right model

gpt-4o-mini is 20x cheaper than gpt-4o. Use the smallest model that works.

2. Set max_tokens

Prevent runaway responses. Most tasks need 500-1000 tokens max.

3. Cache responses

Same input = same output (with temp=0). Cache aggressively.

4. Monitor usage

Log every call with token counts. Set billing alerts.

---

Model Comparison (2025)

Model Best for Cost
gpt-4o-mini Most tasks, classification, simple generation $
gpt-4o Complex reasoning, coding, analysis $$
claude-3-5-sonnet Long documents, nuanced writing $
gemini-1.5-flash Fast, cheap, good for simple tasks $

Key Takeaways

  • It's just an API call - HTTP request with JSON, nothing magic
  • Messages array is key - system sets behavior, user provides input
  • Temperature 0 for factual - use low temperature for deterministic outputs
  • Always handle errors - rate limits and timeouts will happen

Next up: Prompt Engineering - how to get better outputs from your LLM calls.

🧠 Quick Quiz

Test your understanding of this lesson.

1

What is the 'messages' array in an OpenAI API call?

2

What does the 'temperature' parameter control?

3

Why should you set max_tokens in production?

The AI Backend Stack