← chapter

Prompting fundamentals

Chapter 3 · the one lever you have on the model

The hour

The whole idea

The prompt is the only interface you get.

You can't retrain the model or read its weights. You decide what goes in the system slot, whether to show examples, and whether to hand it a template.

One question, asked twice

# bare: the model decides length, tone, shape
client.responses.create(model="gpt-5.4-nano", input=QUESTION)

# guided: a system instruction pins the role and the rules
client.responses.create(
    model="gpt-5.4-nano", instructions=SYSTEM, input=QUESTION,
)

Same model. The answer changes completely.

Rules, not vibes

The role is the cheap part. The constraints do the work:

Vague roles drift. Specific rules hold.

OpenAI vs Gemini

# OpenAI: system prompt is a top-level argument
responses.create(instructions=SYSTEM, input=QUESTION)

# Gemini: system prompt hangs off the config
generate_content(
    contents=QUESTION,
    config=types.GenerateContentConfig(system_instruction=SYSTEM),
)

Same prompt text. Different attachment point.

Put it to work — three moves

Each one is a docker compose up web app.

One backend, two SDKs

PROVIDER = os.environ.get("PROVIDER", "openai")
ai = importlib.import_module(f"ai_{PROVIDER}")

PROVIDER=gemini docker compose up --build swaps the SDK. The prompt text is identical across both.

Takeaway

Be specific in the system prompt. Show examples when format matters. Hand it a template when you need the same shape every time. Everything fancier is built on these three.