Troubleshooting Claude Not Following Prompt Instructions: A Complete Guide

Wrap user data in XML tags, use system prompts, and set temperature to 0 to ensure Claude reliably follows prompt instructions.

When Claude appears to ignore your instructions, the root cause is usually ambiguous boundaries between your directions and the variable content. The anthropics/prompt-eng-interactive-tutorial repository provides a comprehensive framework for troubleshooting Claude not following prompt instructions through clear delimiters and structural patterns.

Why Claude Ignores Prompt Instructions

Claude processes everything in the context window as a continuous narrative unless given explicit structural cues. When user data bleeds into instructions without clear separation, Claude treats the entire block as a single input stream.

In Anthropic 1P/04_Separating_Data_and_Instructions.ipynb, the tutorial demonstrates this failure mode where Claude mixes static instructions with dynamic list items, causing it to return the wrong array index because it cannot distinguish between the instruction text and the data payload.

Three Proven Patterns to Fix Instruction Following

Wrap User Data in XML Tags

Claude is trained to recognize XML as structural delimiters. Wrapping variable content in custom tags like <sentences> or <user_input> creates an unambiguous boundary that Claude cannot misinterpret.

This pattern appears in Anthropic 1P/05_Formatting_Output_and_Speaking_for_Claude.ipynb, where the tutorial shows that XML-tagged data prevents Claude from treating user content as part of the system instructions.

Use a System Prompt

The system prompt establishes a high-level contract before Claude sees the user message. By defining the role and expected structure in the system parameter, you reduce ambiguity in the main prompt window.

Implementation details for this approach are documented in AmazonBedrock/boto3/10.2_Appendix_Tool Use.ipynb, which demonstrates how system prompts guide Claude's behavior before processing user inputs.

Prefill Claude's Response

Placing the opening tag or first words of the desired output in the assistant turn forces Claude to continue from that exact point. This technique eliminates stray preamble or conversational filler that Claude might otherwise add.

The prefill pattern is covered in the same tool-use appendix, showing how to structure the messages array to constrain Claude's opening tokens.

Implementation Examples from the Source Code

The get_completion Utility Function

Every notebook in the tutorial uses a standardized wrapper for the Anthropic API. This function enforces deterministic behavior through temperature=0.0 and accepts an optional system prompt:

def get_completion(prompt: str, system_prompt=""):
    message = client.messages.create(
        model=MODEL_NAME,
        max_tokens=2000,
        temperature=0.0,
        system=system_prompt,
        messages=[{"role": "user", "content": prompt}]
    )
    return message.content[0].text

Source: Anthropic 1P/04_Separating_Data_and_Instructions.ipynb

Incorrect Prompt Structure (Failure Mode)

This example demonstrates how Claude confuses instructions with data when boundaries are unclear:

SENTENCES = """- I like how cows sound
- This sentence is about spiders
- This sentence may appear to be about dogs but it's actually about pigs"""

PROMPT = f"""Below is a list of sentences. Tell me the second item on the list.

- Each is about an animal, like rabbits.
{SENTENCES}"""

Claude incorrectly includes "Each is about an animal..." as the first list item, returning the wrong sentence because it cannot distinguish the instruction from the data payload.

Corrected Prompt with XML Delimiters

Wrapping the variable in XML tags resolves the ambiguity:

PROMPT = f"""Below is a list of sentences. Tell me the second item on the list.

- Each is about an animal, like rabbits.
<sentences>
{SENTENCES}
</sentences>"""

Claude now reliably identifies the second sentence within the tagged block, treating the XML-wrapped content as distinct from the instructions.

Source: Anthropic 1P/05_Formatting_Output_and_Speaking_for_Claude.ipynb

Using stop_sequences for Precise Control

To prevent Claude from generating beyond a desired boundary, use stop_sequences that match your closing XML tags:

response = client.messages.create(
    model=MODEL_NAME,
    temperature=0.0,
    max_tokens=200,
    stop_sequences=["</answer>"],   # stop when closing tag appears

    messages=[
        {"role": "system", "content": "You are a helpful assistant."},
        {"role": "user", "content": PROMPT}
    ]
)
print(response.content[0].text)

This technique ensures Claude halts generation immediately after the specified sequence, preventing runaway outputs or unwanted post-script text.

Key Files in the Tutorial Repository

  • Anthropic 1P/04_Separating_Data_and_Instructions.ipynb – Demonstrates the failure mode where Claude mixes instruction and data, and introduces the XML-tag fix.
  • Anthropic 1P/05_Formatting_Output_and_Speaking_for_Claude.ipynb – Covers XML delimiters, prefill techniques, and stop_sequences for output control.
  • Anthropic 1P/hints.py – Provides concise hints for each exercise, including the "wrap variable in XML tags" recommendation.
  • AmazonBedrock/boto3/10.2_Appendix_Tool Use.ipynb – Explains system prompt design and tool-use patterns that reduce instruction-following errors.

Summary

  • Ambiguous boundaries between instructions and user data cause Claude to ignore or misinterpret prompts.
  • XML tags (<sentences>, <user_input>) create unambiguous delimiters that Claude recognizes as structural boundaries.
  • System prompts establish high-level behavioral contracts before Claude processes user content.
  • Prefilling the assistant's response forces Claude to continue from a specific starting point, eliminating unwanted preamble.
  • Temperature 0 and stop_sequences provide deterministic, precisely bounded outputs.

Frequently Asked Questions

Why does Claude mix my instructions with the user input?

Claude processes the entire context window as a continuous text stream. Without explicit delimiters like XML tags, it cannot distinguish where your static instructions end and the dynamic user data begins. As shown in Anthropic 1P/04_Separating_Data_and_Instructions.ipynb, this causes Claude to treat instructional text as part of the data payload, leading to incorrect responses.

How do XML tags improve prompt reliability?

XML tags act as structural delimiters that Claude's training recognizes as boundaries between instructions and content. Wrapping variable data in tags like <sentences> or <user_input> guarantees that Claude isolates the payload from the instructions. The tutorial demonstrates in Anthropic 1P/05_Formatting_Output_and_Speaking_for_Claude.ipynb that this pattern eliminates the ambiguity that causes instruction-following failures.

What is the purpose of prefilling Claude's response?

Prefilling places the opening text of the desired output in the assistant's message turn, forcing Claude to continue generation from that exact point. This technique prevents Claude from adding conversational preamble or explanatory text before the actual answer. According to the tool-use appendix in AmazonBedrock/boto3/10.2_Appendix_Tool Use.ipynb, prefill is particularly effective when combined with XML output tags to constrain the response format.

When should I use stop_sequences versus max_tokens?

Use stop_sequences when you need Claude to halt immediately after a specific text pattern, such as a closing XML tag like </answer>. Use max_tokens only as a safety cap to prevent runaway generation costs. The tutorial emphasizes in Anthropic 1P/05_Formatting_Output_and_Speaking_for_Claude.ipynb that stop_sequences provide precise structural control, while max_tokens merely limits length without regard to content boundaries.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →