0Pricing
Claude Architect · Lesson

Prompt & Review Anti-Patterns

Single-pass multi-file review and same-session self-review.

Prompt & Review Anti-Patterns is a free Claude Architect lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Claude Architect learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Two Anti-Patterns, One Root Cause

This lesson dissects two review anti-patterns that quietly drain quality from agentic code review: single-pass multi-file review and same-session self-review.

Both share one root cause: asking a single context to do too much at once. When you cram many files into one pass, attention gets diluted. When the same session that wrote the code also reviews it, the author keeps its own reasoning and won't challenge itself.

On the Claude Certified Architect exam (Scenario 5, CI/CD), these are classic distractors. Recognizing them — and knowing the correct structure — is worth real points.

Why Single-Pass Multi-File Review Fails

Imagine handing the model 14 changed files and saying "review this PR." The model spreads finite attention across all of them simultaneously. Subtle per-file bugs get missed, and the cross-file story — how a renamed function ripples through its callers — is never examined deliberately.

Two mechanisms compound the failure:

  • Attention dilution: more files in one pass means shallower scrutiny per file.
  • Lost-in-the-middle: models attend most to the start and end of context, so files in the middle of a large dump get the least scrutiny.

The fix is not a bigger context window — it is better decomposition.

The Multi-Pass Review Structure

The correct pattern is multi-pass review: a focused per-file local pass on each file, THEN a separate cross-file integration pass that examines how the pieces fit together.

The local passes catch in-file defects with full attention. The integration pass catches the bugs that only exist between files: broken contracts, mismatched signatures, stale callers, inconsistent error handling.

This mirrors a broader exam principle: use fixed pipelines / prompt chaining for known sequential steps, and reserve adaptive decomposition for open-ended investigation. Review has a known shape, so a pipeline fits.

review_files = glob("src/**/*.py", changed_only=True)

# Pass 1: per-file local review (focused attention each)
local_findings = []
for path in review_files:
    local_findings += review_one_file(client, path)

# Pass 2: separate cross-file integration review
integration_findings = review_integration(client, review_files)

report = local_findings + integration_findings

Why Same-Session Self-Review Fails

The second anti-pattern: letting the same session that generated the code also review it. The exam is blunt here — independent / fresh-instance review beats same-session self-review.

The reason is cognitive lock-in. The author retains the reasoning, assumptions, and rationalizations it used while writing. It already "decided" the code is correct, so it tends to confirm rather than challenge. A clean reviewer carries none of that baggage and sees the code as an artifact to interrogate.

Put differently: the generation context biases the review. You want the reviewer biased toward skepticism, not toward the author's earlier conclusions.

Review in an Isolated Session

The remedy is to run review in an isolated session, decoupled from the generation context. In Claude Code CI/CD this is natural: generation and review are separate non-interactive invocations.

For pipelines, always run review with -p / --print (non-interactive) and emit --output-format json so results are machine-parseable. The review job gets only the diff and the criteria — not the chat history that produced the code.

# Generation step (one invocation)
claude -p "Implement the ticket in TICKET.md" \
  --output-format json > gen.json

# Review step — SEPARATE, isolated session (no generation history)
claude -p "Review the staged diff against our review criteria." \
  --output-format json > review.json

Forking Shares Context — Be Careful

Session controls matter. --resume <name> continues a named session; fork_session branches from a shared point. For review, beware: forking from the generation session carries the author's reasoning forward, recreating the same-session bias you were trying to escape.

Prefer a genuinely fresh session fed a structured summary of what to review. There is also a freshness angle: resumed tool results can be stale if the codebase changed since — sometimes a fresh session with a structured summary beats resuming.

Prompt the Reviewer With Explicit Criteria

An isolated reviewer is only as good as its instructions. Vague prompts ("be more precise," "find bugs") produce noisy, inconsistent output. Explicit criteria win: "flag a comment only when it contradicts the code" beats "check the comments."

For CI specifically, the goal is to minimize false positives — a review that cries wolf gets ignored. Tight, testable criteria keep signal high.

REVIEW_CRITERIA = """You are reviewing a code diff in an isolated session.
Flag an issue ONLY when one of these is true:
- a null/None path can be reached with attacker- or user-controlled input
- a function signature changed but a caller was not updated
- a comment directly contradicts the code it documents
Do NOT flag style, naming, or speculative refactors.
Return [] if nothing meets the bar."""

Few-Shot Examples Sharpen the Reviewer

Where ambiguity remains, add 2-4 targeted few-shot examples per ambiguity. The model generalizes from them — it does not merely repeat them. Few-shot is the best lever for consistency, edge cases, output format, and reducing hallucinated findings.

For a reviewer, show one example that should be flagged and one that should NOT. That calibrates the false-positive boundary far better than another paragraph of prose.

FEW_SHOT = """Example A (FLAG):
  diff: `def charge(amount):` -> `def charge(amount, currency):`
  caller still calls `charge(amount)`  => signature/caller mismatch.
Example B (DO NOT FLAG):
  rename of a local variable `tmp` -> `buffer` with all uses updated.
  No behavioral change => not an issue."""

Force Structured Output for Findings

To make review results reliable and parseable, force structured output with a tool plus a JSON Schema. Setting tool_choice to "any" guarantees the model calls some tool, eliminating free-text drift; a forced specific tool gives even tighter control.

Schema discipline matters: mark a field required ONLY if it is always present. Never require a possibly-absent field — the model will fabricate one to satisfy the schema. Use an enum with an "other" value plus a free-text detail field for extensibility.

tools = [{
  "name": "report_findings",
  "description": "Return code-review findings for the diff.",
  "input_schema": {
    "type": "object",
    "properties": {
      "findings": {"type": "array", "items": {
        "type": "object",
        "properties": {
          "file": {"type": "string"},
          "category": {"enum": ["bug", "contract", "other"]},
          "detail": {"type": "string"}
        },
        "required": ["file", "category"]
      }}
    },
    "required": ["findings"]
  }
}]

resp = client.messages.create(
    model="claude-sonnet-4-5", max_tokens=2048,
    tools=tools, tool_choice={"type": "any"},
    messages=[{"role": "user", "content": review_prompt}])

Re-Runs: Report Only New Issues

Review runs repeatedly as a PR evolves. When you re-run, include the prior results and report only new or still-unfixed issues. Re-flagging everything from scratch buries the genuinely new problems and trains reviewers to ignore the bot.

This also keeps the integration pass honest: a fix in one file may introduce a fresh cross-file break, and that is exactly what the next run should surface — not the noise that was already resolved.

prior = json.load(open("review.prev.json"))

prompt = f"""Re-review the current diff in an isolated session.
Prior findings (already reported): {json.dumps(prior)}
Report ONLY issues that are new or remain unfixed.
Do not repeat findings the author has resolved."""

Don't Reach for the Batch API Here

One last trap. Pre-merge / blocking review is time-sensitive, so it does NOT belong on the Message Batches API. Batches are 50% cheaper with up to a 24h window but carry no latency SLA and do not support multi-turn tool calling — wrong for anything blocking a merge.

Reserve the Batch API for non-blocking jobs: overnight audits, nightly full-repo sweeps, bulk report generation. Use custom_id to correlate requests and re-submit only the failures. Pre-merge gating stays on standard, low-latency calls.

Quick Check: Designing the Review Stage

A teammate's CI calls Claude Code to review pull requests. It resumes the same session that generated the code and asks it to review all 14 changed files in one prompt. False positives are high and real cross-file bugs slip through. Which redesign best fixes this?

Recap: Review Like an Architect

Key takeaways:

  • Avoid single-pass multi-file review — it dilutes attention and the middle gets lost. Do per-file local passes THEN a separate cross-file integration pass.
  • Avoid same-session self-review — the author retains its reasoning and won't challenge itself. Review in a fresh, isolated session; beware that forking/resuming carries bias and stale results.
  • Prompt with explicit criteria + 2-4 few-shot examples to minimize false positives.
  • Force structured output (tool + schema, tool_choice:"any"); require only always-present fields.
  • On re-runs, report only new/unfixed issues.
  • Keep blocking review off the Batch API — no latency SLA; reserve batches for overnight audits.

Frequently asked questions

Is the “Prompt & Review Anti-Patterns” lesson free?

Yes — the full text of “Prompt & Review Anti-Patterns” is free to read here on the web, and the Claude Architect course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Claude Architect course, upgrade to CoddyKit PRO.

What will I learn in “Prompt & Review Anti-Patterns”?

Single-pass multi-file review and same-session self-review. You practise Claude Architect with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Claude Architect?

No prior experience is required. Claude Architect on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Prompt & Review Anti-Patterns” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Claude Architect lesson?

Yes. Every Claude Architect lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Loop & Orchestration Anti-Patterns
  2. Tool & Error Anti-Patterns
  3. Prompt & Review Anti-Patterns
  4. Escalation & Metrics Anti-Patterns
← Back to Claude Architect