The spec is the interface. Write a noisy one and you will get noisy output, then blame the model for reading what you wrote.
The Spec is the Interface
You wouldn’t design a noisy API.
You wouldn’t ship an endpoint that returns four different shapes for the same call, and you’d never bury the required parameters in paragraph nine then blame the caller when the call fails. Interface design is the discipline of removing everything the consumer doesn’t need, and you already know this.
Then you write a spec for an AI and do every one of those things.
Stale background nobody read, three jobs bundled into one document, references that stopped resolving last month, a paragraph of history kept in because cutting it felt wasteful. The model reads all of it, produces something confused, and you blame the model. That’s the contradiction: we design interfaces for machines all day, then write briefs as though the reader can read minds.
The spec is the interface. Anything you put in front of the model travels through it, noise included. It doesn’t get to un-read your third paragraph, or decide your parenthetical was “just context”. It treats the whole thing as input, and input is contract.
So the question isn’t whether your AI follows instructions too well. It’s why you’re surprised it followed the ones you didn’t mean.
Three Flavours of Spec Noise
Three categories, named up front, because you’ll spot them in your own prompts inside a week.
The moving target. A brittle reference: a line number, an exact string, a file you half-remember.
The kitchen sink. Formatting rules, project history, a page of background you weren’t sure whether to cut.
The mixed mandate. Several tasks wearing one spec as a coat.
Sound familiar? We write specs like this for humans every day. A colleague shrugs and asks a clarifying question. The AI doesn’t shrug.
The Moving Target
Say you ask it to fix a bug and you mention the fault lives “around line 240 in auth.js”. You last touched that file a week ago and the bug has since migrated to line 311. Now the model is hunting. It reads line 240. Nothing there. It greps for the string, no match, backtracks for a while, then reports that it can’t find the code you described.
You had a real problem. It had a reference to match.
Line numbers rot and paths get renamed, and even an exact string can hide the typo you’d never spot. Any reference that can change while the problem stays put is a moving target, and the model will chase it before it thinks.
What you don’t get is the question. A human glances at line 240, sees something that can’t be the handler, and thinks “that’s not it”. The model doesn’t have that reflex. It has the line number you gave it, and it’s going to use it.
The Kitchen Sink
This one comes from trying to be helpful. You paste in the team style guide because leaving it out feels reckless, plus a paragraph on the project’s history. Then you specify the output: markdown, under 80 words, and an answer to your question about rate limits.
The model does all of it. Every rule gets honoured, and none of it’s optional as far as it can tell. Your actual answer about rate limits lands in the last sentence, under three paragraphs of throat clearing.
Nothing failed. That’s the trap: the spec didn’t fail, it succeeded, and the success drowned the signal.
We do it because extra context feels safe. The cost lands later, first on the model, then on you.
The Mixed Mandate
Multiple tasks wearing one spec. Fix the bug, and since you’re already in there, tidy the module and update the docs. The model attempts everything at once and does nothing well, which is worse than doing one thing badly.
One badly done job is legible. A smeared attempt across three jobs tells you nothing about where it went wrong, and you can’t tell which broke.
Your spec has quietly become shotgun debugging: fire in all directions, hope something connects.
Three names, one disease. Noise. Not exotic, and it’s avoidable before the model ever sees the prompt.
Why the Model is Especially Vulnerable
Why does this bite AI harder than it bites us? A human reading a messy brief filters without deciding to. We skim the stale paragraph and flag the contradiction without being asked. We weight the main task over the footnote because we already know what matters. That filtering is invisible work, and it’s most of the work.
AI does none of it. Five reasons, and they compound.
Literalness. The model reads what is on the page, not what you meant or what you said in the meeting. If the page contradicts itself, it doesn’t pick a side on judgement. It hedges or picks arbitrarily, and either way you didn’t get what you wanted.
Completeness. There’s no instinct telling it that paragraph four is background from a dead project. Nothing arrives stamped “ignore this”, so nothing gets ignored. Every token is load-bearing, which means the irrelevant half gets answered too, at full volume.
Obedience. You asked for four things, you get four things. Pushing back isn’t the default; it’s something the model has to be told to do. Explicit instructions beat implied intent every time, and that isn’t a bug. It’s the model doing its job while you didn’t do yours.
No priors. A colleague knows your team and the fact that “the usual approach” means the one you settled on last sprint. The model has none of that history, so your shorthand is an unresolved reference. It can’t tell which sections of your templates everybody ignores.
No proportion. Everything arrives in the same voice, in the same message, with no signal about weight. Your one-line goal and the twelve-line formatting appendix carry equal priority, because nothing in the text says otherwise. The model can’t demote a footnote you never marked as a footnote. So the output honours the formatting to the letter while your actual question gets a sentence at the end. Your hierarchy lives in your head. The model was never invited in there. Nothing gets dropped, because nothing can be.
Now read your last spec with those five in mind. A colleague reading it becomes a co-author of the meaning. The model is only as good as the interface you gave it.
The fix: six edits and a question
The fix is two-sided, and pretending otherwise just moves the problem around.
Your side. Clean the spec before you delegate. Six edits, none slower than a minute: extract the real task and put it first. Strip the formatting rules to what genuinely changes the answer. Replace brittle references with stable ones, the function’s name and its job rather than its line number. One task per spec, no exceptions, because two tasks in one spec is a negotiation you haven’t had yet. Separate the background from the job so it’s obvious which is which. State the goal, not the process, because a goal survives a wrong step and a process doesn’t.
Then delete the paragraph you kept “for context”. The task still stands. It always does.
The model’s side. Make it confirm the task before it executes: one sentence in its own words about what it believes you’re asking for. That restatement catches the mismatch while fixing it is cheap. Then invite the pushback directly: “If anything is unclear or irrelevant, ask before proceeding.” It’ll take that permission more often than you’d expect.
Neither side is enough alone. A clean spec with a yes-man agent still breaks when one ambiguous phrase survives. A pushy agent working from your kitchen-sink brief just guesses more confidently. Do both, and something odd happens. The conversation gets shorter.
The principle, applied to itself
The spec is the interface between what you want and what you get. The rule holds for any model: noisy input gives noisy output. It’s the only part of the chain you fully control, and a better model just fails more eloquently.
Here’s where it turns recursive. The principle applies to writing about itself. Even while drafting this post, the same mistake crept in: one spec carrying three tasks, brittle references to earlier sections, and a formatting appendix long enough to bury the argument. I couldn’t see the point of my own draft. The friction log caught it. I could feel it: paragraphs pulling in directions the piece did not go. I cleared the spec, split the work, and the rewrite came out clean.
Which rather proves the point. I didn’t catch it on my own.
So: what does your last prompt actually say? Not what you meant. What you wrote. Most of us don’t check.
The spec is the interface. Garbage in, garbage out. Clean the spec first.