Overview

These patterns are the reusable building blocks for reliable LLM prompts. Each pattern solves a specific failure mode: XML delimiters prevent content injection, few-shot examples outperform abstract instructions, chain-of-thought unlocks multi-step reasoning, role separation keeps behavior consistent across turns, and output schemas eliminate parsing surprises. For the principles behind why each pattern works, see prompt-design.

XML delimiter pattern

Wrap variable content in XML tags so the model distinguishes instructions from data.

Tag conventionUse case
<document>...</document>Reference text the model should read but not follow as instructions.
<instructions>...</instructions>Task instructions separated from context.
<examples>...</examples>Few-shot examples block.
<input>...</input>The specific item to process in this call.
<output>...</output>Where the model should write its answer (in the template).
<context>...</context>Background information; lower priority than instructions.
<thinking>...</thinking>Ask the model to write reasoning here before answering.
You are a copyeditor. Follow the rules in <instructions> and apply them to <input>.

<instructions>
- Correct grammar and spelling.
- Do not change the author's voice.
- Flag any factual claims you cannot verify with [VERIFY].
</instructions>

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

Write the edited document only. No commentary.

Use distinct tag names for each semantic role. Do not reuse the same tag name for different content in the same prompt.

Few-shot template

Provide 2 to 5 input/output examples before the task. Examples override abstract instructions; the model generalizes from them. See few-shot for selection guidance.

Classify each customer message as: REFUND, SHIPPING, TECHNICAL, or OTHER.
Respond with only the category label.

<examples>
<example>
<input>My package hasn't arrived after 3 weeks.</input>
<output>SHIPPING</output>
</example>
<example>
<input>I'd like to return my order for a full refund.</input>
<output>REFUND</output>
</example>
<example>
<input>The app crashes when I tap the export button.</input>
<output>TECHNICAL</output>
</example>
</examples>

<input>
{{CUSTOMER_MESSAGE}}
</input>

Keep examples representative of the full distribution, not just easy cases. Include at least one near-boundary example.

Chain-of-thought

Ask the model to reason before answering. For Claude, the extended thinking feature handles this automatically; for other models, add an explicit reasoning step. See chain-of-thought.

You are a financial analyst. Answer the question after working through the evidence step by step.

<question>{{QUESTION}}</question>
<data>{{FINANCIAL_DATA}}</data>

First, identify the key metrics relevant to the question.
Then reason through what each metric implies.
Finally, state your conclusion.

<thinking>
[Reason here before writing the answer]
</thinking>

<answer>
[Final answer only]
</answer>

For latency-sensitive tasks, chain-of-thought increases token count. Profile before requiring it in production.

System and user role separation

Use the system prompt for persona and persistent rules; use the user turn for task content. This separation is critical for multi-turn reliability. See system-prompts.

SlotPut hereDo not put here
systemRole definition, behavioral rules, output format spec, tone, language.The user’s specific task.
userThe content to process for this specific request.Behavioral overrides (they should not be overridable).
assistant (prefill)Force a response prefix; constrains format strongly.Long text blocks.
messages = [
    {
        "role": "system",
        "content": (
            "You are a senior code reviewer. "
            "Review the submitted code for correctness, security, and style. "
            "Respond in JSON matching the schema provided by the user."
        )
    },
    {
        "role": "user",
        "content": f"<code>{user_code}</code>\n\nSchema: {json_schema}"
    }
]

JSON output schema

Request structured output by embedding a schema in the prompt and prefilling the assistant turn with {. See structured-output.

Extract the key entities from the support ticket below.
Return a JSON object matching this schema exactly. No markdown fences.

Schema:
{
  "category": "REFUND | SHIPPING | TECHNICAL | OTHER",
  "urgency": "low | medium | high",
  "product_id": "string or null",
  "summary": "one sentence"
}

Ticket:
<ticket>{{TICKET_TEXT}}</ticket>

Prefill the assistant turn for models that support it:

messages = [
    {"role": "user", "content": prompt},
    {"role": "assistant", "content": "{"}   # forces JSON object start
]

Validate the response with a schema validator (pydantic, zod, ajv) rather than trusting raw output. Retry on validation failure with an error message in the next user turn.

Role-framing patterns

Assign a role when it encodes implicit expert knowledge. See role-framing.

FramingWhen to use
"You are a senior {domain} engineer."Technical review, code generation, architecture decisions.
"You are a copy editor at a major publication."Writing, editing, headline scoring.
"You are a {domain} expert who always cites sources."Research tasks where hallucination risk is high.
"You are a helpful assistant."General tasks; add more specificity when quality matters.

Avoid roles that imply problematic behavior even when the task seems to require it. The role shapes the distribution of plausible responses; keep it domain-specific rather than character-specific.

Common gotchas

  • Prompt injection: user-controlled content in <input> tags can contain pseudo-instructions. Instruct the model to treat everything inside <input> as data only, not commands.
  • Overly long few-shot example sets push the task instructions out of the model’s attention window. Use 3 to 5 examples; prefer quality over quantity.
  • Prefilling with {" does not guarantee valid JSON. Always parse and validate the response. Structured-output APIs (with JSON mode or tool-use) are more reliable than prompt-only approaches.
  • Abstract negative instructions (“don’t be vague”) are less effective than positive examples showing the desired behavior. Show, rather than tell, what the output should look like.
  • System prompts are not truly secret in most APIs; adversarial users can often extract them via prompt injection or reflection. Do not store API keys or confidential logic there.
  • Chain-of-thought reasoning inside <thinking> tags can itself be manipulated. For high-stakes decisions, validate conclusions independently of the reasoning trace.