GeekHub Learn
Module

The anatomy of a prompt: system, user, assistant

If you ever wondered why ChatGPT "remembers it is Claude" or "stays in character", it is the system message. Mastering message roles is what separates hobbyists from engineers.

A play has three speakers: the director (system), the audience member who asks (user), the actor who responds (assistant). The director's notes set the stage. The audience asks. The actor delivers, then waits for the next prompt.

Modern chat APIs use a list of messages, each with a role:

  • system: instructions, persona, constraints, format rules. Persistent and high priority.
  • user: the human's request.
  • assistant: the model's previous responses, sent back so the model has memory of what it already said.
  • tool (newer): structured outputs from tool calls.

The API takes the entire array each call. There is no hidden server-side memory unless you build it. You manage memory.

A typical OpenAI call:

from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[
        {"role": "system", "content": "You are a concise tutor. Answer in 2 sentences."},
        {"role": "user", "content": "Explain RAG."},
    ],
)
print(response.choices[0].message.content)

Add the assistant reply back into messages for the next turn. That is conversation memory.

Visualize it

A vertical message list visualization: a settings-icon next to "system", a person-icon next to "user", a sparkles-icon next to "assistant". Show how the array grows turn by turn.

Try it now

Open Google AI Studio or OpenAI Playground. Add a system message that says "Always reply in haiku." Send any prompt. Notice the constraint persists across turns.

Hands-on lab

Write a 5-turn conversation by hand as a JSON array of messages. Include one system, three user, three assistant entries. This is the "wire format" of every chat app.

Try it now

What happens if you put a system instruction inside a user message instead? Is it weaker, stronger, or the same?

Common mistakes

  • Forgetting to append assistant replies to history (model "forgets" each turn)
  • Putting persona inside every user message instead of once in system
  • Building "memory" via repeated system updates instead of clean message arrays

Debugging tip

When the model loses persona, check that your system message is still in the array. When it loops, check you are not double-appending.

Challenge

Build a small script that maintains a chat in a Python list and prints history nicely. No frameworks. Just messages.append(...).

Where this shows up

  • Chatbots with personas (customer support, tutor, sales)
  • Multi-step agents that hand off to one another
  • Tool-using assistants that emit tool messages

From the field

In production, you do not just keep growing the messages array forever. You "truncate", "summarize", or "rolling-window" history. Module 6 will show you how.

Recap

A prompt is an ordered list of role-tagged messages, not a single string. System sets the stage, user asks, assistant remembers. You manage the array, the API replays it.


Quick recall

3 prompts · think before you flip

Prompt 1 of 3

What are the three core message roles?

Quiz time

1 question · tap an answer to check it

  1. 1. To make a chatbot remember what it said two turns ago, you must

Finished lesson 3.2?

Mark complete to update your module progress and unlock the streak.

Loading