The Problem
If your prompts still produce inconsistent results after reading the articles and trying the techniques, the problem usually isn't a missing trick — it's a handful of specific mistakes hiding in prompts that otherwise look reasonable.
Prompting failures are patterned. The same mistakes appear across developers, projects, and models. Once you know what to look for, you can spot them in your own prompts and stop making them.
This is a catalog of the seven most damaging anti-patterns: how to recognize each one, why it fails, and how to fix it.
One caveat, and it matters: most of this list was written for a stateless chat window that only knew what you typed. In Claude Code or Codex CLI, the thing reading your prompt has a filesystem, a shell, and git — it can go find things out instead of guessing. That upgrade doesn't retire any of these seven, but it changes what the fix looks like for at least one of them. Where that happens, this catalog says so.
Anti-Pattern 1: The Pleaser
What it looks like:
This is the smallest anti-pattern on the list, and worth being honest about that: modern models and modern context windows don't choke on "please." What actually costs you isn't the courtesy — it's what the courtesy does to the sentence around it.
Why it fails:
- Signal dilution: the actual instruction gets pushed past the throat-clearing instead of leading the sentence
- It compounds: harmless alone; stacked with a wall of "helpful" narrative context (next entry), it's how a one-line request turns into a paragraph nobody reads closely — model or human
The fix:
Same instruction, no runway before it. Read your first sentence back — if it doesn't open with the verb, that's the tell, not the politeness itself.
When politeness IS appropriate: user-facing applications where the model's own words get read by a human, or when you're deliberately setting a conversational tone for the output.
Anti-Pattern 2: The Novelist
What it looks like:
Why it fails:
- Buried lede: the actual question is 150 words deep
- Irrelevant context: Flask, React, PostgreSQL don't matter for a memory issue
- Stale the moment you finish typing it: that project history is a snapshot of what you remember, not what's actually in the repo right now — and the thing reading it can go check the repo directly
The fix:
The deeper version of this fix, in Claude Code or Codex CLI: don't transcribe context you can just point at. "Here's what I remember the upload handler doing" is a lossy summary of a file the agent can open itself. Tell it where to look instead of what you think is there — "check the upload handler and the last few log lines from the crash" beats three paragraphs of your memory of the code. Paraphrasing decays. Pointing doesn't.
Anti-Pattern 3: The Micromanager
What it looks like:
Why it fails:
- Constrains better solutions: the model can't use regex, existing libraries, or a better algorithm — your steps are the ceiling, not the floor
- Encodes your assumptions: your step-by-step might have bugs or inefficiencies, and now they're load-bearing
- Defeats the point: if you're specifying every line, you did the design work yourself and hired a typist
The fix:
State the outcome and the constraints, not the route. That's the whole fix — but it leaves a real question unanswered: what if you actually want to review the steps before anything gets written, because the change is big enough that you don't trust a first pass? That's not a case for micromanaging. It's a case for asking the agent for the steps first: "before you write anything, lay out your plan — the files you'll touch and the order — and stop." Read what comes back, correct it, then let it run. (Claude Code calls this Plan Mode; every agentic tool has some version of it.) You get the safety of seeing the steps in advance without the cost of having written them yourself — because a plan you wrote is a cage the model can't improve on, and a plan it wrote for your approval is a checkpoint you can.
When dictating the actual steps IS appropriate: teaching scenarios, exact compatibility with existing code style, or a regulatory/compliance requirement that specifies the implementation, not just the outcome.
Anti-Pattern 4: The Optimist
What it looks like:
or
or
In Claude Code or Codex CLI, none of these fail for the reason they used to. The agent can grep the repo, run the app, and read the actual error — it doesn't need you to hand it the codebase. What it's still missing is the one thing you didn't say: what "fixed" looks like. Without a target to check its work against, it forms two guesses instead of one — a guess at what's wrong, and a guess at what counts as done — and hands you a plan built on both.
Why it fails:
- No target to verify against: "fix the bug" names a location, not an outcome. The agent can find a plausible bug and fix that, without ever confirming it's the one actually costing you
- The guess compounds: a diagnosis you never checked, feeding a fix you never specified, produces a change that looks done and might not be
- You inherit the review cost: the vaguer the target, the more of the resulting diff you have to read line by line just to find out what it decided "fixed" meant
The fix:
The target doesn't need to be a formal test — "show me that case passing afterward" is usually enough on its own to get the agent to write and run one. What matters is that there's now something to check the answer against besides your own read of the diff: a reproduction that used to fail and now doesn't, an error that's gone, a behavior you can point at. Name the location if you already know it, but always name the target — that's the part a vague request skips, and it's the part that turns a plan-and-a-guess into a fix you can actually verify.
Anti-Pattern 5: The Copy-Paster
What it looks like:
Why it fails:
- Generic instructions add nothing: "Be thorough and accurate" — were you planning to be sloppy?
- Wrong persona for task: "Helpful AI assistant" is generic; "Senior React developer" is specific
- Template cruft: instructions designed for general chat, not your specific task
- Second-hand advice, first-hand cost: a boilerplate prompt from a guide (or an influencer's screenshot) was tuned for someone else's codebase and someone else's model. Your own agent, sitting in your actual repo with your actual session history, usually already has a better read on how you like to work than a stranger's canned template does — and pasting theirs over it throws that context away.
The fix, for a one-off task:
Two more moves matter here, both about where the borrowed instructions come from. First: if the standard you're reviewing against actually exists somewhere real — a style guide, an ADR, last quarter's incident writeup — don't summarize it into your prompt from memory. Point the agent at the file and let it read the source directly: "review this component against `docs/perf-guidelines.md`." A live document beats your paraphrase of it, and it beats a stranger's paraphrase even more.
Second: if you catch yourself pasting the same instructions into a new session for the third time, that's not a prompt problem anymore, it's a packaging problem. Turn it into a skill — a saved procedure the agent can invoke by name — or a sub-agent scoped to exactly that job, instead of re-typing the brief every time and hoping you remembered all of it. The Copy-Paster is what happens when you reach for someone else's static template; a skill is what happens when you save your own, once, and never retype it again.
Anti-Pattern 6: The Threatener
What it looks like:
Why it fails:
- Doesn't improve accuracy: dread doesn't make a model better at parsing JSON — there's no "trying harder" mode underneath for the threat to switch on
- Causes over-caution: stakes-as-threat reliably buys hedging, disclaimers, and defensive checks on code that didn't need them — you asked for anxiety and got anxiety
- Wastes tokens: the whole paragraph of doom adds no instruction the model can actually act on
The fix, up front:
Where this pattern actually shows up most isn't the opening prompt, though — it's the correction. The first answer comes back wrong, and the instinct is to lean on it harder: "this is broken, be more careful this time." That's still the Threatener, just aimed at the reply instead of the request, and it fails for the same reason: there's no dial between careless and careful for it to turn. What works instead is telling it, plainly, which requirement it missed — borrow the format from a build log, not a scolding: FAIL: crashes on empty string, doesn't return None. PASS: type hints present, malformed input handled. You're allowed to be disappointed the first pass didn't work; say so if it's true. But say it as a verdict against a stated requirement, not a warning about what will happen if it fails again — the first gives it something to fix, the second just gives it a mood to perform.
The rule: stakes work as context, never as threat, and correction works as a verdict, never as a warning. "This handles financial data, so input validation is not optional" is a priority. FAIL: missing input validation is a verdict. "Don't screw this up" and "be more careful" are neither — they're noise with feelings attached.
Anti-Pattern 7: The Role-Player Gone Wrong
What it looks like — usually pasted into a CLAUDE.md or AGENTS.md, not typed fresh:
Why it fails:
- It's a confidence dial, not a skill dial: "never uncertain" doesn't make the model right more often — it makes it say it's right more often. Same error rate, with the warning label removed
- It runs on every task, forever: a bad persona in one message is one bad message. A bad persona in your CLAUDE.md governs every session in the repo until someone notices and deletes it
- It fights the one thing you actually want from it: when it hits an ambiguous requirement or a risky migration, you want it to say so. This instruction is asking it not to
The fix:
Facts about the repo and rules to follow, not a costume. A persona still earns its place when it supplies knowledge or names an audience — "review this the way a security engineer would," "explain it like the reader has never used a terminal" — or when it's a sub-agent's actual job description: a read-only explore agent, a security-reviewer scoped to a narrower toolset, where the role change comes with a real difference in what it's allowed to touch. That's the whole test in both cases: does this line change what the agent knows or can do, or just what it sounds like? Confidence isn't knowledge. If it's not adding either, cut it — same as everything else on this list.
Persona test: does this role carry real knowledge or a real toolset that improves the task? If it's just a tone, drop it.
Anti-Pattern Interactions
These anti-patterns often combine:
- The Pleasing Novelist: "I hope you don't mind me asking, but I've been working on this project and I really need some help..." [300 more words]
- The Micromanaging Threatener: "CRITICAL: Do exactly as I say or this will fail! Step 1: Create a variable called x..."
- The Optimistic Copy-Paster: [Generic template from tutorial] + "Fix the thing that's broken."
Recognizing combinations helps diagnose prompts that fail in multiple ways.
The skill that does this
There's a skill that runs this whole review for you — vc-prompt-auditor. Install it and it finds the prompts that actually failed you, proves which sentences did no work, and leaves the shorter version in prompt-audit.md. Do the loop by hand once first, though. It has two places a machine can flatter itself: deciding which prompt underperformed, and deciding that two answers are "the same." Once you have made those calls yourself, you will know which rows of the automated review deserve an argument.
Failure Recovery
When a prompt produces bad output, diagnose by anti-pattern:
| Symptom | Likely Anti-Pattern | Fix |
|---|---|---|
| Confident answer, wrong thing got fixed | Optimist | Name the target — what "fixed" looks like, not just where to look |
| Response is overly verbose | Novelist | Trim your prompt, specify format |
| Wrong approach to solution | Micromanager | Specify outcomes, not steps |
| Generic/unhelpful response | Copy-Paster | Drop the borrowed template — point it at the real source, or save your own as a skill |
| Defensive/hedging response | Threatener | Remove stakes language; if it's a correction, use a plain PASS/FAIL verdict instead |
| Weird persona leakage | Role-Player | Match persona to task |
| Long prompt, mediocre results | Pleaser + Novelist | Radical trim |
Quick Reference
Before Sending Checklist
- Can I remove politeness without losing meaning? (Pleaser)
- Is this prompt under 100 words for simple tasks? (Novelist)
- Am I specifying WHAT not HOW — or, if I want a plan first, is it the agent's plan I'm reviewing, not my own steps? (Micromanager)
- Did I name a target — what "fixed" looks like — not just where to look? (Optimist)
- Is this my own instruction, or a template someone else wrote — and if I'm repeating it, should it be a skill instead? (Copy-Paster)
- Am I applying pressure, or stating a verdict/requirement? (Threatener)
- Does this role carry real knowledge or a real toolset, not just a tone? (Role-Player)
How Much To Say
Skip the word-count math — there's no clean number that works for both a one-line ask and a multi-file investigation. Use the shape of the task instead:
| Situation | What to send |
|---|---|
| Simple, self-contained (explain, translate, one-line review) | One sentence, no setup |
| You already know the fix | Name the outcome and the constraint, skip the steps |
| You don't know the fix yet | Name the symptom AND the target — what "fixed" looks like — then let it investigate the rest |
Whatever the situation: if your prompt is longer than the answer you expect back, reconsider.
The Universal Fix
For any underperforming prompt:
- Identify the task verb (review, write, explain, fix)
- List essential context (code, error, constraints)
- Specify output format (if not obvious)
- Delete everything else
- Add back only what improves output
Most prompts improve by subtraction.
The Meta-Lesson, Updated
These anti-patterns were written for a stateless chat function that only knew what you typed. In Claude Code or Codex CLI, the model reading your prompt can read your repo, run your tests, and open a browser — and that upgrade doesn't retire the list. It just moves what "context" means.
- Politeness still costs tokens for nothing — that one didn't change.
- Narrative context still buries the ask — still true.
- Stakes-as-threat still buys hedging, not accuracy — unchanged; a correction lands better as a stated verdict than as pressure.
- But "the model only knows what you provide" stopped being universally true. An agent with tools goes and gets its own context. What it still can't get from the repo is what you consider done — that has to come from you, every time.
The model used to be a pure function of your words: whatever you left out, it never had. Now it's a function of your words plus whatever it goes and finds — which means the one thing you can never hand off is the target. Noise in the input still creates noise in the output; the new failure is a target-shaped hole where the goal should be.
Prompt engineering is noise reduction. Agentic prompting adds one requirement on top: always name what "done" looks like.