Prompts
    promptscodereviewsecuritycoding

    AI Code Review Mastery: Prompts and Strategies for Better Code Feedback

    Pasting a diff and asking 'review this' gets generic praise about error handling and edge cases. These prompts and strategies turn AI code review into a genuinely useful first pass.

    Editor: Paul RadfordJun 2, 20267 min read
    AI Code Review Mastery: Prompts and Strategies for Better Code Feedback

    Getting useful code feedback from an AI model comes down to three things: giving it enough surrounding context to judge intent, asking for specific categories of problems instead of "review this," and treating its output as a first pass that a human still has to triage. Skip any of those and you get generic praise or noise.

    Why does AI code review often feel useless?

    Most engineers try AI review once, paste in a diff, get back "this looks good but consider adding error handling," and never come back. The failure isn't the model, it's the prompt and the input. A raw diff without the surrounding file, the PR description, or the coding standards in play gives the model nothing to reason about beyond syntax. Models trained on public code default to the most statistically common advice: add comments, handle errors, consider edge cases. That advice is true of almost any function ever written, which is exactly why it feels worthless.

    The fix is narrowing scope. Instead of "review this PR," ask for one category of defect at a time: concurrency bugs, off-by-one errors in pagination, N+1 queries, or missing input validation on a specific endpoint. Narrow prompts produce specific findings because you've constrained the search space the model is implicitly doing.

    Building a prompt that actually finds bugs

    A review prompt needs four things: the code, the context (what the code is supposed to do), the constraints (performance, security posture, style guide), and the failure modes you care about. Here's a structure that works well with Claude, GPT-4 class models, or Gemini through their respective APIs:

    text
    1You are reviewing a pull request for a Python service that processes
    2payment webhooks from Stripe. Latency budget is 200ms p99. This code
    3runs at-least-once, so idempotency matters.
    4
    5Focus only on:
    61. Race conditions in the idempotency key check
    72. Places where a retry could cause a double charge
    83. Any place a Stripe webhook payload field is trusted without
    9 verification
    10
    11Do not comment on style, naming, or missing docstrings.
    12
    13<diff>
    14{paste diff here}
    15</diff>
    16
    17<surrounding_context>
    18{paste the full file or relevant functions, not just the diff}
    19</surrounding_context>

    Constraining what the model should ignore is as important as saying what to check. Without the "do not comment on" line, half the response budget goes to naming nits, and the actual race condition gets buried in the middle of a bulleted list where reviewers skim past it.

    For anything beyond a single file, pasting a diff without surrounding context is the single biggest cause of hallucinated or shallow feedback. The model can't tell if a variable used in the diff is validated three functions up, so it either assumes the worst or ignores it. If you're using Cursor or GitHub Copilot's chat, explicitly @-reference the files the diff touches rather than relying on the diff alone. Cursor's documentation on context and Copilot's chat context docs both cover how each tool decides what to index and when it falls back to a smaller window, and that fallback behavior is where quality quietly degrades on large repos.

    Which categories of bugs are AI models actually good at catching?

    In practice, across models, the reliability breaks down roughly like this:

    Strong: null/undefined handling, type mismatches, obvious SQL injection patterns, missing await/async bugs in JS/TS, incorrect exception handling, resource leaks (unclosed file handles, connections), inconsistent error codes across similar endpoints.

    Medium, needs a good prompt: race conditions, N+1 query detection, cache invalidation bugs, incorrect retry/backoff logic, authorization checks that are present but wrong (checking the wrong field or role).

    Weak, don't rely on it: business logic correctness against a spec the model hasn't seen, subtle timing bugs that depend on runtime behavior, anything requiring knowledge of your specific infrastructure quirks (that one Postgres connection pool that behaves oddly under load), and cross-service consistency issues where the bug lives in a different repo entirely.

    The weak category is where teams get burned. An AI reviewer approving a PR with confident language ("this correctly implements the retry logic described in the ticket") creates false confidence, because the model is pattern-matching on how correct code usually reads, not verifying against your actual ticket or your actual production behavior.

    Cost and latency: what this actually costs you

    If you're running review on every PR through an API rather than a flat-fee IDE subscription, cost adds up faster than people expect on large diffs. A 500-line diff with 2000 lines of surrounding context easily hits 6000 to 10000 input tokens once you include instructions and a system prompt. At Claude or GPT-4 class pricing, a single thorough review might run a few cents, which sounds trivial until you multiply by every PR, every push, and every re-review after changes. Teams running review-on-every-push at scale (hundreds of PRs a day) have hit monthly bills in the hundreds of dollars purely on review, separate from their coding assistant seats.

    Latency matters more than people plan for. A review that takes 20 to 40 seconds is fine as an async CI check but is disruptive if a developer is waiting on it inline before merging. Tools like GitHub's Copilot code review (in GitHub's docs) and CodeRabbit run as CI-triggered async jobs specifically because synchronous blocking review at PR-scale token counts is not a good user experience. If you're building your own review bot on top of an API, put it in the CI pipeline as a non-blocking check that posts comments, not a merge gate that developers sit and wait for, unless your diffs are consistently small.

    Prompting for severity, not just findings

    A raw list of ten issues with no ranking gets ignored, because reviewers can't tell if issue three is a security hole or a naming preference. Force the model to bucket its own output:

    text
    1For each issue found, classify as:
    2- BLOCKER: will cause incorrect behavior or a security issue in production
    3- SHOULD FIX: correctness risk but not urgent, or a maintainability concern
    4- NIT: style or preference, optional
    5
    6Output format:
    7[SEVERITY] file:line - one sentence description - suggested fix

    This does two things. It forces the model to actually commit to a judgment rather than hedging with "you might want to consider," and it gives your human reviewer a scannable list where they can ignore every NIT and focus on BLOCKER lines first. Teams that skip this step end up training their engineers to ignore AI review comments entirely, because wading through ten low-value nits to find the one real bug isn't worth the time after the third or fourth PR.

    When AI review is the wrong tool

    Don't use a general-purpose LLM review for anything that depends on runtime state you haven't given it: performance regressions that only show up under production load, memory issues that require a profiler, or correctness bugs in code that calls out to a service whose behavior the model has never seen (an internal gRPC service, a proprietary data format). In these cases the model will still produce confident-sounding output, and that confidence is the actual danger, not the absence of an answer.

    It's also the wrong tool for architecture-level review disguised as code review: "should this be a queue or a direct call" is a design conversation, not a diff-level check, and prompting a model with a 200-line diff to answer it will get you a plausible-sounding paragraph that ignores your actual constraints (team size, existing infra, on-call load). Save that for a design doc reviewed by a human who knows the system, and reserve AI prompts for the mechanical, pattern-based bugs it's actually reliable at catching.

    Static analysis tools (ESLint rules, Semgrep, existing SAST tooling) remain better than a prompt for anything that has a deterministic, rule-based answer: unused imports, banned function calls, license compliance. Don't ask an LLM to do what a five-minute Semgrep rule (see Semgrep's rule docs) does deterministically and for free at CI time. Reserve the LLM budget, in tokens and in review-fatigue, for the judgment calls a linter can't make.

    A workflow that holds up over time

    Run a cheap deterministic pass first (linter, type checker, Semgrep) so the AI reviewer never wastes tokens restating what a five-second static check already caught. Feed the AI reviewer full file context, not bare diffs, and give it a narrow, categorized prompt tied to the actual risk profile of that code (payment logic gets a different prompt than a CSS change). Force severity labels so humans can triage in seconds. Treat BLOCKER findings as a prompt to look closer yourself, not as ground truth to merge or reject automatically. And revisit your prompts every few months: model behavior shifts with version updates (GPT-4o behaves differently from GPT-4 turbo on the same prompt, and Claude's newer models tend to hedge less but also assume more), so a prompt tuned in early 2025 may need retuning against whatever model you're running by the time you read this.

    Advertisement

    728 × 90 — Leaderboard — Google AdSense

    Related Articles