Message Roles

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 shapes how; user asks what
  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:

  1. A system message: answer in one short sentence
  2. 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).