System Prompt vs User Prompt
System prompt vs user prompt describes the two main inputs of a chat-based language model: the system prompt contains persistent instructions written by the developer, while the user prompt contains the specific request for a single turn. The model receives both together and is trained to treat system instructions as higher-priority rules.
- System prompt: Developer-defined instructions that establish the role, rules, output format and boundaries for an entire conversation.
- User prompt: The message submitted for one request, such as a question, a code snippet or an error log.
- Message roles: Chat APIs label every message with a role, typically system, user or assistant, so the system prompt travels as the system message.
- Instruction hierarchy: Models are trained to follow system instructions when a user message conflicts with them, although this protection is not absolute.
- Shared context: Both prompts occupy the same context window and both consume billable tokens.
For example, a code review assistant keeps one system prompt that limits comments to bugs and security, while each user prompt contains a different snippet to review.
Quick Answer
The system prompt defines how the assistant behaves across every request, and the application developer controls it. The user prompt defines what the assistant should do right now, and it usually comes from the end user or from application data. Persistent rules belong in the system prompt, and request-specific content belongs in the user prompt. Keeping this separation makes the assistant's behaviour consistent, testable and easier to secure.
System Prompt vs User Prompt: Comparison Table
| Aspect | System prompt | User prompt |
|---|---|---|
| Author | Application developer | End user or application data |
| Purpose | Defines role, rules and output format | States the specific request |
| Lifetime | Constant across the conversation | Changes with every turn |
| Priority | Higher, by model training | Lower when it conflicts with system rules |
| Typical content | Persona, constraints, format, safety policy | Question, code, logs, documents |
| Visibility | Usually hidden from end users | Written or seen by the end user |
| Change process | Versioned and tested like code | No review before each request |
| Security role | Holds the defensive instructions | Main entry point for prompt injection |
When to Use a System Prompt
- Persistent identity: Assign a role such as "code review assistant for a Python team", a technique described in types of prompting.
- Output rules: Specify formats that must never change, such as a maximum of two bullet points or structured output in JSON.
- Scope restrictions: Limit the assistant to relevant topics, such as bugs and security, and define how to decline other requests.
- Tool policies: Describe when the model may request a function, as covered in tool calling.
- Stable reference information: Include a style guide or naming conventions that apply to every request.
When to Use a User Prompt
- Specific requests: Submit the individual question, diff or log extract that needs a response.
- Variable data: Insert retrieved documents, file contents or database results that change for each request.
- Clarifications: Refine or correct the previous response within the same conversation.
- Per-request options: Request a variation, such as a shorter summary, that stays within the system rules.
- Untrusted content: Place external text, such as a pasted log or a third-party document, in the user prompt and never in the system prompt.
Example
The program below builds the messages for two code review requests that share a single system prompt.
import json
# One system prompt, fixed by the developer and sent with every request
SYSTEM_PROMPT = (
"You are a code review assistant for a Python team. "
"Comment only on bugs and security. Reply in at most two bullets."
)
def build_messages(user_prompt):
return [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": user_prompt},
]
# The user prompt changes with every request
user_prompts = [
"Review: log.info(f'login ok, password={pw}')",
"Review: for i in range(len(items) + 1): print(items[i])",
]
batches = [build_messages(p) for p in user_prompts]
print(json.dumps(batches[0], indent=2))
print("Same system prompt in both:", batches[0][0] == batches[1][0])
print("User prompts differ:", batches[0][1] != batches[1][1])[
{
"role": "system",
"content": "You are a code review assistant for a Python team. Comment only on bugs and security. Reply in at most two bullets."
},
{
"role": "user",
"content": "Review: log.info(f'login ok, password={pw}')"
}
]
Same system prompt in both: True
User prompts differ: True- System side: The review scope and the two-bullet limit are written once, so every request follows identical rules without repeating them.
- User side: Each snippet, the logged password and the off-by-one loop, arrives as a separate user prompt that the developer does not control.
- Consistency check: Comparing the two message lists confirms that only the user message changes between requests.
The same assistant built without a system prompt must repeat every rule inside each user message, as shown below.
User: You are a code review assistant for a Python team.
Comment only on bugs and security. Reply in at most two bullets.
Review: log.info(f'login ok, password={pw}')- Repetition: The rules are copied into every request, which increases token usage and allows the copies to drift apart over time.
- Weaker authority: The rules carry the same priority as the snippet, so text inside the reviewed code can contradict them more easily.
- Harder maintenance: Changing one rule requires updating every place that constructs a user message, instead of one versioned system prompt.
The two prompts solve different problems from context engineering, which decides what additional information enters the context window for each request.
Quick Quiz
Pick an answer to check yourself. Nothing is saved.
Question 1 / 3
1. Who normally writes the system prompt?
Frequently Asked Questions
What is a system prompt?
A system prompt is a set of instructions that the developer sends with every request to a chat model. It sets the assistant's role, rules and output format for the whole conversation. Common system prompt examples assign a role, such as a Python code reviewer, and limit the scope and format of every reply.
Can users see the system prompt?
Most applications do not display it, but it should not be treated as secret. Users can sometimes persuade a model to reveal it, so passwords, keys and private data never belong in a system prompt.
Can a user prompt override the system prompt?
Models are trained to prefer system instructions when the two conflict, but the protection is not complete. Carefully written user text can still override rules, which is why applications add validation and other defences.
Should examples go in the system prompt or the user prompt?
Examples that apply to every request usually go in the system prompt, so they are written once. Examples specific to one request belong in the user prompt.
Related Articles
- What is Prompt EngineeringLearn what prompt engineering is, how to design a prompt step by step, its key characteristics, uses and limits, with a Python code review prompt example.
- Types of Prompting (Zero-shot, Few-shot)Compare the types of prompting: zero-shot, one-shot, few-shot, chain of thought, role prompting and prompt chaining, with a Python few-shot prompt builder.
- What is Context EngineeringLearn what context engineering is: selecting, ranking and fitting information into an LLM context window, with a Python token budget example and limits.
- AI Agent Security and Prompt InjectionPrompt injection in AI agents: direct and indirect attacks, privilege separation, allow-listed tools, output validation and approval, with a Python demo.
- Tool Calling (Function Calling) in LLMLearn how tool calling works in LLMs: JSON Schema tool definitions, model tool calls, argument validation and tool results, with a Python DevOps example.
- Chain of Thought PromptingLearn chain of thought prompting: how step-by-step reasoning improves LLM accuracy and how to parse the final answer, with a Python log triage example.