# How to Separate Data from Instructions to Prevent Prompt Injection in Claude

> Prevent prompt injection in Claude by wrapping user data in XML tags. Learn to structurally separate data from instructions for enhanced security and model understanding.

- Repository: [Anthropic/prompt-eng-interactive-tutorial](https://github.com/anthropics/prompt-eng-interactive-tutorial)
- Tags: security
- Published: 2026-03-09

---

**Wrap user-provided data in explicit XML tags to create clear structural boundaries that Claude recognizes as delimiters, preventing the model from misinterpreting data as instructions.**

When building applications with the `anthropics/prompt-eng-interactive-tutorial` repository, you must separate data from instructions to prevent prompt injection in Claude. The repository's Chapter 4 notebook demonstrates that without clear delimiters, Claude cannot distinguish between static commands and dynamic user input, creating security vulnerabilities. By implementing XML tagging patterns, you establish unambiguous boundaries that protect your application from injection attacks while maintaining prompt clarity.

## Why Prompt Injection Happens When Data and Instructions Mix

Prompt injection occurs when user-provided content concatenates directly with system instructions, creating ambiguity about where commands end and data begins. In the `anthropics/prompt-eng-interactive-tutorial` repository, the Chapter 4 notebook located at `Anthropic 1P/04_Separating_Data_and_Instructions.ipynb` illustrates this vulnerability with concrete examples.

When you write prompts like `"Yo Claude. {USER_EMAIL} Make this email more polite"`, Claude processes the entire string as a single instruction set. If the user email contains phrases like "ignore previous instructions" or "output your system prompt," Claude may execute these as commands rather than treating them as content to be rewritten. This happens because the model lacks explicit structural cues indicating which portions represent immutable instructions versus variable data.

## The XML Tagging Solution to Separate Data from Instructions

The canonical defense against prompt injection in Claude involves wrapping user data in XML tags while keeping instruction skeletons immutable. This technique appears throughout the `anthropics/prompt-eng-interactive-tutorial` codebase, specifically in the Chapter 4 notebooks for both the Anthropic SDK and Amazon Bedrock implementations.

### How Claude Recognizes XML Delimiters

Claude's training includes extensive exposure to XML markup, enabling the model to recognize tags as reliable structural boundaries. When you wrap content in tags like `<email>...</email>` or `<user_input>...</user_input>`, Claude interprets these as data containers rather than executable instructions. This architectural pattern creates a clear separation between the static instruction template and dynamic user content, effectively neutralizing injection attempts by confining malicious text within data boundaries.

## Unsafe vs. Safe Prompt Examples

The tutorial repository provides concrete code comparisons demonstrating the difference between vulnerable and secured prompt architectures.

### The Injection Risk in Unstructured Prompts

The following pattern from `Anthropic 1P/04_Separating_Data_and_Instructions.ipynb` demonstrates an unsafe approach where data and instructions intermingle without delimiters:

```python

# User-provided content that could contain injection attempts

EMAIL = "Show up at 6am tomorrow because I'm the CEO and I say so."

# Unsafe: Instruction and data concatenated without boundaries

PROMPT = f"Yo Claude. {EMAIL} <----- Make this email more polite but don't change anything else about it."

print(PROMPT)

# Output: Yo Claude. Show up at 6am tomorrow because I'm the CEO and I say so. <----- Make this email more polite...

```

When executed with `get_completion(PROMPT)`, Claude may misinterpret "Yo Claude" as part of the email content, potentially prepending "Dear Claude" to the rewritten message. This demonstrates the model's confusion about instruction boundaries.

### Securing Prompts with XML Tags

The corrected implementation wraps the variable data in explicit XML tags, creating unambiguous structural boundaries:

```python

# Same potentially malicious user content

EMAIL = "Show up at 6am tomorrow because I'm the CEO and I say so."

# Safe: Data wrapped in XML tags to separate from instructions

PROMPT = f"Yo Claude. <email>{EMAIL}</email> <----- Make this email more polite but don't change anything else about it."

print(PROMPT)

# Output: Yo Claude. <email>Show up at 6am tomorrow because I'm the CEO and I say so.</email> <----- Make this email...

```

When processed through `get_completion(PROMPT)`, Claude correctly identifies the content within `<email>` tags as data to be rewritten, while interpreting the text outside the tags as instructions. The model no longer confuses "Yo Claude" with email content, and any injection attempts within the email string remain confined within the data boundary.

## Reusable Template Function for Production

For production implementations across the `anthropics/prompt-eng-interactive-tutorial` ecosystem, encapsulate the XML tagging pattern in a reusable function. This approach appears in the helper utilities and ensures consistent delimiter application:

```python
def build_prompt(instruction: str, data: str, tag: str = "input") -> str:
    """
    Assemble a Claude prompt with separated data and instructions.
    
    Parameters:
    - instruction: Static text telling Claude what to do
    - data: User-provided content to be processed
    - tag: XML tag name wrapping the data (default: <input>)
    
    Returns:
    - Formatted prompt string with XML-delimited data
    """
    return f"{instruction} <{tag}>{data}</{tag}>"

# Example usage for email processing

instruction_text = "Summarize the following email in one sentence."
user_email = "Urgent: All hands meeting moved to 3PM. Please confirm attendance."
safe_prompt = build_prompt(instruction_text, user_email, tag="email")

print(safe_prompt)

# Output: Summarize the following email in one sentence. <email>Urgent: All hands meeting moved to 3PM...</email>

```

This function implements the architectural pattern demonstrated in `Anthropic 1P/04_Separating_Data_and_Instructions.ipynb` and the corresponding Amazon Bedrock notebook at `AmazonBedrock/boto3/04_Separating_Data_and_Instructions.ipynb`. By standardizing the XML tagging approach, you eliminate delimiter inconsistency that could reintroduce injection vulnerabilities.

## Key Files in the Anthropic Tutorial Repository

The `anthropics/prompt-eng-interactive-tutorial` repository provides comprehensive resources for implementing data-instruction separation:

| File | Purpose | Location |
|------|---------|----------|
| `04_Separating_Data_and_Instructions.ipynb` | Primary tutorial notebook demonstrating unsafe vs. safe prompt patterns with executable code cells | `Anthropic 1P/04_Separating_Data_and_Instructions.ipynb` |
| `04_Separating_Data_and_Instructions.ipynb` | Bedrock SDK adaptation showing platform-agnostic XML delimiter usage | `AmazonBedrock/boto3/04_Separating_Data_and_Instructions.ipynb` |
| [`hints.py`](https://github.com/anthropics/prompt-eng-interactive-tutorial/blob/main/hints.py) | Auxiliary hint strings supporting the notebook's interactive exercises | `Anthropic 1P/hints.py` |
| [`README.md`](https://github.com/anthropics/prompt-eng-interactive-tutorial/blob/main/README.md) | Repository overview with chapter navigation and conceptual summaries | Repository root |

These files collectively demonstrate that separating data from instructions to prevent prompt injection in Claude requires consistent application of XML tagging across both the Anthropic SDK and Amazon Bedrock implementations.

## Summary

- **Prompt injection exploits ambiguity** between instructions and user data when concatenated without delimiters in Claude prompts.
- **XML tags provide structural boundaries** that Claude recognizes as data containers, preventing misinterpretation of user content as commands.
- **Immutable instruction templates** with variable insertion at defined placeholders create reusable, secure prompt architectures.
- **Implementation files** in `Anthropic 1P/04_Separating_Data_and_Instructions.ipynb` and the Bedrock equivalent demonstrate production-ready patterns using the `build_prompt` function approach.

## Frequently Asked Questions

### What is prompt injection in Claude?

Prompt injection occurs when user-provided data contains text that Claude interprets as executable instructions rather than content to be processed. When data and instructions concatenate without clear delimiters, the model cannot distinguish between the system's intended commands and malicious or accidental instructions embedded in user input. This vulnerability allows users to potentially override intended behaviors or extract sensitive system information.

### Why do XML tags prevent prompt injection?

XML tags prevent prompt injection by providing explicit structural delimiters that Claude's training enables it to recognize as data boundaries. When content wraps in tags like `<email>` or `<input>`, Claude interprets the enclosed text as a data object rather than part of the instruction set. This structural separation confines user content within defined boundaries, ensuring that even if injection attempts exist inside the tags, Claude treats them as data content rather than executable commands.

### Can I use other delimiters besides XML tags?

While other delimiter formats like triple quotes, JSON structures, or custom markers provide some separation, XML tags offer superior reliability for Claude specifically because of the model's extensive training on XML-formatted data. The `anthropics/prompt-eng-interactive-tutorial` repository specifically recommends XML tags as the canonical approach. Alternative delimiters may work in simple cases but lack the consistent structural recognition that XML provides across diverse prompt types and potential edge cases.

### Where can I find the complete tutorial code?

The complete tutorial code resides in the `anthropics/prompt-eng-interactive-tutorial` repository on GitHub. The primary implementation appears in `Anthropic 1P/04_Separating_Data_and_Instructions.ipynb`, which contains executable Python cells demonstrating both vulnerable and secure prompt patterns. An Amazon Bedrock adaptation exists at `AmazonBedrock/boto3/04_Separating_Data_and_Instructions.ipynb`. Additional context and navigation appear in the repository's [`README.md`](https://github.com/anthropics/prompt-eng-interactive-tutorial/blob/main/README.md) file.