A prompt is structured input, not a blob of text. Four concepts — message roles, the patterns that make prompts reliable, the stateless request loop, and system prompts as set-once behavior programming.
The 4 concepts of prompting
Tap any concept to jump to its 5-card cluster.
A prompt is a list of labeled messages
You don't send one blob of text. A prompt is a list of messages, each with a role: system (the rules and persona), user (the request), and assistant (the model's previous replies).
The roles tell the model who is speaking and how to weight each part. System instructions carry the most authority; user turns are the task; assistant turns are the running history. Structure, not just wording, shapes the answer.
A script with named speakers
BEFORE: Imagine you could only talk to the model by typing one giant paragraph — your rules, your question, and its past answers all mashed together with no labels.
PAIN: The model can't tell your standing instructions from a one-off question, or its own past words from yours. Everything blurs, and behavior drifts.
MAPPING: Roles turn the blob into a script with named speakers: DIRECTOR (system) sets the scene, ACTOR-YOU (user) says a line, ACTOR-MODEL (assistant) replies. Now everyone knows their part — the model reads the play instead of a wall of text.
The three roles
- systemDurable behavior: persona, rules, output format, tool policy. Usually the first message.
- userThe actual request or the human's turn in the conversation.
- assistantThe model's prior replies — included so it can see what it already said.
- You assemble the listEach call sends the whole ordered array; the model reads it top to bottom.
Pseudocode
messages = [ { role: "system", content: "You are a concise ops assistant." }, { role: "user", content: "Summarize this alert: ..." }, # after the model replies, you append it: { role: "assistant", content: "Severity: high..." }, { role: "user", content: "Who should own it?" }, ] reply = model.chat(messages)
Misconceptions
user vs system changes how reliably it's followed.A prompt is an ordered list of role-tagged messages: system, user, assistant. Structure guides the model as much as wording.
Put durable rules in system, the task in user, and real replies in assistant.
Reliable prompting is patterns, not luck
Good prompts aren't magic phrases — they're a handful of reusable patterns: give clear, specific instructions; show few-shot examples of the input→output you want; ask for chain-of-thought ("think step by step") on hard reasoning; and specify the exact output format.
Each pattern targets a specific failure. Vague results → add specificity. Wrong format → add an example. Bad reasoning → ask it to show its work. You compose them like tools.
Briefing a new contractor
BEFORE: Early users had one move: type a question and hope for the best — like telling a new contractor "make it nice" and walking away.
PAIN: "Make it nice" gets you something, but rarely what you pictured. Redo after redo, because you never showed them the target.
MAPPING: Patterns are a proper brief: precise instructions ("2 coats, matte white"), an example photo (few-shot), and "walk me through your plan first" (chain-of-thought). Show the target and the reasoning, and the result matches on the first try far more often.
The core patterns
- Be specificState the task, constraints, and audience. Replace adjectives ("concise") with rules ("max 3 bullets").
- Few-shot examplesShow 1–3 input→output pairs. Examples beat descriptions for teaching format and style.
- Chain-of-thoughtFor multi-step reasoning, ask it to think step by step before answering — accuracy rises.
- Specify output formatSay exactly what shape you want (JSON keys, bullet count) so the result is parseable.
Match the pattern to the failure
IF output is vague / off-target: → add specificity + constraints IF format / style keeps drifting: → add few-shot examples IF multi-step reasoning is wrong: → ask for chain-of-thought IF you need to parse the result: → specify an exact output format # smaller models need MORE of these
A 7B model like Mistral leans harder on examples and explicit format than a frontier model does.
Misconceptions
Prompting is composable patterns: specificity, few-shot examples, chain-of-thought, explicit format. Each fixes a specific failure.
Show the target with an example rather than describing it — especially for smaller local models.
The model forgets between calls
Each API call is stateless: the model remembers nothing from the last one. What feels like "memory" in a chat is an illusion — you resend the entire conversation (all prior messages) on every request.
So a multi-turn chat is really: build the messages list → call → append the reply → add the next user turn → call again with the whole thing. The model re-reads the full history each time, because to it, every call is the first.
The clerk who forgets you every visit
BEFORE: In a chat app like iMessage, the other person just remembers the conversation — you never re-explain what you already said.
PAIN: The model isn't that person. It's a brilliant clerk with amnesia: helpful in the moment, but the instant you leave the window, it forgets you completely.
MAPPING: So you carry a folder. Each visit you hand the clerk the whole file — every prior exchange — and they answer as if reading it fresh. The "conversation" lives in your folder, not the clerk's head.
One turn of a chat
- Send the full historyEvery message so far goes in the request — system, all user and assistant turns.
- Get one completionThe model reads it all and returns the next assistant message.
- Append itAdd the reply to your list so the next call includes it.
- Add the next user turn & repeatThe list grows each turn — which is why context and token budgeting (M02) matter so much.
Pseudocode
history = [ system_message ] FUNCTION turn(user_text): history.append({ user: user_text }) reply = model.chat(history) # send the WHOLE list history.append({ assistant: reply }) RETURN reply # the model kept no memory — # 'history' IS the memory, and it lives # in your code, growing every turn.
Misconceptions
The API is stateless — you resend the full conversation every call. "Memory" is your growing messages list, not the model's.
Because history grows each turn, managing it (M08, M11) is a core agent skill, not an afterthought.
Set-once behavior programming
The system prompt is where you program the agent's durable behavior once: its persona, its rules, its output format, its tool policy. It sits at the top of every request and colors everything the model does.
It's the highest-leverage text you write — a few careful lines steer thousands of responses. Put anything that should hold across the whole conversation here; keep user messages for the specific task of the moment.
The employee handbook
BEFORE: Without a system prompt, every user message has to re-explain how the model should behave — "be concise, respond in JSON, stay professional" — over and over.
PAIN: Repeating the rules each turn is wasteful and inconsistent; miss them once and behavior slips. It's like re-training an employee at the start of every task.
MAPPING: The system prompt is the employee handbook: written once, applies to everything. The employee reads it on day one and every task follows it, so each user request can just be the task — not a re-briefing.
What goes in the system prompt
- Persona & toneWho the agent is and how it speaks ("a terse ops assistant").
- Rules & constraintsWhat it must always/never do, safety limits, refusal policy.
- Output contractThe format it should return (JSON shape, structure) when that's constant.
- Tool policyWhen to use which tool, and how to handle failures — durable guidance for the loop.
System or user message?
IF it should hold for the WHOLE conversation (persona, rules, format, tool policy): → put it in the SYSTEM prompt IF it's specific to THIS request (the actual task, this input): → put it in the USER message # durable = system, one-off = user
Misconceptions
The system prompt programs durable behavior once — persona, rules, format, tool policy. Highest leverage per token.
Durable rules go in system; the moment's task goes in user. For must-hold guarantees, add real guardrails too.
Test the core insight
One question per concept. Tap to reveal the answer.
system as higher-priority standing rules, user as the task, and assistant as its own history. The same rule is followed more reliably in system than buried in a user message.Open the full module on desktop
The desktop version has you craft real system prompts and few-shot patterns against local Mistral, watch the stateless loop grow a message list turn by turn, and build a reusable prompt template — in Python and Node.
Open M03 on Desktop → Roles · patterns · stateless loop · system prompts · ~50 minModule 3 of 26 · Open Source Track · Foundations