A Local Code Review Agent: The Use Case Small Models Are Actually Good At

Written by Jakub Rusinowski · Last updated 2026-08-04 · Hardware figures computed by our VRAM engine

Code review is the local-agent use case with the best quality-per-VRAM ratio. Reviewing a diff is bounded, read-only, and needs no multi-step planning — so a 14–27B model does genuinely useful work where the same model would struggle as an autonomous editor. Feed it the diff plus the files it touches, ask for specific defect classes, and gate on severity so it never becomes noise.

Most local-agent disappointment comes from asking a mid-sized model to do the hardest thing available: plan, edit multiple files, and stay coherent for an hour. Review inverts every one of those difficulties. The input is bounded — a diff, plus the files it touches. Nothing is written, so mistakes cost attention rather than code. The task is pattern recognition against known defect classes, which is what these models are best at. And the output goes to a human who filters it anyway.

There is also a straightforward reason to want it local. Review means sending your entire diff — often the most sensitive code in the repo, sometimes with credentials, always with your architecture — somewhere. On your own GPU that question does not arise, which is why review is frequently the first local-AI use case an organisation approves.

What a review agent should and should not look for

The difference between a useful reviewer and a noise generator is entirely in scoping. Linters, formatters and type checkers already exist and are better than any model at what they do. Ask the model for what they cannot see.

Ask for these:

Never ask for these:

A useful reviewer says less than you expect. Five real findings beat forty.

A review script you can run in a pre-commit hook

The whole thing is a diff, a prompt, and a local endpoint. This version reviews staged changes with enough surrounding context to be accurate.

#!/usr/bin/env bash
# review.sh — local review of staged changes
MODEL=${MODEL:-qwen3.6:27b-32k}

DIFF=$(git diff --cached --unified=15)                    # generous context lines
[ -z "$DIFF" ] && { echo "nothing staged"; exit 0; }

PROMPT=$(cat <<'EOF'
You are reviewing a diff before commit. Report ONLY defects you can point at.

Look for: logic errors, missing error handling, concurrency/ordering bugs,
security-relevant patterns (injection, unvalidated input, secrets), resource
leaks, and untested new branches.

Do NOT report: formatting, import order, naming preferences, anything a linter
or type checker would catch, or suggestions to "consider adding a comment".

For each finding output exactly:
SEVERITY (high|medium|low) | file:line | one-sentence defect | why it breaks

If there are no defects, output exactly: NO FINDINGS
EOF
)

printf '%s\n\n--- DIFF ---\n%s\n' "$PROMPT" "$DIFF" \
  | ollama run "$MODEL" \
  | tee /tmp/review.txt

grep -qi '^high' /tmp/review.txt && exit 1 || exit 0   # block on high severity

Three decisions in there are worth copying. --unified=15 — narrow diffs are the top cause of false positives, because the model cannot see that the null check is three lines above the hunk. The explicit "do NOT report" list — without it, half the output is formatting advice. A fixed output format — it makes findings greppable, and it lets you fail the hook only on high severity, so review informs rather than blocks.

Giving it enough context to be right

Review quality tracks context quality more sharply than most tasks, because a diff is by definition an excerpt. In rough order of impact:

1. Widen the diff. --unified=15 or more. Cheap, and it removes a large share of false positives outright. 2. Include the whole file when the diff is dense. If a change touches more than about a third of a file, send the file. Reasoning about an excerpt of a heavily-modified file is guessing. 3. Include the function's callers for signature changes. git grep -n "functionName" output, appended. This is where a reviewer earns its keep — a model that can see three call sites catches the one that was not updated. 4. Include AGENTS.md. Your conventions are exactly what a generic reviewer cannot know, and it is a few hundred tokens (rules files). 5. Review per file, not per PR, on big changes. A 40-file diff exceeds any local window and attention degrades long before the limit. Loop over files and concatenate the findings — slower in wall-clock, dramatically better in signal (context engineering).

Models for review, by tier

Review is read-only and bounded, so the useful floor sits a tier below autonomous editing. VRAM is Q4_K_M weights from the site’s compute engine — add KV cache for the diffs you will feed it.

ModelVRAM (Q4)Runs onContextLicense
Qwen3-Coder 8B
8 GB — single-file review — Catches obvious defects in one file. Expect misses on cross-file reasoning; keep diffs small.
ollama pull qwen3-coder:8b
5.6 GB8 GB GPU (RTX 3060/4060)
Mac: 16 GB unified
125KApache-2.0
Devstral-2 22B
16 GB — the practical floor — Strong at defect classes and consistent formatting of findings. The value pick for review.
ollama pull devstral:22b
14.1 GB16 GB GPU (RTX 4060 Ti 16GB / 5060 Ti)
Mac: 24 GB unified
125KApache-2.0
Qwen 3.6 27B
24 GB — the daily reviewer — Cross-file reasoning becomes dependable; false-positive rate drops noticeably.
ollama pull qwen3.6:27b
17.6 GB24 GB GPU (RTX 3090/4090)
Mac: 24 GB unified
256KApache-2.0
Qwen 2.5 Coder 32B
24–32 GB — code-specialised alternative — Long-standing code specialist; a good second opinion when you want a different model family.
ollama pull qwen2.5-coder:32b
20.1 GB24 GB GPU (RTX 3090/4090)
Mac: 32 GB unified
128KApache-2.0

Controlling false positives

A reviewer that cries wolf gets disabled in a week. Treat precision as the metric, not recall.

Where to run it

Three placements, increasingly ambitious. Start at the top.

Pre-commit hook (local, blocking on high only). Fastest feedback, zero infrastructure, and the diff never leaves the machine. Keep it under about thirty seconds or people will bypass it — small diffs and a resident model make that easy.

Pre-push or a local CI step. More context available (the whole branch diff), less time pressure. A good place for the two-pass security review.

Self-hosted CI, posting findings on the PR. A runner with a GPU, or a shared box serving the model over the network to a runner without one. This is where a team gets consistent review on every PR without any code leaving the building — the reason private, self-hosted AI is an easier internal sell for review than for anything else. Post as comments, never as a blocking status, until the false-positive rate has earned it.

Whichever you pick: the agent is read-only. No auto-fix, no auto-commit. Review that also writes code is two jobs, and combining them removes the property — bounded and consequence-free — that made review a good fit for a local model in the first place.

Frequently asked questions

Can a local LLM do useful code review?
Yes, and it is the local use case with the best quality-per-VRAM ratio. Review is bounded, read-only and pattern-recognition-shaped, so a 16–24 GB model does genuinely useful work where the same model would struggle as an autonomous editor. The constraint is scoping: ask for defect classes a linter cannot see, and demand file:line evidence for each finding.
What model do I need for local code review?
Devstral-2 22B on a 16 GB card is the practical floor and the value pick. Qwen 3.6 27B on 24 GB is where cross-file reasoning becomes dependable and false positives drop noticeably. An 8B model works for single-file diffs but misses anything requiring context beyond the hunk.
How do I stop an AI reviewer from producing noise?
Give it an explicit "do not report" list covering formatting, naming and anything the linter catches; require file:line plus a one-sentence mechanism for every finding; gate blocking on high severity only; run at low temperature; and keep a log of recurring false positives that you fold back into the prompt. Five real findings are worth more than forty.
Why does my review agent flag things that are handled elsewhere in the file?
It cannot see them. A diff is an excerpt, and the null check is often three lines outside the hunk. Widen the diff (git diff --unified=15 or more), send the whole file when a change touches a large fraction of it, and append call sites for signature changes. Context width fixes most false positives before any prompt tuning does.
Should the review agent fix the problems it finds?
No — keep it read-only. A reviewer that also edits is doing two jobs, and it loses the property that made it a good fit for a local model: bounded, consequence-free work. Let a human or a separate, sandboxed editing session act on the findings.
Can this run in CI without sending code to a provider?
Yes. Either give a self-hosted runner a GPU, or serve the model from one shared machine over the network to runners that have none. Findings post as PR comments, and no diff leaves your infrastructure — which is why review is often the first local-AI use case an organisation approves.

Keep going