Prompt engineering that still works with modern models
Prompt engineering picked up a reputation for magic words and secret incantations. Most of that faded as models got better at understanding plain requests. What's left is less exciting and much more useful: a small set of habits that make results better, and that keep working across model versions.
This post collects them. None require special syntax. They come down to communicating clearly with a very capable reader who has none of your context.
Think of the model as a smart new colleague
A useful mental model: the model is a sharp, well-read colleague who just joined and knows nothing about your project, your users, or what "good" means for you. If you'd need to explain something to a human contractor, you need to explain it to the model.
That shifts what a good prompt contains. It's rarely a clever phrase. It's usually the missing background: who the audience is, what the output is for, what a great answer looks like, and what to avoid. When a result disappoints, the honest question is often "what would a new hire have needed to know that I didn't say?"
Say exactly what you want
Vague requests get generic answers. Compare:
- "Summarize this article."
- "Summarize this article in five bullet points for a busy engineering manager. Focus on decisions and risks, skip background, and end with one recommended action."
The second version names the format, audience, focus, and length. It's not longer for its own sake; every clause removes a guess.
Recent models tend to follow instructions more literally than older ones. If you want extra effort, say so ("go beyond the basics and include edge cases"). If you want restraint, say that ("only change what I asked; don't refactor"). Don't count on the model to infer that you wanted more or less than the words say.
Explain the why
A rule with a reason generalizes better than a bare rule. Compare "Never use ellipses" with "Never use ellipses, because this text will be read aloud by a speech engine that can't pronounce them." The second lets the model handle related cases you didn't list, like avoiding other symbols a speech engine would stumble on.
This applies to constraints in agent prompts too. "Don't run destructive commands" is weaker than "Don't run destructive commands, because this runs against a shared staging database that other teams use." The reason gives the model something to reason from.
Show examples
Examples are the strongest lever in prompting, and the most underused. A few good samples of input and desired output communicate format, tone, and level of detail faster than paragraphs of description.
Some guidance:
- Use two to five examples, and make them varied. If every example looks alike, the model will copy the pattern too closely.
- Include an awkward case. One example with a tricky input teaches more than three easy ones.
- Match the real distribution. Examples that look nothing like production data give misleading signals.
- Label them clearly, so the model knows they're demonstrations, not part of the task.
When output must follow an exact format, one worked example often does what a page of formatting rules can't.
Structure the input
Prompts that mix instructions, documents, and questions in one blob invite confusion. Separate them. XML-style tags are a favorite with Claude, and the idea works with any delimiter:
<instructions>
Answer using only the documents below. If the answer isn't there, say so.
</instructions>
<documents>
<document id="1">...</document>
<document id="2">...</document>
</documents>
<question>What is the refund window for annual plans?</question>
Three benefits follow. The model can tell instruction from data. You can refer to parts by name ("in the documents above"). And it's easier to treat hostile text inside a document as content instead of commands. That last point matters for agents that read untrusted input, though tags alone won't stop an attack.
For long documents, put the material first and the question last. Models generally do better when the question comes after the data it refers to.
Specify the output format
If something downstream will read the answer, say what shape it should take. Name the fields, the types, the allowed values, and what to do when data is missing. "Return JSON with keys title (string), priority (one of low, medium, high), and due (ISO date or null)" beats "return JSON."
For anything that a program parses, don't rely on prompt wording alone. Use structured output features or a forced tool call so the response is validated against a schema, as covered in getting reliable JSON out of an LLM.
Also say what not to include. If you don't want a preamble like "Sure, here's..." ask for the output only. It's a small line that saves you a parsing step.
Give it room to think
Some tasks get noticeably better when the model works through the problem before answering: math, multi-step logic, tricky code, weighing tradeoffs. You have two options.
Ask for reasoning in the prompt. "Think through the problem step by step in <thinking> tags, then give the final answer in <answer> tags." You can then parse out the answer and discard the reasoning.
Use a model's built-in reasoning mode, if it has one. Many current models can spend extra effort thinking before they reply, controlled by a setting instead of a prompt trick. If you turn that on, you often don't need to ask for step-by-step reasoning yourself, and heavy-handed instructions can even get in the way.
Reasoning costs tokens and time, so save it for tasks that need it. Classification and simple extraction rarely benefit.
Let it say "I don't know"
Models tend to answer even when they shouldn't. If accuracy matters, give an explicit exit: "If the documents don't contain the answer, reply 'Not found' instead of guessing." For factual work, ask it to quote the supporting text before answering, which makes unsupported claims easier to spot. This is one of the cheaper defenses covered in why LLMs hallucinate.
Roles: useful, but don't overdo it
Assigning a role ("You are a senior database engineer reviewing a schema") can set tone and focus, and a sentence or two in the system prompt is reasonable. The elaborate versions, with three paragraphs of backstory and claims that the model is the world's greatest expert, add little. A specific task description beats a grand persona.
Adjusting for the kind of task
The same principles land differently depending on what you're asking for.
Extraction. Define the fields and formats, say what to do with missing values, and include an example with an awkward input. Ask for exact quotes where you need traceability. Temperature and reasoning matter little here; schema validation matters a lot.
Classification. List the labels with a one-line definition of each and a hard case or two. Ask for the label and a brief justification, then use the justification to debug misclassifications. Tell it what to do when nothing fits, since "other" or "unsure" needs a defined meaning.
Writing and editing. Describe the audience and voice, and show a sample of the tone you want. For edits, say what to preserve as strongly as what to change: "keep my structure and claims, tighten the wording." Otherwise the model will helpfully rewrite everything.
Code. Give the language, versions, constraints, and the surrounding code it needs to fit into. Ask for tests or an explanation of edge cases. Point it at failing output rather than describing the failure from memory.
Analysis and advice. Ask for the reasoning, the assumptions, and what would change the conclusion. A model that lists its uncertainty is more useful than one that sounds sure.
Keeping long prompts healthy
Prompts grow. A line gets added after every bad output, and six months later nobody knows why half of them exist. Some hygiene helps.
- Keep prompts in files under version control, not pasted into a dashboard.
- Note the reason for each rule in a comment or commit message.
- Group related instructions under short headings, so the structure is visible.
- Remove contradictions when you add something new. Read the whole prompt again, not just your edit.
- Rerun your test set after each change, and after each model upgrade too. A new model may follow the same words differently, and rules that compensated for an old weakness can cause trouble on a new one.
A good rule of thumb is that if you can't explain what a sentence in your prompt is for, delete it and see whether the tests notice. More often than you'd expect, they won't, and you've just made the prompt shorter, cheaper to run, and easier for the next person to understand.
What to stop doing
Habits that made sense with earlier models and mostly don't help now:
- Shouting. ALL CAPS, repeated "IMPORTANT" and "CRITICAL" markers. On modern models these can cause over-application, where one emphasized rule swamps everything else. Calm, clear wording works better.
- Bribes and threats. Promising a tip or warning of consequences isn't a reliable lever.
- Stacking dozens of rules. A long list of overlapping "don'ts" often contradicts itself. Prune, and prefer positive instructions ("write in plain language") over long lists of prohibitions.
- Copying prompts from the internet unread. A prompt tuned for one model and task may misfire on yours.
- Over-relying on tricks when the real problem is missing context or a task too big for one step.
Test prompts like code
The single most valuable habit is treating a prompt as something you test.
- Collect real inputs, including messy and adversarial ones. Twenty is a decent start.
- Decide what good looks like before you look at outputs. Write it down.
- Change one thing at a time, and rerun the same set.
- Compare results side by side, not from memory.
- Keep the winner and the history in version control, with a note on why you changed it.
It's tempting to tweak a prompt after seeing one bad output. That fixes one case and often breaks two others. A fixed test set stops you from chasing your tail, and it grows into the evaluations described in how to evaluate an AI agent.
Prompts are one part of a bigger picture
For a single call, prompt quality dominates. For anything that runs across many steps, the prompt is just one piece of what the model sees, and context engineering is the wider discipline. Good prompting still matters there, but tool design, retrieval, and memory usually move results more.
A template to start from
When you're staring at a blank prompt, this skeleton covers most of what matters:
Context: who this is for and what it's used for.
Task: exactly what to do, in one or two sentences.
Inputs: <tagged data goes here>
Constraints: length, tone, things to avoid, and why.
Format: the exact shape of the output.
Examples: two or three varied samples.
If unsure: what to do instead of guessing.
Fill it in, run it on ten real inputs, and see what breaks. Then fix the prompt where the outputs show a real gap, not where you imagine one, and keep every version so you can go back to the one that worked last Tuesday. Do that a few times and you'll have something better than most of the clever prompts floating around online.