Phase 03 · Talking to models: the API layer Core

LLM API Tutorial

The standard request format for every LLM: a list of messages, each with a role (system / user / assistant), sent fresh on every call.

In plain terms

Talking to a model over API is like mailing a transcript of a play to an actor and asking 'write the next line'. The transcript lists who said what - the director's instructions (system), the customer's lines (user), the actor's past lines (assistant). The actor keeps nothing; you mail the whole transcript every time.

Why it matters

Raw models just continue text. The messages format gives conversations structure - who's speaking, what are the standing instructions - and became the universal contract across OpenAI, Anthropic, Google and every open-model server.

How it works

You send JSON: a model name, an optional system instruction, and messages: [{role, content}, ...]. The API returns the assistant's next message plus a usage token count. 'Memory' is an illusion you build: append each reply to your list and resend it all next turn.

When you use it

Every single interaction with a hosted model - chatbots, extraction, agents - flows through this shape.

In code

from anthropic import Anthropic
client = Anthropic()  # reads ANTHROPIC_API_KEY env var
history = []
while True:
    history.append({"role": "user", "content": input("you: ")})
    reply = client.messages.create(
        model="claude-sonnet-5", max_tokens=500,
        system="You are a concise assistant.",
        messages=history)
    text = reply.content[0].text
    history.append({"role": "assistant", "content": text})
    print("bot:", text)

Common mistakes

  • Assuming the API remembers previous calls - statelessness is rule #1; forget it and your bot has amnesia.
  • Mixing up roles (instructions in user, user data in system), which weakens both.
  • Ignoring the usage field, flying blind on cost.

Best practices

  • Write one small wrapper function for model calls (handles auth, retries, logging) and use it everywhere.
  • Store conversation history in your own database, keyed by user/session.
  • Read your provider's API reference end to end once - 30 minutes that saves 30 hours.

Try it yourself

Using any provider's Python SDK, build a terminal loop: read input, append to a messages list, call the model, print and append the reply. Congratulations - you've built ChatGPT's skeleton in ~20 lines.

Deep dive

LLM APIs are the production doorway to AI models. Your app sends messages and settings, receives model output, and handles cost, latency, streaming, and failures.

What it is

An LLM API lets your backend call a hosted model with messages, system instructions, tool definitions, and output settings.

Why it matters

Almost every Gen AI app starts by calling a model API reliably and safely from server-side code.

How it works

Send a request with messages and parameters, handle the response, stream chunks when user-facing, and log usage for cost and debugging.

Common mistakes

  • Putting API keys in browser code.
  • Ignoring rate limits and timeouts.
  • Forgetting that APIs are stateless unless you resend history.

Best practices

  • Keep provider calls server-side.
  • Add retries with backoff.
  • Track token usage from day one.

Practical workflow

client.messages.create(model='...', messages=[{'role':'user','content':'Explain RAG'}])

Resources

FAQ

Should LLM API calls happen in the frontend?

No. Keep provider keys and model calls behind a protected backend.

When should I stream responses?

Stream long user-facing answers so the interface feels responsive.