Building AI Agents from Scratch

Build Your First LLM Application

Call an OpenAI-compatible chat API with system and user messages and print a real response.

Before an agent exists, you need a process that can reach a model. One file, three messages, a printed reply. If this fails, nothing later will work.

Project

python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate

python -m pip install --upgrade pip
python -m pip install "openai>=1.40"

The official openai client talks Chat Completions. Compatible hosts (OpenAI, Groq, OpenRouter, many local servers) honor OPENAI_BASE_URL. The key stays in the environment — never in the file.

set OPENAI_API_KEY=sk-...
# optional compatible host:
set OPENAI_BASE_URL=https://api.groq.com/openai/v1
set OPENAI_MODEL=llama-3.3-70b-versatile

One completion

Create chat.py:

import os

from openai import OpenAI

client = OpenAI(
    api_key=os.environ["OPENAI_API_KEY"],
    base_url=os.environ.get("OPENAI_BASE_URL") or None,
)
model = os.environ.get("OPENAI_MODEL", "gpt-4.1-mini")

response = client.chat.completions.create(
    model=model,
    messages=[
        {"role": "system", "content": "You are a concise lab assistant. Answer in two sentences."},
        {"role": "user", "content": "What is a context window?"},
    ],
)
print(response.choices[0].message.content)

system is standing orders. user is this turn. The reply is choices[0].message.content. We omit temperature so a host that rejects it still works.

Check it

  1. Run python chat.py. You should see two sentences, not a traceback.
  2. Change the system prompt to “Answer only with a number.” Ask a counting question. The shape of the reply should change.
  3. Unset the key and confirm the client fails before you add tools.

Next: wrap that call in a loop you control.