The tell
It works. That's the problem.
An over-instructed agent takes about ten seconds to spot. The system prompt reads like defensive code I'd have written on a day I didn't trust the runtime — every branch spelled out, every edge case pinned down in prose, nine numbered steps for something the model would have nailed in one. And here's what keeps the pattern alive: it works. The demo passes. The feature ships. Nobody looks again.
That "it works" is where the rot hides. Bad code works too. I can solve almost any problem with enough nested conditionals and copy-paste — the program runs, the tests go green, and I've quietly signed up for the next six months of maintenance. An over-stuffed prompt is that exact move in a different file. It passes today and breaks on the next model version, because I hardcoded behavior the model was about to handle on its own.
So I've started treating prompts the way I treat code I'll have to maintain, because that's what they are. A prompt is not an asset you pile up. It's a liability you carry.
Why we do it
Control feels like diligence.
Nobody over-instructs on purpose. It's a good instinct wearing the wrong outfit. You want the thing to behave in front of real users, so you reach for what makes code behave: nail down everything, leave nothing to chance. But an agent isn't a function I'm implementing. It's a capable teammate I'm briefing — and every step I narrate for it is a step I've taken away from it. The more I script, the worse it does the moment reality stops matching my script. In production, reality never matches the script.
There's a second reason, and it's the uncomfortable one: we get attached to our prompts the way we get attached to our PRs. That instruction block is something I wrote, defended in review, and now own — so it only grows. Every incident bolts on another line (never do X again). Every review adds a clause. Nobody ever deletes anything, because deleting feels like admitting the line was never load-bearing. That's not engineering. That's ego with a commit message.
Stop instructing the model. Hand it the suggestions and the gotchas, then be patient with the context. You're not writing a hack — you're writing a briefing.
A way to picture it
The brain doesn't move the fingers.
Picture yourself picking up a coffee cup. Your brain doesn't send a numbered list to each finger — flex this knuckle thirty degrees, two newtons of grip, rotate the wrist. It sets an intent ("grab the cup"), maybe one caution ("the handle's hot"), and trusts the hand to do the rest. Try to consciously drive every tendon and you'll be slower, clumsier, and you'll drop it.
That's an agent. The LLM is the brain — it thinks, it orchestrates, it decides what to do next. The tools are the hands — they're what actually reach out and act. When I over-instruct, I'm consciously controlling each finger: scripting the exact tool calls, in order, for a body that already knows how to move. It works in the demo the same way you can pick up a cup slowly while staring at your hand. It falls apart the second the cup is somewhere you didn't expect.
So I brief the brain and hand it good tools — then I let it reach.
Same hands. The second version lets the brain decide which one to use, and when.
Now look at that last line again — issue_refund isn't idempotent, never call it twice. I wrote that for years before I noticed what it actually is. That's not a gotcha. That's a bug I decided to solve with a sentence.
A perfectly obedient model still double-refunds when the request times out after the call already landed, when the webhook fires twice, when two agents pick up the same ticket. The instruction was never the control — it just felt like one. Which points at the move I now reach for first: the strongest prompt deletion is usually not a prompt edit at all. It's a tool edit. Give issue_refund an idempotency key and that line deletes itself permanently, for every model I will ever run.
That's the general test. If I have to write a constraint once, it might be a real landmine. If I have to write it five times, my tool is wrong. The prompt carries intent and traps. The tools carry the invariants.
How I build now
Five rules I actually follow.
None of this is about writing less to look clever. It's about spending my words where they compound instead of where they decay.
Suggest, don't dictate.
I give the model a rule of thumb, not a screenplay. "When something can't be undone, confirm before you do it" holds across a thousand situations I'll never enumerate. "If the message says cancel, open screen three" holds in exactly one. I write the heuristic and let the model apply judgment — because judgment is the whole reason I reached for a model instead of an if-statement.
Ship the gotchas, not the checklist.
The model finds the happy path without me. What it can't know is the landmine I stepped on last week — so that's what I write down: the payments API that says paid before the charge settles, the search index that lags writes by a couple of seconds, the "user" that's null for accounts created before 2021, the webhook that fires twice on retry. Everything else, I let it work out. A good prompt reads less like a manual and more like me leaning over to say — before you start, watch out for this.
Patience is the technique.
The lazy move is to keep tuning the sentence. The move that works is slower: give the model what it's actually missing. The domain rules. The real constraints. What "done" means here, specifically. The two things that always trip people up in this system. That's not a prompt trick — it's just doing the homework. And it's the part everyone skips, because homework doesn't feel clever.
Aim for the right altitude.
There's a height I'm aiming for. Too low — if-this-then-that, hardcoded — and it shatters on the first real user I didn't imagine. Too high — "be helpful, use good judgment" — and it just guesses. I aim for the altitude a sharp teammate would want on day one: the goal, the boundaries, the traps, and room to think. Nothing I'd have to rewrite the day the model gets better.
Treat the prompt like code you'll delete.
Every line I add is a line someone maintains, audits, and second-guesses the day the model shifts underneath it. So I hold each one to that bar: if a line only restates what the model already does well, it isn't a guardrail — it's debt. Most of my best prompt edits have been deletions.
In practice
The same move, twice more.
Different agents, same discipline: cut the steps the model can infer, keep the facts it can't — and push the hard requirements somewhere they can actually be enforced.
The requirement stays — it has to name the discount. What goes is the tone coaching. It already knows what good push copy sounds like; it can't know your truncation limit.
The steps it can infer. Dedupe didn't move into the prompt — it moved into a unique index, where it can't be forgotten. The date quirk is all that's left for me to say.
Related work
I'm not the only one saying this.
I didn't invent any of this — I just got tired of watching it get ignored. If you want the receipts behind the argument, here's the prior art worth reading. Same conclusion, arrived at from a dozen directions.
- Anthropic · Engineering Building effective agents "Find the simplest solution possible, and only increase complexity when needed." The whole argument, in one sentence, from the people shipping the models.
- Anthropic · Engineering Effective context engineering for AI agents Where "right altitude" comes from — and the case against hardcoding brittle logic into a prompt. Backs rule 04. Worth noting they're careful about this: minimal doesn't mean short, it means sufficient.
- Anthropic · Engineering How we built our multi-agent research system Where "instill good heuristics, not rigid rules" comes from — the design principle behind Claude Research. Backs rule 01.
- Rich Sutton · 2019 The Bitter Lesson Two pages, written before any of this. Researchers kept trying to hand-encode human knowledge, "but it always got in the way." Every prompt I've over-written is that mistake at a smaller scale.
- Liu et al. · TACL 2023 Lost in the Middle: How Language Models Use Long Contexts The mechanism, peer-reviewed: performance is highest at the start and end of the context and degrades in the middle. A wall of instructions buries your one real constraint in exactly the worst place.
- Imran Khan · arXiv 2025 You Don't Need Prompt Engineering Anymore: The Prompting Inversion Heavy procedural constraints beat plain chain-of-thought on GPT-4o and then lost to it on GPT-5 — the author calls it the guardrail-to-handcuff transition. One benchmark, one preprint, so hold it loosely; but it's the shape I keep seeing.
- Sean Goedecke Prompts are technical debt too Goes further than I do: prompts are a worse form of debt than code, because they decay silently and every model upgrade can break a working one. Theo covered it in More Prompts = Worse Code? if you'd rather watch than read.
- Eric Roby Loop Engineering: Stop Prompting Agents Where I found Swyx's "salty lesson" — the agent-era echo of Sutton's bitter one: don't fix things by hand; build the loop that scales.
The limit
Where I don't do any of this.
This argument has a boundary and it's worth saying out loud. It applies to open-ended work, where more than one path is a good one: drafting the copy, ingesting the weird file, judging whether a refund is reasonable.
It does not apply where the procedure is the product. If a step is regulatory, contractual, or safety-critical — a disclosure that must appear, an approval that must be recorded, an action that must never happen twice — I don't ask a model to use judgment where the system needs a guarantee. That goes into code: a validator, a policy engine, a state machine the model cannot route around.
"Brief the model" was never "let the model decide everything." It's a claim about where each kind of rule belongs. Soft judgment goes in the briefing. Hard constraints go in machinery. The failure I'm arguing against is the third option everybody actually picks — encoding a guarantee as a politely worded sentence and calling it a control.
The point
Brief it. Then trust it.
Next time you're about to add the tenth instruction, delete the first nine and watch what breaks. In my experience, less than you feared. Give the model the map and the landmines, then get out of its way. That's not laziness — it's the same taste that separates software I'm proud of from software that merely runs.