Prompt EngineeringHow instructions land
The system prompt and the user turn
Which half of the request is the frame, and which half is the job.
WHY THIS, FOR YOU
You have one long user message doing everything — the rules, the examples, the pasted document and the actual question, all in one block. It works, roughly, until a user's own text argues with your rules and wins, or until a chat runs to turn nine and the model is back to the habit you told it to drop. The split between the system prompt and the user turn is not cosmetic, and it is not a law either. This lesson shows what changes when a line crosses that boundary, why a conversation is a list you can only add to, and when to leave the split alone.
The Messages API gives you a system parameter beside the messages list, and it is easy to read that as tidiness. It is more than that, and less than a lock. This lesson is about which text is the frame and which is the job, and what happens to each as a conversation grows. Where a line sits inside a slot, and what the cache does with it, is the next lesson.
1.Two slots, one default
Mechanically, the system prompt, the history and the new message are joined into one sequence before the model reads any of it. That does not make the slots interchangeable.
Position. The system prompt is at the front of every call. As a chat grows, a rule typed into turn 2 slides further back behind newer text. A system rule never moves.
Training. As of October 2026, models are post-trained on data where the system prompt is the operator's standing instruction and the user turn is the request being served. That is a learned prior, and a strong one. When the two conflict, the system prompt usually wins.
Usually, in the vendor's own guidance, is not always. Nothing in the API enforces it, and a user message with convincing instructions can still steer the model. Hamel Husain and Shreya Shankar, in an evals FAQ from September 2026, advise a different default when you are unsure: put the text in the user turn, because it moves between models more easily and is easier to debug. They give no data. Treat both views as opinion, and treat the split below as a default you confirm by running your own cases with the rule in each place.
| Goes in the system prompt | Goes in the user turn |
|---|---|
| Who it is and what job it does | The specific request, this time |
| Rules that are true on every call | The data for this one call |
| The output format and field names | The one variable question |
| Tone and register | The user's own words, unedited |
| What to do when the answer is not in the source | Anything that changes per call |
A rule that arrives in a user message reads as this request's preference, and the next message can talk it out of it. A rule in the system prompt reads as policy, which is harder to argue with.
Anything you would be annoyed to see change between calls belongs in the system prompt.
Rules, examples, the document and the question arrive in one block, in whatever order they were typed. A user's own words sit beside your rules with no signal that one outranks the other.
Role, rules and format go in the system prompt. The document and the question go in the user turn. Then test the split against your own cases.
More rules is not better. The Claude Code team said in a July 2026 conversation that they cut their agent's system prompt hard for the newest models and keep a separate prompt per model. That is one team describing its own product, with no published eval, so use it as a reason to re-read a long prompt whenever you change models, not as a number. They also counted tool definitions as part of the prompt, which is true: the model reads them too.
2.A conversation is a list you append to
The API is stateless. Your code resends the whole conversation every turn, so your newest instruction competes with everything said earlier, including the model's own replies. Those replies are few-shot examples whether you meant them to be or not. Five bulleted answers teach it that this conversation produces bullets, and one sentence at turn 6 asking it to stop is outnumbered.
As of October 2026, on Sonnet 5.5 and the other newest models the vendor lists, a thinking block stays valid only while system, tools and the earlier messages are unchanged. Edit a turn, rebuild system or summarise old turns in place, and the next request either errors or, if you opt in, drops the block. For accounts created on or after 31 August 2026 the vendor says Sonnet 5.5 enforces this with an error. The rule is append-only.
from anthropic import Anthropic
client = Anthropic()
MODEL = "claude-sonnet-5-5" # as of October 2026
def text_of(resp) -> str:
return "".join(b.text for b in resp.content if b.type == "text")
# The format rule is here before turn one. Changing system later breaks the history.
SYSTEM = """You write release notes for a developer tool.
One line per user-visible change. Plain past tense. No bullets, no headings.
If a change has no user-visible effect, omit it entirely."""
history = [] # append only: never edit, reorder or summarise an earlier turn
def ask(user_text: str) -> str:
turn = {"role": "user", "content": user_text}
resp = client.messages.create(
model=MODEL,
max_tokens=2000, # thinking is on by default and counts against this
system=SYSTEM,
messages=history + [turn],
)
if resp.stop_reason != "end_turn":
raise RuntimeError(f"no usable answer: {resp.stop_reason}")
# Commit only after success. Keep the whole assistant turn, thinking blocks
# included, exactly as it came back.
history.extend([turn, {"role": "assistant", "content": resp.content}])
return text_of(resp)
print(ask("fix(auth): correct token expiry check"))
print(ask("feat(export): add CSV export to reports"))
# A later change is a new turn, not an edit of an old one.
print(ask("From now on, put the area first, like 'Auth: ...'."))
The parameter spellings are copied from the vendor docs as of October 2026, not run here, so try them on your SDK version first. Committing both turns only after the check keeps a failed call from leaving a half-finished turn in the list.
The failure case. Suppose SYSTEM had no format rule. The first user asked for bullets, the model gave bullets for five turns, and at turn 6 someone typed "stop using bullets". By turn 9 the bullets are back. The tempting fix is to edit turns 1 to 5 into plain lines and resend. On a thinking model that edit makes the later blocks invalid, so you get an error, or the block is dropped. Better, in order:
- Prevent it. Put the rule in
systembefore turn one. Rebuildingsystemmid-chat has the same binding problem. - In a running chat, append a firm, specific turn, and check the next answer. Nothing guarantees a new turn beats five old examples, so measure.
- Or start a new conversation whose first turn carries a short summary. It has no earlier blocks to invalidate.
- Append a correcting turn
- Start a new conversation from a summary
- Plain chat only: edit in place, strip old thinking blocks
Two smaller notes from the vendor, both as of October 2026. A mid-conversation system message, in beta, is the vendor's way to change instructions without rewriting history. And the old trick of ending the list with a half-written assistant turn, so the model continues it, is a 400 on Claude 4.6 models and Mythos Preview. Ask in the user turn, or use structured outputs, covered in Output contracts.
3.Channels carry weight, and when to leave the split alone
Where a piece of text arrives is a signal the model reads. As of October 2026, current models are trained to resist indirect injection, and the Sonnet 5.5 guide says that has a side effect. A real user message placed inside a tool_result, or wedged right after one, can be read as an attack. The model may tell the user the tool output impersonated them, or stop to ask for confirmation. The vendor gives no rates. Its advice is plain: user words go in a user turn as a text block after the last tool result, tool output stays in tool_result, and harness notices go in a separate system message.
That signal is a training prior, like the system prompt's weight, and not a lock. The system prompt is not a security boundary, and Prompt injection explains why.
When not to use the split. A one-shot call with a short prompt gains nothing from it. One user message with the rules at the top reads fine, and the system slot buys you no weight you will notice. Skip it too when your own cases show the user-turn version scoring the same, because the user turn is the more portable choice if you may change models. Do not use the system prompt as a dumping ground either. Every standing rule is a rule that applies to every call, so check each one for the case where it is wrong.
Everything dated above will move, and the model-specific rules most of all. The ideas underneath are steadier: the frame goes first, the model copies what it has already said, and you confirm a placement by measuring it.
Next: how the pieces sit inside the request, and what that decides for the cache — Prompt layout and the cache.
WHAT YOU TAKE AWAY
- Put rules that are true on every call in the system prompt, and treat that as a default you test, not a law.
- Set the format in the system prompt before turn one, because the model copies its own earlier replies.
- Keep the messages list append-only wherever thinking is on.
- Send user words in a user turn, never inside a tool result.
- Never treat the system prompt as a security boundary.
RECALL NO SCROLLING BACK
The system prompt tends to win a conflict with the same text in a user turn because...
You are unsure whether a rule works better in the system prompt or the user turn on your model. The best move is...
On Sonnet 5.5 with thinking on, a chat drifts back to bullets at turn 9. The safest fix is...
A user types a message while your agent is waiting on a tool. Where do their words go?
A teammate says the system prompt will stop users from overriding your rules. The accurate reply is...
GO DEEPER
- Anthropic — prompting best practices, giving Claude a role (opens in a new tab)
- Anthropic — prompting Claude Sonnet 5.5 (opens in a new tab)
- Anthropic — what is new in Sonnet 5.5 (thinking blocks and history) (opens in a new tab)
- Husain and Shankar — AI evals FAQ (system versus user prompt) (opens in a new tab)
- Willison — fireside chat with the Claude Code team (self-reported results) (opens in a new tab)