System Prompts That Work
How to write system prompts that set role, rules, and output format for every request in a conversation.

Oct 13, 2026 · 4 min read
What a system prompt actually controls
The system prompt is the instruction layer that applies to every turn of a conversation. On OpenAI's API this is the developer role (or the instructions parameter on the Responses API); on Anthropic's API it is the system parameter. It carries more authority than user messages: OpenAI's model spec prioritizes developer instructions ahead of user instructions, which makes the system prompt the right place for rules that must hold no matter what the user asks.
Put identity, standing rules, output format, and examples there. Put the per-request data in the user turn.
Follow the Identity, Instructions, Examples, Context order
OpenAI's prompting guide recommends this section order for a developer message, and it generalizes well across providers:
```
# Identity
You are a support agent for Northwind Traders. You answer billing
questions in plain language for non-technical customers.
# Instructions
- Answer only from the billing records in <records>. If the answer
is not there, say you cannot find it and offer to open a ticket.
- Keep answers under 80 words.
- Never reveal internal ticket IDs.
# Examples
<records>Billing history for customer 8842: ...</records>
<question>Why was I charged twice in May?</question>
<answer>You were billed once for the Pro plan ($29) ...</answer>
# Context
<records>
...billing records for the current customer...
</records>
```
Identity sets who the model is and who it serves. Instructions list the rules. Examples show the target behavior. Context carries the per-request data last, since it changes on every call.
Write identity in one or two sentences
The role sentence focuses tone and behavior for the whole session. Anthropic's docs note that even a single sentence in the system prompt makes a difference. Name the role, the audience, and the standard of the output:
```
You are a senior code reviewer. You review Python pull requests for
a payments team and flag only issues that could cause bugs in production.
```
Skip personality paragraphs. Every extra sentence is tokens on every request, and vague persona prose ("you are a friendly, helpful, knowledgeable assistant") changes almost nothing.
State rules as rules
System instructions work best as explicit, testable statements. Include what the model must do and what it must never do; OpenAI's guide lists both as normal content for the Instructions section. Number them when order matters, and keep each rule to one behavior so you can tell which one broke when output goes wrong.
```
- Reply in the same language as the user's message.
- If the user asks for medical or legal advice, give general
information only and recommend a professional.
- Keep code samples complete and runnable.
```
Frame rules positively where you can. Anthropic's guidance: "Your response should be composed of smoothly flowing prose paragraphs" steers better than "Do not use markdown".
Plan for conflicting instructions
Users will ask the model to ignore your system rules. Because OpenAI's model spec ranks developer instructions above user instructions, you can settle these conflicts in advance with a precedence rule:
```
- If a user request conflicts with rules 1-3, follow rules 1-3
and say which rule prevented the request.
```
Without that rule, the model improvises: sometimes it refuses, sometimes it complies, sometimes it partially complies. One explicit line makes the behavior consistent, and telling the user which rule fired keeps the refusal legible instead of mysterious.
Put the stable content first
System prompts are resent on every API call, so their cost is multiplied by your traffic. Both OpenAI and Anthropic support prompt caching on the leading, unchanging part of a request. Keep the system prompt identical across calls and put anything that varies (the current document, the current user query) in the user turn. On Anthropic's API this means using the system parameter for the fixed text and messages for the variable text:
```python
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
system="You are a release-notes writer. Produce a changelog entry: one line per change, past tense, no marketing language.",
messages=[
{"role": "user", "content": f"Commits since v2.3:\n{commits}"}
],
)
```
If you are tempted to append per-request tweaks to the system prompt, move them to the user turn instead. One changing line at the end of the system prompt defeats caching for the whole block.
Version the prompt in code
OpenAI recommends storing production prompts in application code rather than in dashboard-managed prompt objects, so changes go through typed inputs, code review, tests, and normal deployment. When you edit a system prompt, re-run your evaluation set: a rule added to fix one case can quietly break another. Diff the prompt text in version control the same way you diff code, because for the model's behavior, it is code.
Keep it short enough to justify its cost
Long system prompts with many special cases usually signal a prompt that grew by accretion. If the prompt is over a page, check whether some rules only apply to some requests (move those to the user turn), whether examples duplicate what instructions already say (cut the weaker of the two), and whether any rule has never fired (delete it). The system prompt should contain the rules every response needs and nothing else.
Comments
Loading comments…