Overview

These are skeletons to paste and adapt; the reasoning behind each is in prompt-design and the template conventions are in prompt-templates. Put long reference material first and the task or question last.

XML delimiters

Wrap each kind of content in its own tag so the model separates instructions from data. Use one tag name per role and refer to the tags by name.

You are a copyeditor. Apply the rules in <instructions> to the text in <input>.

<instructions>
- Fix grammar and spelling; keep the author's voice.
- Mark claims you cannot verify with [VERIFY].
</instructions>

<input>
{{USER_DOCUMENT}}
</input>

Return only the edited text.

Few-shot

Use three to five varied examples, including one near a category boundary. Details are in few-shot.

Classify each message as REFUND, SHIPPING, TECHNICAL, or OTHER. Answer with the label only.

<examples>
<example><input>My package never arrived.</input><output>SHIPPING</output></example>
<example><input>I want my money back.</input><output>REFUND</output></example>
<example><input>The export button crashes the app.</input><output>TECHNICAL</output></example>
</examples>

<input>{{MESSAGE}}</input>

Reasoning

Prefer built-in adaptive thinking over handwritten step lists.

Model typeDo
Claude Fable 5.1, Opus 5.5, Sonnet 5.5, Haiku 5.5Enable adaptive thinking and set output_config.effort; do not hand-write step lists.
Claude Haiku 4.5 (previous generation)Extended thinking with thinking.budget_tokens, or the <thinking> pattern below.
Models without built-in reasoningAsk for reasoning in <thinking> tags, then the result in <answer> tags, and parse only the answer.

See reasoning-model-prompting and chain-of-thought.

System and user roles

Put standing rules in the system prompt and task data in the user turn.

SlotPut hereNot here
System promptRole, standing rules, output format, tone.The specific task data.
User messageThe content to process this call.Rules that must not be overridable.

The Anthropic Messages API takes the system prompt as a top-level system parameter, not as a message role:

client.messages.create(
    model="claude-sonnet-5-5",
    max_tokens=1024,
    system="You are a code reviewer. Check correctness, security, and style.",
    messages=[{"role": "user", "content": f"<code>{code}</code>"}],
)

Structured output

Constrain the format in the API, not with a pasted schema and a prefilled {. On Claude, pass the schema through output_config.format, or use a strict: true tool for schema-valid tool input; see structured-output. Validate with pydantic, zod, or ajv anyway and retry once with the error message on failure.

Gotchas

Avoid these; each fails on current Claude models or invites prompt injection.

GotchaFix
Assistant prefill returns HTTP 400 on Claude 4.6 and later and all 5.x models.Use structured outputs, or state the format in the system prompt.
Text inside <input> can carry instructions.Say it is data, and apply the controls in prompt-injection-defense.
”Don’t be vague” teaches little.Show the desired output as an example.
System prompts can be extracted by users.Keep keys and confidential logic out of them.