The system prompt is where stable instructions belong, and it is also what you will later cache.
In the Messages API the system prompt is not a message in the list. It is a separate top-level parameter called system, sent next to messages. Whatever you put there applies to the whole conversation: Claude's role, the rules it must follow, the output style, and background facts.
A good split is:
system: things that stay the same on every request ("You are a support assistant for Acme. Answer in two short paragraphs.").messages: the actual user input that changes each time.
system can be a plain string, or a list of text blocks if you want to mark parts of it for caching later.
Keep instructions specific and give the reason behind a rule; Claude follows "Use plain words, because readers are beginners" better than "Be simple". Long reference material (a policy document, a product catalogue) can go in the system prompt too, wrapped in clear labels such as XML-style tags, so Claude can tell instructions from data.
Some current models also accept extra system messages later in the conversation, but the top-level parameter is the standard place and works on every model.
Example
import anthropic
client = anthropic.Anthropic()
SYSTEM = (
"You are a friendly cooking assistant. "
"Answer in at most three sentences, because users read on a phone."
)
msg = client.messages.create(
model="claude-opus-5-5",
max_tokens=300,
system=SYSTEM, # top-level, not inside messages
messages=[{"role": "user", "content": "How do I keep rice from sticking?"}],
)
print(msg.content[0].text)Remember
systemis a top-level parameter, not a message role- Put stable rules in system, changing input in messages
- Explain why a rule exists; Claude follows reasons well
Watch out for
- Adding {"role": "system"} as the first item in messages; use the system parameter.