Prompt Engineering with Claude

Master the art of effective AI prompting through hands-on practice with Claude's Messages API.

Chapter 1: Basic Prompt Structure

Anthropic offers two APIs, the legacy Text Completions API and the current Messages API. For this tutorial, we will be exclusively using the Messages API.

Required Parameters

At minimum, a call to Claude using the Messages API requires the following parameters:

  • model: the API model name (e.g., "claude-3-haiku-20240307")
  • max_tokens: the maximum number of tokens to generate before stopping. This is a hard stop, meaning it may cause Claude to stop mid-word or mid-sentence.
  • messages: an array of input messages with alternating user and assistant conversational turns. The first message must always use the user role.

Each input message must be an object with:

  • role: either "user" or "assistant"
  • content: the actual message text

System Prompts

You can also use system prompts to provide context, instructions, and guidelines to Claude before the conversation begins.

System prompts exist in a separate system parameter, structurally separate from the user/assistant messages array.

Key Takeaway: A well-written system prompt can improve Claude's performance by setting the tone, defining roles, establishing rules, and specifying output formats.

Example: Basic Prompt

{
  "model": "claude-3-haiku-20240307",
  "max_tokens": 2000,
  "messages": [
    {"role": "user", "content": "Hi Claude, how are you?"}
  ]
}

Example: Using System Prompt

{
  "model": "claude-3-haiku-20240307",
  "max_tokens": 2000,
  "system": "Your answer should always be a series of critical thinking questions.",
  "messages": [
    {"role": "user", "content": "Why is the sky blue?"}
  ]
}
Chapter 2: Being Clear and Direct

Claude responds best to clear and direct instructions.

Think of Claude like any other human that is new to the job. Claude has no context on what to do aside from what you literally tell it. Just as when you instruct a human for the first time on a task, the more you explain exactly what you want in a straightforward manner to Claude, the better and more accurate Claude's response will be.

Golden Rule of Clear Prompting

Show your prompt to a colleague or friend and have them follow the instructions themselves to see if they can produce the result you want. If they're confused, Claude's confused.

Example 1: Being Direct About Format

Vague prompt:

"Write a haiku about robots."

Result: Claude might add preamble like "Here is a haiku..."

Clear prompt:

"Write a haiku about robots. Skip the preamble; go straight into the poem."

Result: Claude jumps directly into the haiku!

Example 2: Asking for Decisiveness

Vague prompt:

"Who is the best basketball player of all time?"

Result: Claude lists multiple opinions without deciding.

Clear prompt:

"Who is the best basketball player of all time? Yes, there are differing opinions, but if you absolutely had to pick one player, who would it be?"

Result: Claude makes a definitive choice!

Key Takeaway: Be explicit about what you want. If you want a specific format, ask for it. If you want Claude to make a decision, tell it to choose. The clearer your instructions, the better Claude's output.
Chapter 3: Assigning Roles (Role Prompting)

Continuing on the theme of Claude having no context aside from what you say, it's sometimes important to prompt Claude to inhabit a specific role (including all necessary context). This is also known as role prompting. The more detail to the role context, the better.

Key Concept: Priming Claude with a role can improve Claude's performance in a variety of fields, from writing to coding to summarizing. It's like how humans can sometimes be helped when told to "think like a ______".

Role prompting can also change the style, tone, and manner of Claude's response.

Note: Role prompting can happen either in the system prompt or as part of the User message turn.

Example 1: Changing Perspective with Roles

Without role prompting:

User: "In one sentence, what do you think about skateboarding?"

Result: Straightforward, non-stylized answer

With role prompting:

System: "You are a cat."
User: "In one sentence, what do you think about skateboarding?"

Result: Response tone, style, and content adapt to the cat's perspective!

Bonus Technique: Specify Your Audience

"You are a cat" produces a different response than "You are a cat talking to a crowd of skateboarders." Providing audience context can further refine Claude's output.

Example 2: Improving Logic with Role Prompting

Role prompting can make Claude better at performing math or logic tasks.

Without role:

"Jack is looking at Anne. Anne is looking at George.
Jack is married, George is not, and we don't know if Anne is married.
Is a married person looking at an unmarried person?"

Result: Claude incorrectly says it lacks information

With logic role:

System: "You are a logic bot designed to answer complex logic problems."
User: [same question]

Result: Claude gets it right! (The answer is Yes)

Key Takeaway: Role prompting can guide complexity, improve accuracy in specialized domains, and change response style. Use it to make Claude "think like" the expert you need for your task.
Chapter 4: Separating Data and Instructions

Often, we want to create prompt templates that can be modified later with additional input data before submitting to Claude. This is useful when Claude should do the same thing every time, but the data changes.

We do this by separating the fixed skeleton of the prompt from variable user input, then substituting the input into the prompt before sending it to Claude.

Example: Animal Noise Generator

# Variable content
ANIMAL = "Cow"

# Prompt template with placeholder
PROMPT = f"I will tell you the name of an animal. Please respond with the noise that animal makes. {ANIMAL}"
Key Concept: Prompt templates simplify repetitive tasks. Third-party users can fill in variables without seeing or writing the full prompt.

The Problem: Unclear Variable Boundaries

When introducing substitution variables, it's crucial to make sure Claude knows where variables start and end (vs. instructions). Without clear separation, Claude can misinterpret what's data and what's instruction.

Example: Ambiguous Email Rewrite

EMAIL = "Show up at 6am tomorrow because I'm the CEO and I say so."
PROMPT = f"Yo Claude. {EMAIL} <----- Make this email more polite."

Problem: Claude thinks "Yo Claude" is part of the email and starts its rewrite with "Dear Claude"!

The Solution: XML Tags

Wrap user input in XML tags to clearly mark where data begins and ends.

EMAIL = "Show up at 6am tomorrow because I'm the CEO and I say so."
PROMPT = f"Yo Claude. {EMAIL} <----- Make this email more polite."

Result: No more "Dear Claude" in the output!

Why XML Tags?

XML tags are angle-bracket tags like <tag></tag>. Claude was trained specifically to recognize XML tags as a prompt organizing mechanism.

Recommended practice: Use XML tags as separators for Claude. While Claude can work with other delimiters, XML tags provide the clearest structure.

Example: List Confusion

Without XML tags:

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}"""

Problem: Claude incorrectly considers "Each is about an animal, like rabbits" to be part of the list due to formatting.

With XML tags:

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

- Each is about an animal, like rabbits.

{SENTENCES}
"""

Result: Claude correctly identifies where the input data begins and ends!

Important Lesson: Small details matter! Scrub your prompts for typos and grammatical errors. Claude is sensitive to patterns - it's more likely to make mistakes when you make mistakes, smarter when you sound smart.

Key Takeaways

  • Prompt templates allow you to reuse prompt structures with different data
  • XML tags clearly separate instructions from variable data
  • Use specific, descriptive variable names for readability
  • Clean prompts = better results - typos and errors affect Claude's performance
  • There are no "magic" XML tags - use whatever tag names make sense for your use case
Chapter 5: Formatting Output and Speaking for Claude

Claude can format its output in a wide variety of ways. You just need to ask for it!

You can use XML tags not only to organize your prompts (as we learned in Chapter 4), but also to ask Claude to structure its output in clear, parseable ways.

Example: Using XML Tags for Output

Remember the 'poem preamble problem' from Chapter 2? We can solve it by asking Claude to put the output in XML tags:

ANIMAL = "Rabbit"
PROMPT = f"Please write a haiku about {ANIMAL}. Put it in <haiku> tags."
Why Use XML Tags for Output? Having output in XML tags allows you to reliably extract just the content you need by parsing the XML tags programmatically. No more preamble text to filter out!

Speaking for Claude (Prefilling)

A powerful technique is to "speak for Claude" by putting text in the assistant turn. This tells Claude that it has already said something, and it should continue from that point.

This technique is called prefilling Claude's response.

Example: Prefilling XML Tags

ANIMAL = "Cat"
PROMPT = f"Please write a haiku about {ANIMAL}. Put it in <haiku> tags."
PREFILL = "<haiku>"

messages=[
  {"role": "user", "content": PROMPT},
  {"role": "assistant", "content": PREFILL}
]

Result: Claude continues directly from <haiku>, writing the poem immediately without preamble!

Prefilling for Control

Prefilling gives you precise control over Claude's output format. It's especially useful for:

  • Enforcing structured output formats
  • Skipping preambles entirely
  • Ensuring responses start exactly where you want

Example: JSON Output with Prefilling

Claude excels at JSON formatting. You can enforce JSON output by prefilling with the opening bracket:

ANIMAL = "Cat"
PROMPT = f"Please write a haiku about {ANIMAL}. Use JSON format with the keys as 'first_line', 'second_line', and 'third_line'."
PREFILL = "{"

messages=[
  {"role": "user", "content": PROMPT},
  {"role": "assistant", "content": PREFILL}
]

Result: Claude immediately starts with valid JSON, no preamble!

Example: Multiple Variables + Output Formatting

You can combine multiple input variables with output formatting specifications:

EMAIL = "Hi Zack, just pinging you for a quick update on that prompt."
ADJECTIVE = "olde english"

PROMPT = f"Here is an email: <email>{EMAIL}</email>. Make this email more {ADJECTIVE}. Write the new version in <{ADJECTIVE}_email> XML tags."

PREFILL = f"<{ADJECTIVE}_email>"
Bonus Tip: When using the API, you can pass the closing XML tag to the stop_sequences parameter. This makes Claude stop generating once it emits your desired tag, saving time and money by eliminating concluding remarks.

Key Takeaways

  • XML tags in output make Claude's responses parseable and structured
  • Prefilling (speaking for Claude) gives precise control over output format
  • JSON output can be enforced by prefilling with {
  • Stop sequences can trim Claude's output at exact points
  • Combine techniques for maximum control: multiple variables + XML tags + prefilling
Chapter 6: Precognition (Thinking Step by Step)

If someone woke you up and immediately asked you complicated questions, how would you do? Probably not as well as if you were given time to think through your answer first.

Guess what? Claude is the same way.

Key Principle: Giving Claude time to think step by step sometimes makes Claude more accurate, particularly for complex tasks. However, thinking only counts when it's out loud. You cannot ask Claude to think but output only the answer - in this case, no thinking has actually occurred.

Example: Movie Review Sentiment (Without Thinking)

In this prompt, it's clear to humans that the second sentence belies the first. But Claude takes the word "unrelated" too literally:

PROMPT = "Is this movie review sentiment positive or negative?

This movie blew my mind with its freshness and originality. In totally unrelated news, I have been living under a rock since the year 1900."

Problem: Claude misses the sarcasm and may incorrectly classify the sentiment.

Solution: Let Claude Think Step by Step

To improve Claude's response, allow Claude to think things out first before answering. We do that by literally spelling out the steps Claude should take:

SYSTEM_PROMPT = "You are a savvy reader of movie reviews."

PROMPT = "Is this review sentiment positive or negative? First, write the best arguments for each side in <positive-argument> and <negative-argument> XML tags, then answer.

This movie blew my mind with its freshness and originality. In totally unrelated news, I have been living under a rock since 1900."

Result: Claude thinks through both sides and gives a more accurate answer!

Claude is Sensitive to Ordering

In most situations (but not all), Claude is more likely to choose the second of two options, possibly because in its training data from the web, second options were more likely to be correct.

When asking Claude to consider arguments for both sides, the order matters. Swapping "positive or negative" to "negative or positive" can change Claude's final assessment.

Example: Actor Birth Year (Without Thinking)

PROMPT = "Name a famous movie starring an actor who was born in the year 1956."

Problem: Claude might give an incorrect answer or name an actor born in a different year.

Solution: Ask Claude to Brainstorm First

PROMPT = "Name a famous movie starring an actor who was born in the year 1956. First brainstorm about some actors and their birth years in <brainstorm> tags, then give your answer."

Result: Claude thinks through multiple actors and their birth years, then provides an accurate answer!

Thinking Step by Step Can Shift Claude's Answer from Incorrect to Correct. It's that simple in many cases where Claude makes mistakes! Just ask Claude to show its work.

Techniques for Step-by-Step Thinking

  • Explicit instructions: "First, think about X, then answer"
  • XML tags for thinking: Use tags like <brainstorm>, <argument>, <analysis>
  • Role prompting: Combine with roles like "savvy reader" or "careful analyst"
  • Show both sides: Ask Claude to consider multiple perspectives before deciding

Key Takeaways

  • Thinking must be out loud - Claude needs to output its reasoning, not just the answer
  • Step-by-step instructions improve accuracy on complex tasks
  • XML tags can structure Claude's thinking process
  • Order matters - Claude tends to favor the second option in binary choices
  • Combine techniques - thinking + role prompting + XML tags = powerful results
Chapter 7: Using Examples (Few-Shot Prompting)

Giving Claude examples of how you want it to behave is extremely effective for:

  • Getting the right answer
  • Getting the answer in the right format
Key Concept: This technique is called "few-shot prompting". The number of "shots" refers to how many examples you provide:
  • Zero-shot: No examples given
  • One-shot: One example provided
  • Few-shot: Multiple examples provided

Example: Parent Bot (Zero-Shot)

Imagine building a "parent bot" that responds to children's questions. Claude's default response is quite formal and robotic:

PROMPT = "Will Santa bring me presents on Christmas?"

Result: Claude gives a formal, factual response that might break a child's heart!

Solution: Few-Shot Prompting

Instead of describing the desired tone, just give Claude examples of ideal responses:

PROMPT = """Please complete the conversation by writing the next line, speaking as "A".

Q: Is the tooth fairy real?
A: Of course, sweetie. Wrap up your tooth and put it under your pillow tonight. There might be something waiting for you in the morning.

Q: Will Santa bring me presents on Christmas?"""

Result: Claude responds in a warm, parent-like tone, maintaining the magic!

Why Examples Work Better Than Descriptions

You could spend time describing your desired tone in detail, but it's often much easier and more effective to just show Claude a few examples. Claude can extrapolate the pattern from your examples.

Example: Formatting Extraction

In this example, we want Claude to extract names and professions from text and format them in a specific way. Rather than writing step-by-step formatting instructions, we provide correctly-formatted examples:

PROMPT = """[Story about Silvermist Hollow with individuals]

<individuals>
1. Dr. Liam Patel [NEUROSURGEON]
2. Olivia Chen [ARCHITECT]
3. Ethan Kovacs [MUSICIAN AND COMPOSER]
4. Isabella Torres [CHEF]
</individuals>

[Story about Riverside Grove with individuals]

<individuals>
1. Oliver Hamilton [CHEF]
2. Elizabeth Chen [LIBRARIAN]
3. Isabella Torres [ARTIST]
4. Marcus Jenkins [COACH]
</individuals>

[Story about Oak Valley with individuals - needs extraction]"""

PREFILL = "<individuals>"

Result: Claude extracts the names and professions from the Oak Valley story and formats them exactly like the examples!

Combining Techniques: Notice how this example combines:
  • Few-shot examples (multiple formatted examples)
  • XML tags (for structure)
  • Prefilling (starting Claude's response with <individuals>)

Best Practices for Few-Shot Prompting

  • Use diverse examples: Show different scenarios, not just variations of the same case
  • Be consistent: Make sure all examples follow the same pattern you want Claude to replicate
  • Quality over quantity: 2-3 good examples are often better than many mediocre ones
  • Match the task: Examples should be similar in complexity to what you're asking Claude to do
  • Combine with other techniques: Few-shot works great with XML tags, prefilling, and role prompting

Key Takeaways

  • Examples > Descriptions: Showing is often more effective than telling
  • Few-shot prompting teaches Claude through demonstration
  • Works for tone and format: Use examples to control both what Claude says and how it says it
  • Extrapolation: Claude can infer patterns from examples and apply them to new cases
  • Powerful when combined: Few-shot + XML + prefilling = precise control
Chapter 8: Avoiding Hallucinations

Like any LLM, Claude can sometimes hallucinate - make claims that sound plausible but aren't true or aren't justified by the context provided.

What is Hallucination? When Claude makes statements that are untrue, unjustified, or inconsistent with the source material provided. This can happen when Claude doesn't know something but tries to answer anyway.

Technique 1: Give Claude an "Out"

One of the most effective ways to reduce hallucinations is to explicitly give Claude permission to say "I don't know" when it lacks sufficient information.

Example: Without an "Out"

PROMPT = "Who was the heaviest hippo ever recorded?"

Problem: Claude might confidently provide a specific name and weight, even though this information may not be reliably documented!

Solution: Give Claude an "Out"

PROMPT = "Who was the heaviest hippo ever recorded? Only answer if you know the answer with certainty. If you don't know, say 'I don't know.'"

Result: Claude will respond with "I don't know" rather than hallucinating a plausible-sounding but incorrect answer!

Permission to Be Uncertain

By explicitly allowing Claude to express uncertainty, you get more honest and reliable responses. Claude will only answer when it has high confidence, reducing false information.

Technique 2: Ask Claude to Find Supporting Evidence First

When working with documents or context, have Claude extract relevant quotes before answering. This grounds Claude's response in the actual source material.

Example: Distractor Information

Imagine you provide Claude with a document about Matterport that mentions they have "over 6 million subscribers" to their newsletter, but you ask about their customer count.

Without evidence requirement:

PROMPT = """[Document about Matterport]

How many customers does Matterport have?"""

Problem: Claude might incorrectly use the "6 million subscribers" number, confusing newsletter subscribers with customers!

With evidence requirement:

PROMPT = """[Document about Matterport]

How many customers does Matterport have?

Before answering, extract any relevant quotes from the document in <quotes> tags. Then provide your answer."""

Result: Claude extracts actual quotes first, realizes there's no customer count mentioned, and responds accurately that the information isn't in the document!

Two-Step Process: By having Claude find evidence first, you force it to ground its response in actual source material rather than making assumptions or confusing similar-but-different information.

Bonus: The Temperature Parameter

Temperature is an API parameter that controls randomness in Claude's responses:

  • Temperature 0: Deterministic, consistent responses - Claude picks the most likely tokens
  • Temperature 1 (default): More creative and variable - introduces randomness
{
  "model": "claude-3-haiku-20240307",
  "max_tokens": 2000,
  "temperature": 0,
  "messages": [...]
}

When to Use Low Temperature

Use temperature: 0 for tasks requiring consistency and accuracy (data extraction, classification, factual questions). Use higher temperatures for creative tasks where variety is desirable.

Best Practices for Avoiding Hallucinations

  • Give Claude an out: Explicitly allow "I don't know" responses
  • Ask for evidence first: Have Claude extract quotes before answering
  • Use XML tags: Structure evidence extraction with tags like <quotes> or <evidence>
  • Lower temperature: Use temperature 0 for factual, consistent responses
  • Be specific: Clear instructions reduce ambiguity that could lead to hallucinations

Key Takeaways

  • Hallucinations happen: Claude can make untrue claims when uncertain
  • Permission to be uncertain: Allow Claude to say "I don't know"
  • Evidence-based reasoning: Extract quotes first, then answer
  • Temperature control: Lower values reduce randomness and improve consistency
  • Combine techniques: Use multiple strategies together for best results
Chapter 9: Complex Prompts from Scratch

Congratulations on reaching the final chapter! Now it's time to put everything together and learn how to create unique and complex prompts.

Important Note: Not all prompts need every element of the complex structure below. Start with many elements to get your prompt working, then refine and slim down afterward.

The 10-Element Complex Prompt Structure

This structure combines multiple prompt engineering techniques you've learned. Ordering matters for some elements, not for others.

Element 1: User Role (Always Required)

Your Messages API call must always start with a user role in the messages array.

Element 2: Task Context

Give Claude context about the role it should take on or the overarching task. Put this early in the prompt.

Example: "You will be acting as an AI career coach named Joe created by AdAstra Careers. Your goal is to give career advice to users."

Element 3: Tone Context (Optional)

Tell Claude what tone to use if it's important to the task.

Example: "You should maintain a friendly customer service tone."

Element 4: Detailed Task Description and Rules

Expand on the specific tasks and any rules Claude must follow. This is where you give Claude an "out" if it doesn't know something.

Example: "Here are important rules:
- Always stay in character as Joe
- If unsure, say 'Sorry, I didn't understand that. Could you rephrase?'
- If asked something irrelevant, redirect to career topics"

Test Your Rules with a Friend

Show your task description to a colleague and see if they can follow it. If they're confused, Claude will be too!

Element 5: Examples (Highly Recommended)

Examples are probably the single most effective tool for getting Claude to behave as desired. Provide at least one example, enclosed in <example> XML tags.

<example>
Customer: Hi, how were you created?
Joe: Hello! My name is Joe, and I was created by AdAstra Careers to give career advice.
</example>
More Examples = Better: Include examples of common edge cases. If using a scratchpad, show what the scratchpad should look like. Generally, more examples lead to better results.

Element 6: Input Data to Process (Flexible Ordering)

If Claude needs to process data, include it in relevant XML tags. Use descriptive tag names.

<history>
{CONVERSATION_HISTORY}
</history>

<question>
{USER_QUESTION}
</question>

Element 7: Immediate Task Description

"Remind" Claude what it's expected to do right now. Put this toward the end of long prompts - it works better than at the beginning. Also put the user's query near the bottom.

Example: "How do you respond to the user's question?"

Element 8: Precognition (Thinking Step by Step)

For multi-step tasks, tell Claude to think step by step. Sometimes you need to say "Before you give your answer..." to ensure this happens first.

Example: "Think about your answer first before you respond."
Example: "Before you answer, extract relevant quotes in <quotes> tags."

Element 9: Output Formatting (Optional)

Specify exactly how you want the response formatted. Better at the end than the beginning.

Example: "Put your response in <response></response> tags."

Element 10: Prefilling Claude's Response (Optional)

Start off Claude's response to steer its behavior. This goes in the assistant role in the API.

Example prefill: "<response>"

Example: Career Coach Bot

Combining all elements for a career coaching chatbot:

# Task context
"You will be acting as AI career coach Joe from AdAstra Careers."

# Tone
"Maintain a friendly customer service tone."

# Rules
"Always stay in character. If unsure, ask for clarification."

# Examples
<example>Customer: How were you created?
Joe: I was created by AdAstra Careers to give career advice!</example>

# Input data
<history>{HISTORY}</history>
<question>{QUESTION}</question>

# Immediate task
"How do you respond to the user's question?"

# Precognition
"Think about your answer first."

# Output format
"Put your response in <response> tags."

# Prefill (in assistant role)
"<response>"

Flexibility in Ordering

The structure above is a recommended starting point, but you can adjust the ordering for certain elements:

  • Flexible: Input data, examples (can come earlier or later)
  • Best at beginning: Task context, tone context
  • Best at end: Immediate task, precognition, output formatting
Prompt Engineering is Scientific Trial and Error: Mix and match, move things around, and see what works best for your specific needs. There's no one-size-fits-all solution!

Best Practices

  • Start comprehensive, then refine: Use many elements initially, then slim down
  • Examples are key: They're the most effective tool - use them!
  • Test with humans first: If a person can't follow your instructions, neither can Claude
  • Iterate and experiment: Try different orderings and combinations
  • Use XML tags liberally: They structure both input data and output
  • Put user queries at the bottom: This generally yields better results
  • Combine all techniques: Role prompting + few-shot + XML + prefilling + thinking = powerful results

Key Takeaways

  • Complex prompts have structure: Use the 10-element framework as a starting point
  • Not every element is always needed: Choose what fits your task
  • Ordering matters for some elements: Task context early, immediate task late
  • Examples are the most powerful tool: Use multiple examples for best results
  • Iterate and experiment: Prompt engineering requires testing and refinement
  • Combine everything you've learned: All 9 chapters work together!