How to Build a Claude-Powered Code Review Assistant
Building a Claude-powered code review assistant means wiring three things together: a way to pull a diff out of your version control system, a prompt that turns Claude into a disciplined reviewer instead of a generic chatbot, and an output format your team can actually act on (inline PR comments, a Slack message, or a CI check). None of this requires fine-tuning or a custom model — it's a prompt engineering and pipeline problem, not a machine learning problem.
This guide walks through the architecture, the prompt structure that produces consistent, useful reviews, and how to wire it into GitHub Actions or a pre-commit hook. By the end you'll have a working assistant that reviews diffs for bugs, security issues, and style violations, and returns structured feedback you can post directly as comments.
The architecture
A code review assistant has four moving parts:
- Diff extraction — pull the changed files and line ranges from git, GitHub, or GitLab.
- Context gathering — optionally include the full file, related tests, or a style guide.
- The review prompt — a system prompt that defines the reviewer's role, scope, and output format.
- Delivery — post comments back to the PR, fail a CI check, or send a summary to Slack.
Claude handles step 3. Everything else is standard scripting. The quality of the assistant lives almost entirely in how you structure the prompt and what context you feed it — garbage in, garbage review out.
Step 1: Extract a clean diff
Don't send Claude a raw git diff with binary noise and merge markers. Clean it first:
git diff origin/main...HEAD -- '*.ts' '*.js' > diff.patch
Filter to the file types and directories your review policy actually covers. Reviewing generated files, lockfiles, or vendored code wastes tokens and produces noise.
Step 2: Design the review prompt
The system prompt is where most of the value gets built. Three rules make the difference between a useful assistant and a verbose one:
- Scope it narrowly. Tell Claude exactly what to look for: bugs, security issues, missing error handling, performance regressions. Don't ask for "general feedback."
- Force a structured output. Ask for a JSON array of findings with file, line, severity, and message. This is what lets you post findings as individual PR comments instead of one giant wall of text.
- Give it an escape hatch. Explicitly allow an empty findings array. Without this, Claude will invent nitpicks just to have something to say.
You are a senior engineer performing a focused code review.
Review only the diff provided. For each issue found, output:
{"file": string, "line": number, "severity": "high"|"medium"|"low", "message": string}
Return a JSON array. If there are no issues, return [].
Flag only: bugs, security vulnerabilities, missing error handling,
and clear performance problems. Do not comment on style or formatting.
Step 3: Send the request
Here's a minimal request using the Claude Messages API shape:
curl https://api.subtoapi.app/v1/messages \
-H "Authorization: Bearer $SUBTOAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4",
"max_tokens": 2000,
"system": "You are a senior engineer performing a focused code review...",
"messages": [
{"role": "user", "content": "Review this diff:\n\n'"$(cat diff.patch)"'"}
]
}'
If you're routing this through SubToAPI, you get an application key (sub_live_...) instead of managing a raw Claude key, plus usage metadata per request — useful when the review bot is running across dozens of repos and you want to see which teams are generating the most review traffic. Setup takes a few minutes; see /docs/quickstart.
Step 4: Parse and post the findings
Once Claude returns the JSON array, map each finding to a GitHub PR review comment via the Checks or Pulls API:
const findings = JSON.parse(response.content[0].text);
for (const f of findings) {
await octokit.pulls.createReviewComment({
owner, repo, pull_number: prNumber,
commit_id: headSha,
path: f.file,
line: f.line,
body: `**${f.severity.toUpperCase()}**: ${f.message}`,
});
}
Fail the CI job if any high severity findings exist, and let low/medium post as non-blocking comments. This keeps the bot useful without becoming a merge bottleneck.
Handling large diffs with tool use
Large PRs often exceed what's useful in a single prompt. Instead of truncating the diff, give Claude tool use access to a function that fetches additional file context on demand — the full source of a changed file, or a related test file — so it only pulls in what it needs rather than you pre-loading everything. This keeps token usage proportional to the complexity of the change instead of the size of the repo. See /docs/tools for the tool-use request format.
Making it interactive
A CI check is one mode, but a chat-style reviewer that engineers can ask follow-up questions in ("why is this a security issue?") is more useful for junior developers. For that, stream the response instead of waiting for the full completion — it feels responsive even on longer reviews. See /docs/streaming for implementation details, and /docs/messages for the full request/response schema.
Cost and rate limits
Review bots run on every push, which adds up fast if you're not careful. Two practical controls:
- Only review changed lines, not the full file, unless a function signature changed.
- Cap max_tokens on the response — review findings are short; you don't need 4000 tokens per PR.
If you're running this across a team, a managed layer like SubToAPI gives you per-key spend visibility and seat-based billing (Solo, Team, and Scale plans), so you can see exactly which repo or team is driving API costs instead of digging through raw Anthropic usage logs. Check /pricing for plan details.
Questions
Does a Claude-powered reviewer replace human code review? No. It's best used as a first pass that catches obvious bugs, missing error handling, and security issues before a human reviewer spends time on the PR, not as a replacement for approval.
How do I avoid the bot leaving comments on unrelated code? Scope the prompt to the diff only, and explicitly instruct Claude to ignore anything outside the changed line ranges. Also filter your diff extraction to exclude generated or vendored files.
What model should I use for code review? Start with a mid-tier model like Sonnet for cost and latency, and reserve larger models for deep architectural reviews on bigger diffs where reasoning quality matters more than speed.