A role is a label on a message that says who that text is from.
In a model API call, each piece of text in the request (and the reply) usually carries one of these labels:
| Role | Meaning |
|---|---|
| user | Your question |
| assistant | The model’s reply |
| system | Standing instructions for how to answer |
Here is one full turn with those labels written out.
Request (what you send):
{
"model": "some-model",
"messages": [
{
"role": "user",
"content": "What is 2 + 2?"
}
]
}
Response (what comes back):
{
"message": {
"role": "assistant",
"content": "2 + 2 is 4."
},
"finish_reason": "stop",
"usage": {
"input_tokens": 10,
"output_tokens": 6
}
}
Same turn in plain form:
user: "What is 2 + 2?"
assistant: "2 + 2 is 4."
The model reads the role as well as the words. That is how it tells your question apart from its own reply — and, next, from standing instructions.
User and assistant
user = you (or your program).
assistant = the model.
Your first API call already used this pair. Some SDKs hide the word role behind a short helper, but the idea is the same: one labeled question, one labeled reply.
System — standing instructions
Sometimes you want rules that are not the question itself:
- “Answer in one short sentence.”
- “You are helping a beginner. Use plain words.”
- “Never invent file paths.”
That is what the system role is for: instructions that shape how the model should answer, separate from what you are asking this turn.
Example request:
{
"model": "some-model",
"messages": [
{
"role": "system",
"content": "Answer in one short sentence. No bullet lists."
},
{
"role": "user",
"content": "What is gravity?"
}
]
}
system → standing rules for this call
user → the question for this turn
│
▼
model runs
│
▼
assistant ← reply (should follow the system rules)Without a system message, the model still answers — it just uses its default style. With a system message, you steer the style and boundaries before the question.
Companies place system text in slightly different spots (inside messages, or a separate system field). The job is the same: standing instructions vs this turn’s question.
Why the labels matter
Compare two requests that use the same words, but different roles:
A — instructions as system
{
"messages": [
{ "role": "system", "content": "Reply with only a number." },
{ "role": "user", "content": "How many legs does a dog have?" }
]
}
B — everything dumped as user
{
"messages": [
{
"role": "user",
"content": "Reply with only a number. How many legs does a dog have?"
}
]
}
Both can work. A keeps “how to answer” and “what I’m asking” in separate labeled boxes. That becomes important when questions get longer, when you add history later, and when tools show up — each piece needs a clear job.
Roles are how you keep those jobs from blurring together.
See it in Code
The Code panel shows one turn that uses:
- A system message: answer in one short sentence
- A user message: a simple question
Then it reads the assistant text. Same idea in Python, Java, Go, and TypeScript.
Cast for this beat
| Word | Meaning |
|---|---|
| Role | Label on a message: who this text is from |
| user | Your question |
| assistant | The model’s reply |
| system | Standing instructions for how to answer |
Next: conversation history — how you send earlier user/assistant messages on purpose so the model can use them (because each call still forgets by default).