Forward-deployed / Learning zone
Prompt engineeringa standalone module
Lesson 04

Structured prompting: XML, delimiters, scaffolds

TL;DR

Once a prompt gets long enough to hold several ideas — the task, some context, an example or two, output format rules — the model needs help telling those ideas apart. The fix is structure: XML tags around each part (<document>, <example>, <instructions>), or clear text delimiters (###, ---, all-caps section labels), that let the model know where one thing ends and the next begins. Anthropic's own guides recommend XML tags specifically for Claude, and structured prompting is the default in every production prompt of any size. The upgrade is not visual polish. It is a real, measurable lift in consistency, because the model stops confusing the document for the instructions and the example input for the actual input.

🎯 For the AI PM (or coding-agent user)

Why it matters — Prompts that "worked in the playground" degrade in production the moment the document field grows or the instructions get more complex. Most of that degradation is unmarked boundaries.

What it changes in your decisions — Every prompt template that ships gets structure by default. Any prompt over a paragraph or with more than two inputs gets XML tags, not prose paragraphs.

Ask yourself — "If I made the document three times as long, would the model still know which paragraph is instructions?"

Risk if ignored — Model confuses instructions for content, follows a user-supplied "instruction" that was actually part of the document (prompt injection), or applies the wrong constraint to the wrong section.

The mental model

Unstructured vs. structured

Unambiguous boundaries — anything inside a tag is that thing, anything outside is not

That single distinction is why structured prompts survive at scale.

Unstructured
You are a summariser. Summarise the following... The article says X, Y, Z. Please use bullets.
Structured
<role>You are a summariser</role>
<task>Summarise the article</task>
<article>X, Y, Z...</article>
<format>bullets</format>
→ upgrade →

The unstructured version leans on paragraph breaks and vibes. The structured version gives the model unambiguous boundaries. Anything inside a tag is that thing. Anything outside is not. That single distinction is why structured prompts survive at scale.

Why XML specifically, and when text delimiters are enough

Anthropic's prompt engineering guides recommend XML tags for Claude for two reasons. Claude was trained on a lot of XML-marked-up text, so it treats tags as strong boundary signals. And XML tags nest cleanly — you can put an <example> inside a <few_shot> block, and the model tracks the hierarchy.

Other models handle other conventions well. OpenAI's guides often use ### section headers and Markdown. Both work. The rule that matters is consistency within one prompt: don't mix XML for some sections and Markdown for others. Pick one and use it for every boundary.

When text delimiters are enough:

When XML tags earn their weight:

Prompt scaffolds

A scaffold is a reusable prompt template with named slots. Instead of writing a new prompt each time, you fill in the slots. Scaffolds turn one good prompt into a platform.

A common scaffold for a document-Q&A tool:

<instructions>
You are a research assistant. Read the document inside <document> and answer the
question inside <question>. If the answer is not in the document, say "not in the
document." Do not use outside knowledge.
</instructions>

<document>
{{DOCUMENT}}
</document>

<question>
{{QUESTION}}
</question>

Now every question your product asks the model uses the same shape. Every A/B test of a new instruction changes exactly one section. Every future improvement — adding a <style> block, splitting <instructions> into <role> and <constraints> — is a targeted edit, not a rewrite.

The "prefill" trick

Anthropic's Claude API supports a small but powerful extension: you can prefill the first few tokens of the model's reply. If you prefill with {, the model will almost always continue as JSON. If you prefill with <answer>, it will fill the tag. This is the single most reliable way to force a specific output shape without a brittle regex parser downstream.

For chat interfaces without prefill, the same effect is approximated by ending your prompt with the opening of the format: "Reply with a JSON object starting with {." Less reliable than true prefill, but often enough.

Tradeoffs

Failure modes

Practitioner checklist