How to Build a Custom Code Review System with Claude's API
So you're reviewing pull requests for your team, and it's draining. Context switching, nitpicks, architectural questions—it adds up. What if you had a second set of eyes that actually thinks about code, not just lint errors?
I built a custom code review system using Claude's API, and it's saved me hours each week. Here's how.
The Problem with Generic Code Review Tools
Most linters catch syntax errors. That's useful. But they miss the important stuff: Is this approach going to bite us in six months? Are we introducing technical debt? Is there a cleaner way to do this?
Claude can actually reason about code. It understands context, trade-offs, and design patterns. That's different from a regex pattern-matcher.
What We're Building
A simple bot that:
- Reads a pull request diff
- Analyzes it for actual architectural issues, not just style
- Suggests concrete improvements
- Flags potential bugs or performance problems
- Stays out of your way on obvious good code
Setting It Up
First, you'll need the Claude API. Grab your API key from Anthropic's console.
# Install the SDK
npm install @anthropic-ai/sdk
# or
pip install anthropic
Create a simple script to read a diff and send it to Claude:
from anthropic import Anthropic
client = Anthropic()
def review_code_diff(diff_content):
message = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
messages=[
{
"role": "user",
"content": f"""Review this code diff for architectural issues, potential bugs, and design improvements.
Focus on:
- Logic errors or edge cases
- Performance problems
- Code clarity and maintainability
- Missed error handling
- Security concerns
Keep feedback brief and actionable. Ignore style/formatting issues.
{diff_content}
}
]
)
return message.content[0].text
# In practice, you'd read the actual diff from your git/GitHub API
diff = """
--- a/api/auth.js
+++ b/api/auth.js
@@ -15,7 +15,12 @@ async function login(email, password) {
const user = await db.users.findOne({ email });
if (!user) return { error: "Invalid credentials" };
- if (password !== user.password) return { error: "Invalid credentials" };
+ // Check against hashed password
+ const match = await bcrypt.compare(password, user.password);
+ if (!match) return { error: "Invalid credentials" };
+
+ const token = jwt.sign({ id: user.id }, process.env.JWT_SECRET, { expiresIn: "24h" });
+ return { token };
"""
feedback = review_code_diff(diff)
print(feedback)
Real-World Example
I ran this on a diff from a recent PR (refactoring our payment processing). Claude caught:
- Missing error handling - If the payment gateway times out, we silently fail instead of retrying
- Race condition - Two concurrent requests could create duplicate transactions
- Unused variable - Declared but never used (the linter missed this somehow)
- Better approach - Suggested using a webhook queue instead of polling
That's the kind of feedback that actually prevents bugs. A linter would've caught #3, maybe. Claude caught all of them.
Integrating with Your Workflow
You have options here:
Option 1: GitHub Action - Run on every PR automatically
- uses: actions/checkout@v3
- name: Review PR
run: node review-pr.js
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
Option 2: Slack bot - Review on demand
@app.message("review")
def handle_review(ack, message, say):
ack()
diff = get_latest_diff() # Your GitHub integration
feedback = review_code_diff(diff)
say(f"Code Review:\n{feedback}")
Option 3: Local CLI - Review before pushing
git diff | node local-review.js
Things to Watch Out For
Cost - Claude isn't free. A typical diff costs $0.01-0.05. For a team, this adds up. Set token limits per review.
Hallucinations - Claude sometimes invents function names or makes assumptions. Always verify suggestions before implementing.
Context windows - Really large diffs (1000+ line changes) might get cut off. Break them into smaller reviews.
False positives - It'll sometimes flag things that aren't actually issues. Use it as a second opinion, not gospel.
The Real Win
You're not replacing human code review. You're automating the grunt work. Your team reads Claude's feedback first—catches the obvious stuff—then focuses on the hard architectural decisions.
In practice, this cuts review time by 30-40%. More importantly, it catches bugs before they hit production.
Next Steps
Start small. Run Claude on one PR. See if the feedback is useful. Adjust the prompt based on your codebase.
Some teams add it to their CI/CD pipeline. Others use it as a pre-review step in their IDE. Find what fits your workflow.
The code is straightforward. The real value is tuning the prompt to your team's standards. After a few iterations, Claude learns what you care about.
Want more on building with AI tools? Check out LearnAI Weekly newsletter—it's practical stuff about integrating AI into real workflows, not hype.
What would you build with code-understanding AI? Drop a comment.
Top comments (0)