The four-box prompt

The four-box prompt

Day 18: The Four-Box Prompt (Context / Task / Constraints / Done When)

When the AI gives you something almost right, rewording the prompt rarely fixes it. The problem usually isn't the wording. It's a decision you never made before you hit enter. A fixed four-part template shows you which decision is missing, and making that decision will do more for the output than any clever phrasing.

The third failed run

I see this every week, in my own work and on my team. Someone asks a coding agent to 'tidy up the payment retry logic.' Run one renames some variables and pulls out a helper. Not it. They reword: 'refactor the retry logic properly, keep it clean.' Run two adds exponential backoff that nobody asked for. They reword again: 'minimal, careful refactor of the retry logic, don't overdo it.' Run three is smaller. Still off.

Then they drop the request into a four-box template and get stuck on the last box, 'Done when'. They can't fill it, because they don't know what 'tidied' is supposed to look like. What they actually wanted was for the duplicate retry path to go away so a flaky test would stop failing. They never wrote that down anywhere, not even for themselves.

The model followed the prompt just fine. The prompt didn't say what they wanted.

The habit: reword, add adjectives, try again

When the output is off, almost everyone does the same thing. We reword. We add adjectives like 'clean', 'robust', 'concise', 'production-ready'. We try a cleverer framing ('act as a senior engineer…'). It feels like progress, because every run comes back a bit different.

But it's guessing. A reworded prompt changes several things at once: tone, emphasis, implied scope, implied format. If run three is better, you don't know which change helped. If it's worse, you don't know which one hurt. You come away with nothing you can reuse, so next week you go through the same loop on a different task.

  • Words like 'clean' or 'better' can't be checked. The model fills them in with its own defaults.
  • Each rewrite rerolls the whole prompt, so you never get to change one variable and compare.
  • Rerolling is cheap in tokens and expensive in attention. With agents that edit files, every bad run also leaves a diff you have to review and revert.

The template

Four boxes, in the same order every time. Copy this somewhere you can paste it from:

text
CONTEXT:
<What the AI needs to know that it can't see: who this is for, where it lives, what already exists, what went wrong before.>

TASK:
<One verb, one deliverable.>

CONSTRAINTS:
<What not to touch. Format. Length. Tools/libraries allowed or banned. Scope limits.>

DONE WHEN:
<How you will check the result without reading its mind. A test, a measurable property, an example, or a 'stop and ask me if…' rule.>
  • Context closes the gap between what's in your head and what's in the model's window. It can't see your Slack thread, your customer, or last week's incident.
  • Task cuts the work down to one action and one output, so the model doesn't drift into work that's merely 'nearby'.
  • Constraints fence off what has to stay the same, so the model's helpfulness doesn't break things you care about.
  • Done when gives you and the model the same finish line. 'Is this right?' becomes something you can check instead of something you go by feel.

Before and after: 'clean up this report'

PMs and analysts send this kind of request to a chatbot all the time. The usual version looks like this:

text
Clean up this report and make it more professional and punchy.
You're a world-class McKinsey editor. Go.

[pastes 1,400-word quarterly update]

You'll get something that sounds polished. It will probably be shorter. It may drop numbers you needed, it may move sections your director expects in a fixed order, and it will use the word 'leverage'. Here's the same request in four boxes:

text
CONTEXT:
Quarterly product update for our director and two VPs. They read it on
mobile between meetings. Last quarter's feedback: 'too long, couldn't find
the risks.' Section order is fixed by the template: Summary, Metrics,
Risks, Next Quarter.

TASK:
Rewrite the report below into a shorter version.

CONSTRAINTS:
- Keep all four sections in the same order.
- Do not change, round, or drop any number.
- No new claims that aren't in the original.
- Plain language; no buzzwords.

DONE WHEN:
- Under 400 words total.
- Risks section is the first thing in the doc after Summary...
  actually: Risks appear as 3 bullets max, each with an owner name.
- If any risk in the original has no owner, list it under
  'Owner needed' instead of guessing.

[report]

Writing the 'after' forced decisions that the 'before' never touched:

  • What 'clean up' actually means here: shorter (under 400 words), with the risks easy to find. 'Professional and punchy' pointed at neither of those.
  • What must stay the same: the numbers and the section order. In the 'before' these were unstated assumptions, and unstated assumptions are exactly what the model overrides.

Look at the half-finished line in Done when, where the writer changed their mind partway through. That's the template working. Better to find your own confusion while you're typing than after the third run.

The key idea: it's a checklist for you, not a trick for the model

Models do respond well to structure. Labelled sections are easier to follow, and Anthropic, OpenAI, and Google all say something like 'be explicit, separate instructions from context' in their prompting guides. That's the smaller benefit, though. The bigger one is that each box asks you a question, and an empty box predicts a specific problem with the result you're about to get:

  • Empty Context → generic answer. The model fills the gap with the most average version of your situation, so you get advice for 'a team' instead of yours.
  • Fuzzy Task → it does something nearby. 'Look at' or 'improve' lets the model choose the verb, so you might get a review when you wanted a fix, or a rewrite when you wanted a summary.
  • No Constraints → it 'helpfully' changes things you wanted left alone: renamed variables, reformatted files, dropped caveats, a new dependency. With coding agents this is the costliest failure, because the unwanted changes are spread across the whole diff.
  • No Done when → nobody can tell whether it worked, you or the model. Agents need this box more than chatbots do. Without a stopping condition, an agent either quits too early or keeps 'improving' things.

So when you can't fill a box, pay attention. It means you haven't made that decision yet, and rewording won't make it for you.

A closer look at Done when, the box people skip

People skip Done when because it feels like extra work, or because they honestly don't know the answer yet. Here are three ways to write one even when you're unsure:

  • A check you could run. 'All tests in payments/ pass.' 'Under 200 words.' 'Returns valid JSON matching this schema.' 'No files outside src/retry/ are modified.' If a script or a quick look can confirm it, it works as a Done when.
  • An example of the right output. Paste one row, one paragraph, or one function signature that looks the way you want. A concrete example answers questions you didn't know you had, like tone, length, and format.
  • 'Stop and ask me if X.' 'If the fix needs a schema change, stop and ask before editing.' 'If two sources disagree, list both and ask which to trust.' This marks the points where your judgement is needed, and for agents running multi-step work it's the most useful kind of Done when.

If none of the three works (you can't name a check, can't show an example, and can't say when it should stop), you're not ready to prompt yet. You need to think first. Sometimes that means sending a different prompt: 'Help me figure out what a good version of this would look like. Ask me questions, don't produce the thing yet.'

text
# Done-when examples by task type

Code fix:      Failing test test_retry_once passes; no other test changes status;
               diff touches only retry.py.
Summary:       5 bullets max; every bullet traceable to a line in the source;
               flag anything you're unsure about with [?].
Data query:    Returns one row per customer; row count matches
               SELECT COUNT(DISTINCT customer_id) FROM orders.
Research:      3 options with one trade-off each. If fewer than 3 credible
               options exist, say so instead of padding.

Why boring wins over time

A clever prompt is a one-off. When it fails, your only move is to rewrite the whole thing. With a fixed shape, a bad result points to a single box:

  • Generic output → fix Context.
  • It solved the wrong problem → fix Task.
  • It broke or changed something it shouldn't have → add a Constraint.
  • You can't tell whether it's right, or it stopped in the wrong place → fix Done when.

Now you're debugging instead of rerolling. You change one thing, run it again, and learn something. After a few weeks you'll also have your own library of Context blocks and Constraints to reuse, and that's where most of the time savings come from.

The shape is useful beyond your own prompts too. Later in the series we'll use it to hand a prompt to a teammate and to have one agent hand work to another. In both cases the risk is that meaning drifts at the handoff, and four explicit boxes, especially an explicit Done when, keep it in place. In my own multi-agent work, handoffs fail because of missing acceptance criteria far more often than because of badly worded instructions.

Today's practice

  • Find the last prompt that gave you a disappointing answer. It could be from a chatbot, your IDE agent, or anywhere else.
  • Rewrite it in the four boxes. Don't improve the wording. Just sort what you already said into Context, Task, Constraints, and Done when.
  • Note which box was hardest to fill and write it down. That box is the real problem, not the phrasing.
  • Fill that box properly, which means making the decision. Then rerun and compare the two outputs side by side.
  • Bonus: repeat this for three prompts this week and see whether the same box keeps being the hard one. In my experience it's usually Done when.

The reframe

A good prompt isn't clever writing. It's a decision you've already made, written down in the same shape every time.

Flashcards
Check yourself

Extend your knowledge

  • Read Anthropic's prompt engineering guide in the Claude docs, especially the sections on being clear and direct and on using examples. See how its advice lines up with the four boxes.
  • Read OpenAI's prompt engineering guide and Google's Gemini prompting strategies. All three separate context, instructions, and output format, and none of them can write your Done when for you.
  • Look at how teams write acceptance criteria for agile user stories, often in the Given / When / Then format borrowed from behaviour-driven development (BDD). It's the same idea as Done when, and it works for prompts as-is.
  • Save the four empty boxes as a reusable snippet (a text expander, an IDE snippet, or a section in CLAUDE.md / AGENTS.md) so starting from the template takes no effort.
Test yourself on this lessonquiz →
Discussion

Ask my AI about this article. The chat stays on your device; when you're done you can publish a short summary for other readers.

No questions yet. Try: what's the trade-off here, or how would this fail in practice?