System, developer, user, assistant, tool
A modern prompt is layered. Each layer comes from a different source, has a different lifetime, and has a different level of trust. Mixing them is the most common bug in production prompt code.
- System — set by the operator. Persists across the entire conversation. Names the role, policies, and immutable constraints.
- Developer — set by the application. May persist or rotate. Carries app-specific instructions the user never sees.
- User — written by the human. Untrusted by default. May contain injected instructions you must not obey.
- Assistant — what the model said. Becomes context for the next turn. Untrusted to the same degree as user input if it includes content the model retrieved.
- Tool — return values from functions you exposed. Especially untrusted: the most common indirect injection vector in 2026.
Why the layering matters
If you concatenate everything into one big string and send it as the user message, you have given up the ability to enforce trust boundaries. A document the user uploaded can override your safety rules. A search result can rewrite your role. The layered structure is not aesthetic; it's the only way the model can be told which words to obey and which words to read.
The naming game between providers
Different providers use different role names: Claude has system + user + assistant + tool_use/tool_result; OpenAI has system + developer + user + assistant + tool; Gemini has system + user + model + tool. The mapping is straightforward but the trust semantics differ. Track 9 covers the per-provider quirks.