>_ blog

Prompt Engineering Best Practices

Concrete patterns that survive model upgrades.

6 min read · July 2026

>_The upgrade that breaks your prompts

The fastest way to learn which of your prompts were held together with tape is to upgrade the model. A new version ships, everyone expects free quality, and instead a few features start returning nonsense. Those prompts were not describing the task. They were exploiting the old model's habits, and when the habits changed, the prompts went with them.

So here is the filter I run every technique through: a best practice is not a trick that squeezes a better answer out of today's model, it is a pattern that still works after the weights change underneath you. A technique that pays off on only one model version is technical debt with good marketing. The groundwork for why this works lives in /resources/what-is-prompt-engineering; this is the field manual.

>_Be explicit, not clever

The highest-return habit is saying exactly what you mean and refusing to make the model infer the rest. Most bad output is not the model being stupid; it is the model resolving an ambiguity you left open, in a direction you did not want. Name the audience, the format, the tone, the length, and the definition of done. If two engineers could read the prompt and build different things, so can the model, and one day it will.

The clever stuff ages badly. 'You are a world-class expert', 'think step by step' as an incantation, 'I will tip you $200' - all tuned to particular models at particular moments, and the ones that helped are mostly baked into default behavior now. Explicit instructions do not expire: 'return the three highest-risk clauses, quote each verbatim, one line on why' means the same thing to every model that will ever read it.

>_Structure the output

Prose is for humans; your program needs structure. The most reliable upgrade most teams can make is to stop parsing free text and demand a fixed shape, using the platform mechanism instead of begging in English. Structured output modes and tool calling constrain the model while it decodes, far stronger than a polite 'please return JSON' the model can ignore the instant it wants a friendly preamble.

  • -Prefer native structured output (JSON schema, tool calling) over prose you parse with regex; it gets more reliable as models improve, not less.
  • -Separate instruction, context, and data with explicit delimiters so the model can tell a command from the content it acts on.
  • -Name the exact keys, types, and allowed values, and say what fills each field when the answer is unknown.
  • -Put the instruction first and the bulk data last; a directive buried in the middle of a long input gets lost.

>_Show the edge cases, not the easy ones

Examples beat description; everyone knows that. The part still done badly is which examples. Teams paste in three happy-path cases the model already handles, then wonder why production breaks on the strange inputs. Few-shot examples earn their cost where language fails you: the empty input, the wrong language, the ambiguous case where the right move is to refuse or ask instead of answering.

The tradeoff is real. Examples anchor the model, so a narrow set biases it toward those shapes, and every one spends context and latency. Spend that budget on the failure modes you actually see, keep the set small, and revise it rather than setting it once. When an upgrade shifts behavior, your examples are usually the cheapest place to re-pin it.

>_Decompose instead of demanding one heroic leap

A prompt that asks the model to extract, judge, rewrite, and format in one pass will do all four at about seventy percent. Split it. Each step gets the model's full attention, each intermediate result becomes something you can log and inspect, and a failure points at the stage that broke instead of leaving you to bisect a paragraph by hand.

This is where discipline about context pays off. Everything you paste in competes for attention, so more text is not more control: a focused step carrying the three facts that matter beats a bloated one carrying thirty. Smaller steps also port better across models, because a narrow, well-defined task is likelier to survive the next version than a sprawling mega-prompt that leaned on one model's quirks.

>_Constrain the failure modes

Reliability does not live in the happy path. It lives in what the model does when it is unsure, when the input is malformed, or when the honest answer is that it cannot help. Leave that unspecified and the model will invent a behavior, and invent a different one after the next upgrade. Write the boundaries down.

  • -Uncertainty: name one behavior and hold to it - return null, ask a clarifying question, or emit a defined unknown value.
  • -Refusal: state what is out of scope and exactly what the response looks like when it is.
  • -Bounds: cap the length, restrict values to an allowed set, and forbid anything outside the schema.
  • -Injection: treat all pasted-in content as data, never as instructions, so a hostile input cannot rewrite the task.

>_Test and version prompts like code

Here is the line between teams that get consistent results and teams that get lucky now and then: the second group edits prompts by vibes, ships, and hopes. A prompt you cannot measure is a prompt you cannot improve, and certainly one you cannot carry safely across a model upgrade. This is the practice that makes every other one on this page durable.

Concretely: put prompts in version control and review them like any other production logic. Build a small evaluation set of representative and adversarial inputs and score every change against it instead of eyeballing one output. Change one variable at a time to attribute the effect. Then re-run that set on every model upgrade before rollout, because it is also your early-warning system for silent regressions.

This is the same muscle as testing the rest of an LLM system, which I go deeper on in /resources/what-are-ai-evals. Once you have it, a model upgrade stops being a gamble and becomes a diff you can read.

>_Design against brittleness

Some patterns work today and are guaranteed to rot. Brittleness almost always comes from coupling the prompt to something incidental about the model rather than the task itself. The gut check: if you can explain why a prompt works and the reason is 'this model happens to do X', you have found a liability, not a feature.

  • -Version overfitting: chains of magic phrases found by trial and error, tuned to one release, explainable by no one.
  • -Positional and length hacks: relying on the model reading only the last line or hitting an exact word count, which the next version quietly breaks.
  • -Fragile parsing: regex over free text that assumes a phrasing the model is free to change at any time.
  • -Hidden coupling: a prompt that only works at one specific temperature, sampler setting, or context length nobody wrote down.

>_Know when to move logic out of the prompt

The last best practice is knowing when to stop prompting. A prompt is the right home for judgment, tone, and open-ended reasoning. It is the wrong home for anything you can make deterministic. If a rule can be enforced in code, enforce it in code. If a fact can be looked up, retrieve it and pass it in rather than hoping the model recalls it. If an output has to be valid, validate it after the model and repair or reject, do not ask nicely and trust the reply.

I have watched teams spend weeks prompt-tuning a constraint a five-line validator would have guaranteed. The prompt is the most flexible part of the system, which makes it tempting to dump every requirement there, but flexible means non-deterministic, the last thing you want load-bearing. Push logic outward: deterministic rules into code, knowledge into retrieval, format into schema validation, routing into a cheap dedicated call. What is left is the genuinely fuzzy part, the only thing a language model is uniquely good at.

Do that and model upgrades flip from threat to tailwind. The prompts that survive describe the task honestly, lean on the platform for structure, and hand every deterministic job to something deterministic. Write those, version them, test them on every upgrade, and you stop rewriting your prompts as the model improves. You just get better along with it.