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 type | Do |
|---|---|
| Claude Fable 5.1, Opus 5.5, Sonnet 5.5, Haiku 5.5 | Enable 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 reasoning | Ask 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.
| Slot | Put here | Not here |
|---|---|---|
| System prompt | Role, standing rules, output format, tone. | The specific task data. |
| User message | The 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.
| Gotcha | Fix |
|---|---|
| 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. |