Anatomy of a good prompt

Prompt Engineering

Chapter 2  ·  Anatomy of a Good Prompt — Clarity, Context, Constraints, Output Format

Most weak prompts aren't wrong — they're just incomplete. Claude will always produce something, but without enough signal it has to guess what you actually want. This chapter gives you a four-part framework that covers what every strong prompt should include, and shows you how to apply it across different kinds of tasks.

The Four Pillars

1
Clarity

What exactly do you want Claude to do? One concrete task, stated plainly. Avoid ambiguity about the verb: explain, write, fix, compare, summarise, list.

2
Context

What does Claude need to know to answer well? Your situation, the existing code, the audience, what you've already tried. Claude can't see your screen.

3
Constraints

What must the answer include, exclude, or stay within? Length, language level, tech stack, tone, libraries to avoid, things already ruled out.

4
Output Format

How should the answer be structured? A bulleted list, a code block, a table, a numbered step-by-step, plain prose. Specify it or Claude will guess.

You don't need all four in every prompt. A quick question might only need clarity. But when a response disappoints you, it's almost always because one of these four is missing.

A Fully Annotated Prompt

Here's a single prompt broken into its four components:

Prompt — annotated by component
Clarity
Write a bash function that watches a directory for new .log files
Context
and emails me when one appears. I'm running Debian 12 with sendmail installed and the directory is /var/app/logs.
Constraints
Use inotifywait, not polling. Keep it under 30 lines. No external dependencies beyond inotify-tools and sendmail.
Output Format
Give me the function in a single code block with a brief comment on each non-obvious line.

Notice that each pillar does something different. Clarity tells Claude what to build. Context tells Claude what world it's building for. Constraints tell Claude what to rule out. Format tells Claude how to present it. Together they leave very little to guesswork.

Pillar 1 — Clarity: State the Task Precisely

The verb you choose matters more than you might expect. Compare these openers:

  • Tell me about Docker → encyclopaedic overview, probably not what you need
  • Explain how Docker volumes differ from bind mounts → focused comparison
  • Fix the Docker volume error in this compose file → action-oriented, specific
  • List the five most common Docker volume mistakes, one sentence each → structured, bounded
Good clarity verbs
Explain (to teach), Write (to produce), Fix (to repair), Compare (to contrast two things), Summarise (to condense), List (to enumerate), Translate, Refactor, Review, Draft. Vague verbs like "help me with" or "tell me about" leave the task type undefined.

Pillar 2 — Context: Give Claude Your Situation

Claude has no visibility into your environment, your skill level, or what you've already tried. The more relevant context you provide, the less Claude has to assume — and assumptions are where responses go wrong.

Useful context to include

  • Environment — OS, language version, framework, relevant tools already installed
  • What you've tried — avoids Claude suggesting things you've already ruled out
  • Audience / skill level — "explain for someone who knows Python but not async" produces a very different response than an unqualified explanation request
  • The actual code or error — paste it; don't describe it from memory
  • Goal behind the task — knowing why you want something lets Claude suggest a better approach if yours is off
Missing context
My cron job isn't running. What's wrong?
Claude must guess the OS, cron implementation, whether it ever ran, what the job is, and what "isn't running" means. The response will be a generic checklist.
With context
My cron job on Ubuntu 22.04 (system crontab, not user) isn't running. The job is: 0 2 * * * /opt/backup.sh >> /var/log/backup.log 2>&1 The log file isn't being created at all. The script runs fine manually as root.
Now Claude can focus immediately — the log not appearing points to cron not triggering the job rather than the script failing. Diagnosis becomes precise.

Pillar 3 — Constraints: Define the Boundaries

Constraints stop Claude from giving you a technically correct answer that doesn't fit your actual situation. They're not about being restrictive — they're about removing the wrong solutions from the space of possible answers.

Constraint typeExampleWhy it helps
Technology scope Use only the standard library — no third-party packages Stops Claude reaching for requests when you're in a restricted environment
Length / depth In under 150 words Forces concision; stops a three-paragraph answer when you needed a sentence
Audience Assume the reader knows Python but not async Calibrates vocabulary and how much explaining to do
What to exclude Don't suggest Docker — we're not containerising this Saves a round-trip where Claude suggests something you'd immediately reject
Tone / register Formal English, no contractions — this is for a client report Critical for written communication tasks
What's already ruled out I've already checked permissions and the firewall isn't the issue Prevents Claude from rehashing what you've already tried

Pillar 4 — Output Format: Say How You Want It

Claude's default format is polite prose with occasional code blocks. That's fine for many requests, but for structured data, step-by-step guides, or anything you'll paste elsewhere, specifying the format pays off immediately.

Format requestWhen to use it
Give me a numbered step-by-step list Installation guides, procedures, anything sequential
Return valid JSON only — no explanation Feeding the output into another tool or script
A markdown table with columns: X, Y, Z Comparisons, option lists, structured data
One sentence per item, no sub-bullets When you need something scannable and brief
Explain first, then show the code Learning contexts; stops code-first responses you can't follow
Code block only — no prose around it When you're pasting straight into a file or terminal
Watch out
Asking for JSON with "no explanation" is one of the most common format requests — and one of the most commonly ignored if you don't put it at the end of the prompt. As noted in Chapter 1, the final instruction carries extra weight. Put format instructions last.

Putting It Together — Before and After

Weak prompt
Can you help me write a cover letter?
Missing: what job, what background, what tone, how long, where it will be used. Claude will ask clarifying questions or produce a generic template.
Strong prompt
Write a cover letter for a senior DevOps engineer role at a fintech startup. I have 8 years of Linux admin experience, strong Kubernetes and Terraform skills, and led a team of 4. The job ad emphasises reliability engineering and on-call culture. Tone: confident but not arrogant. Length: 3 short paragraphs, no filler phrases like "I am excited to apply".
All four pillars present. Claude has everything it needs to produce a draft that's on-target first time.

Quick Prompt Review Checklist

Before you send a prompt, run through this mentally:

  • Have I stated clearly what I want Claude to do (the verb / action)?
  • Have I given Claude enough context — environment, background, existing code?
  • Have I told Claude what to avoid or stay within (tech constraints, length, exclusions)?
  • Have I specified the output format if the default won't work?
  • Is there anything Claude would have to guess that I could easily tell it?
Remember
A prompt doesn't need to be long to be good. "Fix the null pointer on line 42 of auth.py — the user object can be None at login" is four pillars in one sentence. The goal is completeness, not verbosity.
Next — Chapter 3: Role Prompting and Personas
When and how to give Claude a role — "act as a senior security auditor", "you are a sceptical code reviewer" — and why this can dramatically shift the tone, depth, and angle of a response. Includes when it helps, when it's pointless, and when it backfires.