AI Learning Hub
beginner

System, user, assistant — the three roles

A chat with an LLM isn't one text box — it's three. Knowing which goes where is the difference between flaky prompts and reliable ones.

What's actually happening

Modern chat APIs take a list of messages, each with a role and content. (If JSON is new to you: it's just a structured way to write data.)

{
  "model": "claude-sonnet-4-6",
  "messages": [
    { "role": "system",    "content": "You are Bramble, a friendly bookshop assistant." },
    { "role": "user",      "content": "Got any sci-fi under £15?" },
    { "role": "assistant", "content": "Hello! A great pick is Project Hail Mary by Andy Weir…" },
    { "role": "user",      "content": "Does it hold up if I haven't read his other books?" }
  ]
}
RoleSet byNotable property
systemYou, the developerMost heavily weighted — guidance here sticks
userThe end user (or your app on their behalf)Can be hostile (more on this in Safety)
assistantThe model (its previous turn)You can also use this to demonstrate desired output (few-shot)

Two things this implies and the diagram doesn't:

  • You can use the assistant role for examples too. Putting fake prior turns in your request is how few-shot prompting works — show the model 3 example user/assistant pairs, then ask the real question.
  • User content can't be trusted. A user typing "ignore your previous instructions" is asking the model to flip on its handler. Robust systems put their real rules in system and treat user content as data, not commands. (Full lesson in Safety.)

Where it shows up in real life

Under the hood (optional)

If you build with the API, the message-list shape maps directly to the request. ~10 lines of Python. Skip if you don't code.

Show the example code (Python, ~10 lines)click to expand
from anthropic import Anthropic
 
client = Anthropic()
response = client.messages.create(
    model="claude-sonnet-4-6",
    system="You are a senior code reviewer. Be terse, technical, and direct.",
    messages=[
        {"role": "user", "content": "Review this PR: <diff>...</diff>"},
    ],
    max_tokens=1024,
)
print(response.content[0].text)

(Anthropic puts system in its own field; OpenAI expects it as the first item in messages. Same idea, different shape.)

Try it yourself (no coding, ~5 minutes)

Set a system prompt without writing code:

  1. ChatGPT: Settings → "Customize ChatGPT""What traits should ChatGPT have?". Paste: "Always reply in the voice of a 19th-century pirate captain. Use 'arrr' liberally." Save.
  2. Or Claude.ai: create a Project → paste the same in instructions.
  3. Start a new chat. Ask anything — "explain compound interest", "recommend a book". The style changes; the facts stay right.

You've just used the same primitive vendors use to give each AI assistant its personality. Imagine writing: "You're a tax-filing assistant. Never give legal advice. If unsure, say 'consult an accountant.'" That's how products are built on top of LLMs.

Check your understanding

  1. 1. Where does the system prompt belong?
  2. 2. What is few-shot prompting?
  3. 3. Your bot leaks customer info when a user types 'ignore previous instructions'. The right fix:

Found this useful? Share it with someone learning AI.

Further reading

Related lessons in this track