Context engineering decides what goes into the window. This is the adjacent problem: given the space, what do the instructions actually say, and how do you keep them working as the system grows.
It is unglamorous and it is not "prompt magic". The teams that do it well treat a prompt as a specification with tests, not a paragraph someone tweaks until a demo passes.
Structure the system prompt
A system prompt that grew by accretion — a rule bolted on for every bug ever reported — behaves unpredictably, because nothing in it is prioritised and much of it contradicts.
Give it a consistent skeleton:
| Layer | Contains | Note |
|---|---|---|
| Identity | What this assistant is and who it serves | Short; sets defaults for tone and scope |
| Capabilities | What it can do, what it must refuse | Refusals belong here, not scattered |
| Constraints | Hard rules that never bend | Keep this list genuinely short |
| Output contract | Shape, format, length | Enforce structurally where possible |
| Examples | A few, only where behaviour is hard to describe | See below — they are stronger than prose |
Then place things by scope. Behaviour that is always true belongs in the system prompt. Behaviour specific to one request belongs in that turn. Behaviour specific to one tool belongs in the tool's description, where the model reads it at the moment of choosing.
The most common structural error is putting per-tool guidance in the system prompt. It costs tokens on every request, and it is far from the decision it is meant to influence.
Why models drop instructions
Instruction-following degrades predictably, and knowing the causes is more useful than adding emphasis.
Volume. A prompt with forty rules will not have forty rules followed. Each addition dilutes the rest. This is the single strongest reason to keep the hard-constraint list short — a rule you are unwilling to delete is a rule you should be able to name.
Conflict. Two rules that disagree in some situation produce arbitrary resolution. "Always be concise" and "always explain your reasoning" will each win about half the time, and no amount of emphasis fixes the contradiction.
Negation. "Never mention pricing" requires the model to hold a prohibition while generating. Positive instructions — "direct pricing questions to the pricing page" — give it something to do instead of something to avoid, and are followed more reliably.
Position. Long prompts are attended to unevenly. A critical rule buried mid-prompt is weaker than the same rule near the start or end.
Examples are stronger than instructions
Few-shot examples are the most powerful and most misused tool here, because they override prose when the two disagree.
They earn their tokens when behaviour is easier to show than to describe: a specific tone, an unusual output shape, an edge case handled a particular way. Three good examples routinely beat three paragraphs.
They cost you when:
- They narrow behaviour. Examples that all follow one shape teach the model that shape is the requirement. Vary them deliberately, or it will generalise the accident rather than the intent.
- They contradict the instructions. The examples win. If your prompt says "be concise" and every example is four paragraphs, you have specified four paragraphs.
- They are stale. Examples embedding an old format keep producing the old format long after the instruction changed.
Order matters too: the last example is weighted most heavily, so put the most representative one there rather than the most interesting.
Steering the output
Three mechanisms, in increasing order of reliability.
Ask. "Respond in JSON." Works most of the time, fails exactly when input is unusual — which is when you least want it to.
Prefill. Begin the assistant's turn yourself, so it continues rather than starts. Cheap and effective for locking a format.
Constrain. Enforce a schema during decoding so invalid output cannot be generated. This is the only approach that is structurally reliable, and where a format genuinely matters it is the correct one.
Choose by consequence. Prose tone can be asked for. A payload another system will parse should be constrained.
Prompts are code
Diagram, as text
- Edit prompt in version control leads to Review by a second person
- Review by a second person leads to Evaluation set passes?
- Evaluation set passes? leads to Edit prompt in version control (no)
- Evaluation set passes? leads to Percentage rollout, version logged (yes)
- Percentage rollout, version logged leads to Metrics hold?
- Metrics hold? leads to Roll back (no)
- Metrics hold? leads to Full release (yes)
The moment a prompt is in production it has the properties of code — and it needs the practices.
Version it. Prompts live in the repository, are reviewed, and ship with a version identifier recorded in your traces. When behaviour changes on Tuesday you need to know which prompt produced Monday's output.
Test it. Every prompt change needs a regression run against a fixed task set, because prompt edits have non-local effects. Fixing one behaviour routinely breaks another, and you will not notice by trying two examples by hand.
Expect drift on model upgrades. A prompt tuned against one model version is tuned to that version's quirks. Upgrading is a change that requires re-evaluation, not a drop-in — this is the most commonly underestimated migration cost in AI systems.
Do not fix systemic problems with prompt text. If the model lacks information, retrieve it. If it needs an action, give it a tool. If output must be valid, constrain it. Prompt patches for structural problems accumulate into the unmaintainable prompt described at the top of this page.
Check your understanding
Common mistakes
Mega-prompts. Forty rules mean forty diluted rules. Short constraint lists are followed better.
Contradictions nobody noticed. Two plausible rules that conflict in some cases resolve arbitrarily.
Negative framing. Say what to do, not only what to avoid.
Examples that fight the instructions. The examples win. Update them together.
Emphasis instead of enforcement. Capitals are not a guardrail.
Per-tool guidance in the system prompt. It belongs in the tool description, next to the decision.
Shipping prompt changes without a regression run. Edits have non-local effects.
Treating a model upgrade as a drop-in. Prompts are tuned to a version; re-evaluate.
Practice
Rewrite this instruction so it is more likely to be followed: 'Please try to be concise and avoid making things up, and format nicely.' Explain each change.
Write your own answer first, on paper or in a note. Then compare.
Show a hint
Each clause is vague, unenforceable, or belongs somewhere other than the prompt.
Show a strong answer
A rewrite:
Answer in at most three sentences. Use only information from the CONTEXT section below. If the context does not contain the answer, reply exactly:
I don't have that information.Return your answer as JSON matching the schema provided.
What changed, and why:
- "Try to be concise" → "at most three sentences". "Concise" is a preference; three sentences is a constraint. Vague adjectives are interpreted differently on every call, which shows up as inconsistent output that looks like model instability.
- "Avoid making things up" → "use only information from the CONTEXT section". The original describes an outcome the model cannot check; the rewrite describes an action it can take. Naming the section makes it concrete rather than aspirational.
- Added an explicit refusal string. Without one, a model with nothing to say produces something anyway, because that is what generation does. Giving it a permitted way to fail is what makes abstention likely — and an exact string is machine-detectable, so you can measure how often it happens.
- "Format nicely" → a schema. This should not be in the prompt at all. Format is enforceable with structured output or validation, where it is guaranteed rather than requested. Anything a validator can check should be checked, not asked for.
- Dropped "please". Politeness costs tokens and adds nothing; the instruction should read as a specification.
The general principle: an instruction should be verifiable. If you cannot write a check that says whether the model complied, the model cannot reliably tell either — and you cannot measure whether a prompt change helped.
Design the workflow for changing a production prompt safely, for a team of six shipping several changes a week.
Write your own answer first, on paper or in a note. Then compare.
Show a hint
Treat it as a deploy, because that is what it is.
Show a strong answer
Treat the prompt as a deployable artefact with the same controls as code.
- Store prompts in version control, not in a database edited through an admin panel. The reason is not tidiness: you need the diff, the author, the review and the ability to say which version produced a given output six weeks ago.
- Attach a version identifier to every request and log it with the response. Without this, an investigation into a bad answer cannot establish what the model was actually told, which makes the whole system undebuggable.
- Require an evaluation run before merge. A fixed set of cases with expected properties — correct answer present, refusal when it should refuse, schema valid, no forbidden content. Fail the build on regression. This is the step that turns prompt editing from vibes into engineering.
- Review by a second person, because prompt changes are behaviour changes and the failure modes are not obvious from reading the diff.
- Roll out by percentage with the old version still available, and compare quality metrics between arms rather than assuming the new one is better. Prompt changes frequently improve the case that motivated them and regress two others.
- Keep rollback to one step, since a prompt regression can be worse than an outage — it is silent.
What I would add for a team shipping weekly: an evaluation set that grows from production failures. Every time a bad answer is reported, it becomes a case. Over a few months that set becomes the most valuable asset the team owns, and it is the only thing that stops the same regression recurring.
One thing to resist: letting non-engineers edit production prompts live through a console. The intent is good — faster iteration — and the effect is untracked behaviour changes with no evaluation and no rollback.
Key takeaways
- Give the system prompt a consistent skeleton — identity, capabilities, constraints, output contract, examples — and place rules by scope.
- Instruction-following degrades through volume, conflict, negation and position. Keep hard constraints few and phrase them positively.
- Examples override prose. They are the strongest lever and the easiest to get wrong; vary them, keep them current, and put the most representative one last.
- Steer output by asking, prefilling or constraining — pick by consequence, and constrain anything another system parses.
- Emphasis is not enforcement. Rules that truly matter belong in code, not prose.
- Treat prompts as versioned, tested code, with the version recorded in traces.
- Model upgrades break prompt tuning. Budget for re-evaluation.
- When a prompt misbehaves, try deleting before adding.
Further reading
- Jason Wei et al., "Chain-of-Thought Prompting Elicits Reasoning in Large Language Models" (NeurIPS 2022).
- Tom Brown et al., "Language Models are Few-Shot Learners" (NeurIPS 2020) — why examples outperform descriptions.
- Long Ouyang et al., "Training language models to follow instructions with human feedback" (NeurIPS 2022).
- Sander Schulhoff et al., "The Prompt Report: A Systematic Survey of Prompting Techniques" (arXiv, 2024).
- Martin Fowler, "Continuous Delivery" (2013) — the release discipline this lesson borrows wholesale.