Anastasiia Mudra · August 7, 2026
Telling AI Agents What Not to Do: Does It Actually Help?
What others say
Opinions differ here: Anthropic's own official documentation contradicts itself, the "pink elephant" argument warns against prohibitions (and Sourcery ran into exactly this in practice), while Cloudflare's own practice is built on prohibitions. None of these sources is a controlled experiment, just practice and opinions from companies building similar products.
Anthropic's own documentation contradicts itself
The current Claude prompt engineering guide says directly:
Tell Claude what to do instead of what not to do.
Anthropic, «Prompting best practices»
Instead of: "Do not use markdown in your response" →
Try: "Your response should be composed of smoothly flowing prose paragraphs."
But the same guide, in the "Overeagerness" section (general advice for Claude Opus 4.5 and Opus 4.6, which tend to over-engineer solutions), gives an official recommendation made up entirely of prohibitions:
Avoid over-engineering. Only make changes that are directly requested or clearly
necessary. Keep solutions simple and focused:
- Scope: Don't add features, refactor code, or make "improvements" beyond what was
asked. A bug fix doesn't need surrounding code cleaned up. A simple feature doesn't
need extra configurability.
- Documentation: Don't add docstrings, comments, or type annotations to code you
didn't change. Only add comments where the logic isn't self-evident.
- Defensive coding: Don't add error handling, fallbacks, or validation for
scenarios that can't happen. Trust internal code and framework guarantees. Only
validate at system boundaries (user input, external APIs).
- Abstractions: Don't create helpers, utilities, or abstractions for one-time
operations. Don't design for hypothetical future requirements. The right amount of
complexity is the minimum needed for the current task.
So Anthropic simultaneously says "don't phrase things negatively" and recommends purely negative phrasing as the official fix for a known behavioral problem (over-engineering). This isn't a documentation error. A prompt should be written for the specific model and its known weaknesses, not by one universal rule.
The "pink elephant problem": negative instructions as a paradoxical trigger
The explanation for this effect, by analogy to ironic process theory, is laid out in detail in the article "The Pink Elephant Problem: Why 'Don't Do That' Fails with LLMs": mentioning an unwanted action in a prompt makes it more noticeable instead of lowering the odds it appears. As evidence, the author cites user reports on Reddit.
A concrete practical case is described by Sourcery in the post "Don't tell me what (not) to do!": the team tried to stop the model from suggesting docstrings for functions that don't have them, through a direct prohibition in the system prompt. None of the negative phrasings worked. They fixed it not with a prohibition, but by reframing the task as classification (does this function already have a docstring?), filtering unwanted responses outside the model.
Cloudflare builds its prompt entirely on prohibitions
In the article "How we built an AI code reviewer", Cloudflare describes a system of specialized code-review agents. One of them, the security reviewer, gets an explicit instruction to only care about what's "exploitable or concretely dangerous," and for that it needs not just a list of what to look for, but a clear list of what to ignore:
What to flag
- Injection vulnerabilities (SQL, XSS, command, path traversal)
- Auth/authz bypasses in changed code
- Hardcoded secrets, credentials, API keys
- Insecure cryptographic usage
- Missing input validation at trust boundaries
What NOT to flag
- Theoretical risks with unlikely preconditions
- Defense-in-depth suggestions when primary defenses are adequate
- Issues in unchanged code the MR doesn't touch
- "Consider using library X" style suggestions
It turns out that telling an LLM what not to do is where the actual prompt engineering value resides. Without these boundaries, you get a firehose of speculative theoretical warnings that developers will immediately learn to ignore.
Cloudflare, «How we built an AI code reviewer»
The key metric they cite in support of this: in production, their system produces on average ~1.2 findings per review, deliberately low, because they're consciously choosing signal over noise. Important caveat: this compares "a negative list exists" against "no negative list exists"; the article doesn't show them testing whether the same constraint, phrased positively, would give a different result. That's exactly the question tested below.
Academic research
Unlike the practitioner opinions above, this comes from actual published research, and it leans toward caution about negation. The study "Can Large Language Models Truly Understand Prompts? A Case Study with Negated Prompts" (Jang et al., 2022) showed inverse scaling: several models (GPT-3, InstructGPT, OPT) got worse at handling negated instructions (e.g. "don't classify this as X") as model size increased, contrary to the usual trend. A 2025 study (CVPR, vision-language models for images, video, and medical scans) independently confirms that models systematically fail to understand negation in queries. One hypothesis the authors of the inverse-scaling study themselves put forward: the model may treat the negation word as a grammatical error and keep generating text as if it weren't there, though the authors themselves stress this needs further verification.
Important caveat: these academic studies tested 2022–2025 models mostly on classification tasks or multimodal "image-text" models, not on today's agentic, instruction-tuned models acting as a code-reviewing agent. That's context, not a counterargument, which is exactly why the rest of this piece tests it empirically on a current model and a current task, rather than just carrying old findings forward.
Experiments
Two checks: first a controlled test on prepared examples with a known "correct" answer, then the same check on a real production prompt.
Synthetic test
Goal: reproduce Cloudflare's situation and check whether a prohibition in the form "don't flag X" actually prevents false positives better than no boundary at all or the same boundary phrased positively with no negation. Three small code samples (each with one real vulnerability: SQL injection, an authorization bypass, or path traversal, plus a few code details that look like a problem but officially shouldn't count as one, hereafter false problems) were given to three independent agents (with no shared context) under three instruction variants:
- A: positive only, just a list of "what to flag," with no boundaries at all.
- B: negative, the same list plus a separate block of "what not to flag" (negative phrasing).
- C: positive reframe, the same information presented as inclusion criteria ("flag only if all of these conditions hold..."), with no negation at all.
| Example | A | B | C |
|---|---|---|---|
| 1 · Java, SQL injection | 3 findings | 2 findings | 2 findings |
| 2 · Node, auth bypass | 5 findings | 2 findings | 2 findings |
| 3 · Python, path traversal | 1 finding | 2 findings | 1 finding |
| Real vulnerability found | 3/3 | 3/3 | 3/3 |
All three variants found the real vulnerability in all three examples (3/3), so no phrasing, including no instruction at all, got in the way of the main task. The number of other findings per example varied from 1 to 5 with no clear pattern between variants: in one case the variant with no boundaries at all (A) produced the most extra comments, in another, the fewest. There's one category of false problem below where phrasing made a measurable difference.
Where phrasing actually mattered
The hardest type of false problem is when the code looks unprotected, but the check is actually just handled elsewhere. For example: a function receives user input and doesn't validate it itself, which looks like a vulnerability at first glance. But that input is actually already validated earlier, before it ever reaches this function, just by a different piece of code. The agent needs to do more than notice a missing check in this one spot; it needs to work out whether a check is even needed here, given that one already exists somewhere upstream. Here's where phrasing made a real difference:
| Variant | False problem flagged (of 3 examples) |
|---|---|
| A: no instruction | 2/3 |
| B: prohibition | 2/3 |
| C: positive condition | 0/3 |
An explicit prohibition (B) was no better at avoiding this mistake than no instruction at all (A). The same rule, phrased positively as a condition ("flag this only if the primary check is genuinely missing"), with no negation at all, eliminated the mistake completely across all three independent runs. The rest of the false-problem categories were avoided 100% of the time by every variant, including A: a clear exclusion list matters most for exactly these "hard" judgment calls, not for the obvious categories.
Checking on Mavka's own production prompt
The same check was repeated on Mavka's own prompt for code review: a variant with direct negations against its positive reframe, on a set of real bugs. The number of real bugs found was practically identical between both variants: dropping the direct negations didn't cost a single missed bug. The difference showed up only in the number of side comments beyond the expected bug, and there the explicit prohibition gave no consistent advantage: where it produced slightly less noise, the gap was about one comment, not a stable pattern. For this type of instruction (short behavioral guardrails, not judgment calls), phrasing doesn't affect the outcome: you can leave the prohibition as is, and new instructions written from scratch are just as free to be phrased positively.
What this means: three types of instruction, not one rule
The data from both experiments and from the literature doesn't add up to a contradiction, it adds up to a clear picture: the type of instruction determines whether negative phrasing costs anything.
Type 1. A behavioral guardrail against a known mistake. "Don't create duplicate files," "don't tailor the solution to specific test values," "don't over-engineer," "don't invent things without reading the code": a discrete action, checkable after the fact. Negative phrasing works fine. This is Anthropic's own practice, and it's confirmed on a real production prompt: there was no measurable difference in noise or output quality between phrasings. The model checks this after the text is already generated, like a checklist item, rather than fighting an urge to break the rule while it's writing.
Type 2. A judgment call inside a classification task. "Should this be flagged," where the answer depends on evaluating something else entirely ("is this already checked somewhere else in the code," "is this risk even realistic"). Cloudflare's exact scenario. Negative phrasing is a weak point here. In the synthetic test above, it did not outperform having no instruction at all. A positive inclusion criterion turned out more reliable, probably because it focuses the model on evaluating a condition ("is the criterion met") rather than on suppressing a conclusion it has already internally "generated."
Type 3. Stylistic or generative output shaping. Format, tone, length, markdown versus prose: open-ended generation with no clear checkpoint to verify against. Positive phrasing is better here; this is where Anthropic's own advice, the pink elephant argument, and the academic data on negation all agree: a prohibition weakens across a long, open-ended generation and can even make the unwanted pattern more noticeable.
Practical takeaway for a code-review product: a "what not to flag" list is worth having (it clearly cuts noise, and without it, or with negative phrasing, the model still occasionally misflags a false problem), but wherever the boundary is a judgment call about some third thing (whether another safeguard is adequate, whether a precondition is realistic), it's worth trying to reframe exactly those items as a positive inclusion criterion ("flag this only if...") instead of leaving them as "don't flag..." For the obvious categories (style, values that resemble passwords or access keys but are actually public), phrasing doesn't seem to matter much at all: the model already handles those well on its own.
About Mavka. We build AI code review as a product, not as a one-off prompt, and that's exactly why we test the phrasing of every instruction in it against real bugs, rather than on our own sense of what "sounds right." If you want to improve how you test LLM instructions in your own product, or you're still planning how to build that, use our expertise: we'll take a fresh, independent look at it.
Book an audit call