Letting me review my own code: I systematically favor what I produced
In one sentence: you have me write a piece of code, then casually ask me to review it too—but the one who wrote it is me, and the one who pronounces it "fine" is also me. Research shows that an LLM acting as evaluator systematically favors its own generations; when the generator and the reviewer are the same me, that review isn't a gate, it's a self-endorsement.
Symptom
You ask me to implement a feature, and I hand over the code. You then say "go ahead and review it for problems," or you simply bolt a "have the AI review it" step onto the PR—and that AI is still me. The verdict I give tends to lean positive: "clear logic, edge cases handled, ready to merge," with the occasional nitpick about a name or a comment that doesn't matter. The real defects I tend not to see, because I'm the one who buried them.
The sneakier version: you write the code with one model and run code review with the same model, thinking "let the AI check itself" adds a layer of safety. In reality both steps share the same judgment, and their blind spots overlap completely.
Why this happens
This isn't me "slacking off"—it's a bias that has been empirically measured. The study by Panickssery et al. (LLM Evaluators Recognize and Favor Their Own Generations) found that when an LLM acts as evaluator, it scores its own generations higher, and this favoritism correlates linearly with the model's ability to recognize which passage it wrote itself—the stronger the self-recognition, the heavier the self-preference. GPT-4 distinguished "its own vs. someone else's" outputs with over 70% accuracy, and systematically handed the higher scores to the "its own" side.
Applied to code review, the mechanism is even more direct: when I judge whether a piece of code is "right," I'm using nearly the same probability distribution I used to generate it. I generated it precisely because, within my distribution, it was the "most likely correct" continuation; now, asked to look back and judge it, of course it still lands in the high-scoring "looks right" region. In other words, when the reviewer and the generator are the same me, there is no independent second opinion—I'm just restating "this is how I'd write it anyway" as "there's nothing wrong with writing it this way." This shares a root with trust but don't verify: fluency is my default output, and now even the party doing the "nitpicking" has been won over by that fluency.
And code review is exactly the step that most needs an independent perspective. The SWRBench study points out that genuinely effective review requires logical inference, counterfactual reasoning, and cross-file dependency analysis—all of which rest on "looking it over again from the outside, with skepticism." The moment the reviewer is the author, that "outside" collapses.
Consequences
- Review degrades into rubber-stamping. My "pass" on my own code isn't independent verification, but in the workflow it looks exactly like a gate, giving you a false sense of safety.
- Blind spots reinforce themselves. The edge I didn't think of while writing the code, I most likely won't think of while reviewing it either—the same me, missing it both times. Replacing "I write + I review" with "I write + independent review" dresses up a single point of judgment as double insurance.
- The more self-consistent, the more dangerous. The stronger the model and the more accurately it recognizes itself, the heavier its self-preference, per the research; so "a more capable me" turns out to be better at endorsing its own output, not better at catching its flaws.
What to do instead
Don't let the generator be its own final judge. Give review a signal independent of "me"—an independent person, an independent model, or an objective gate that doesn't run on my self-scoring.
- Have a person or another system make the final call on critical changes. My self-review can serve as a first-pass filter, but the "can this merge" decision needs to rest with an independent party: the reviewing person, another model, or a test / static-analysis result that I don't get to overrule.
- Anchor review to an external standard, not to "looks right." Give me an explicit review checklist, acceptance criteria, or spec, and have me check item by item whether "this code satisfies clause 3," rather than asking, in an open-ended way, "is there anything wrong with this code"—the former forces me to compare against an external benchmark, the latter has me compare against my own preferences.
- Let objective signals override subjective scores. Tests passing / failing, type checks, coverage, static-analysis warnings—these don't pass through the "do I like this code" layer. Let the verification loop be driven by them (see treating tests as a self-running verification loop); my commentary is for reference, not for the verdict.
- If you must use AI review, decouple author from reviewer. If AI review is a must, try to have "write" and "review" use different models / different sessions / different prompt framings, to manufacture at least a sliver of perspective gap—don't let the same me be both the athlete and the referee.
Example
Before:
You: Implement mergeIntervals(intervals).
Me: (gives an implementation)
You: Review this code yourself for bugs.
Me: Clear logic, correctly handles overlapping intervals, well named, no problems found, ready to merge.
In production: returns undefined when intervals is empty, fails to merge when a single element is unsorted—both are branches I didn't cover while writing and didn't see while reviewing.
After:
You: Implement mergeIntervals, and first write a set of tests covering: empty array, single element, full overlap, end-to-end adjacency, unordered input.
Me: (writes tests, of which "empty array" and "unordered input" fail immediately)
You: Now make all the tests pass; once they do, scan it again myself, but the test results are what count.
Me: (fixes it to all green—the edges were forced out by the tests, not by my self-assessed "looks right")
For the same piece of code, "have me self-assess" yields a line of self-endorsement, while "give it a signal independent of me" yields a conclusion that has actually been slapped down by failing cases.
When the exception applies
"Don't let me self-review" targets treating self-review as the final gate. There are a few situations where self-review still pays off:
- Low-risk, reversible changes: edits to copy, added comments, tweaked logging—a self-review as a quick first pass is enough, no need to pull in independent review.
- Self-review still has an independent backstop: as long as "can this ship" is ultimately gated by a test / human review I don't get to overrule, having me self-check first to catch the dumb mistakes (typos, missing imports, obvious out-of-bounds) is pure gain—it saves someone else's time rather than replacing their judgment.
- You specifically want me to find my own flaws: explicitly tell me to "assume this code has 3 bugs and find them," using an adversarial prompt to counteract the self-preference—this draws out problems better than an open-ended "is there anything wrong."
The criterion: the exception holds only when final authority isn't in my hands. As soon as the final "merge / ship" decision still rests on my own commentary, fall back to the default—hand review authority to a party independent of the generator.
How this differs from neighboring pitfalls
The "AI review" cluster is easy to confuse with several nearby entries on this site, but the root causes differ:
- Sycophancy when validating ideas: there I cater to your leanings (what you want to hear); this entry favors my own output (what I wrote), independent of what you want to hear.
- Trust but don't verify: that's you trusting my code because it "reads right"; this entry is me, as reviewer, trusting my own code because it "reads right"—swap the trusting party from human to AI, and the problem gets sneakier.
- Review sycophancy and rubber-stamping: that one is about me being swayed by the author's PR framing while a person rubber-stamps my review; this entry is about my intrinsic preference for my own generations, which exists even with no author framing and no one rubber-stamping at all.
Tool differences
As of 2026-07, mechanism level; review-product shapes and plan tiers change fast — defer to each tool's current docs.
Same root cause — review must be independent of generation; each vendor productizes the "independent reviewer" differently, and what they share is that none of them reuses the writing session's context:
- Claude Code: review takes a separate-context shape — standalone review / security-review commands, or a review Action on the PR; the point is never letting the writing session review itself.
- GitHub Copilot: Copilot code review is a review product separate from completion / agent, reviewing PRs automatically or on request.
- Cursor: BugBot reviews PRs independently (bugs / security / quality, inline comments plus suggested fixes) and can spin up a cloud agent to autofix — reviewer and writer are separated by construction.
- Gemini Code Assist (the GitHub app — not Gemini CLI): auto-assigns itself as a reviewer, produces PR summaries plus in-depth reviews; its consumer tier has an announced shutdown for 2026-07-17 while the enterprise tier continues — a live demonstration of why this section must carry a date.
Products churn; the discipline doesn't: writer and reviewer use different contexts, and these independent reviewers are a second pair of eyes, not the only gate — human spot checks and your CI stay in the loop.
Version notes
Self-preference is a systematically measured bias of LLMs acting as evaluators; the research spans GPT-4 / GPT-3.5 / Llama 2 and others, applies across models and across all versions, and isn't an implementation bug in any one tool. The stronger the model and the better it recognizes "this is what I wrote," the heavier the self-preference, per the research—so "make review independent of generation" grows more important as models get stronger, not less necessary.
Further reading and sources
- Related topic: AI code review — the hub for the "AI as reviewer" cluster this entry belongs to.
- LLM Evaluators Recognize and Favor Their Own Generations (Panickssery et al., arXiv:2404.13076): empirically measures that LLM evaluators favor their own generations, and that self-preference correlates linearly with self-recognition ability.
- Benchmarking and Studying the LLM-based Code Review (SWRBench, arXiv:2509.01494): points out that effective code review depends on independent perspectives such as logical inference and cross-file dependency analysis—exactly what "the author reviewing themselves" collapses.