DEV Community

Emery Chen
Emery Chen

Posted on

From Diff to Comment: A Free AI Reviewer for Your Pull Requests

Your pull request pipeline deserves a free AI review stage. It takes about 30 minutes to wire. This tutorial uses MonkeyCode's free tier. You get automated comments on every PR. The cost is zero until the quota runs out.

Disclosure: This article was prepared as part of MonkeyCode's product outreach.

MonkeyCode is an open-source AI coding assistant. It offers free model access and a free hosted server. Both are operator-supplied claims. Verify the current quotas in the docs before you plan around them.

Why Add an AI First Pass

Human review is slow. It is also expensive. An AI reviewer catches obvious issues first. Your team then focuses on design and architecture.

Treat the AI as a filter. Not as a replacement.

What You Need

  • A GitHub repository
  • A CI provider (GitHub Actions here)
  • A MonkeyCode account with API access
  • A token for the free model endpoint

Stage 1: Get a Token

Sign in to MonkeyCode. Create an API token. The dashboard shows your free quota. Note the number. Record the date. Quotas change.

Store the token as a CI secret. Name it MONKEYCODE_TOKEN.

Stage 2: Write the Review Script

The script reads a diff. It sends the diff to the model. It prints issues in a parseable format.

import os
import sys
import requests

def get_diff():
    if os.environ.get('PR_DIFF'):
        return os.environ['PR_DIFF']
    return sys.stdin.read()

def review(diff):
    url = os.environ.get('MONKEYCODE_URL', 'http://localhost:3000/v1/completions')
    token = os.environ['MONKEYCODE_TOKEN']

    prompt = f"""Review this code diff. Focus on:
1. Bugs and logic errors
2. Security issues
3. Performance problems

For each issue, give: line number, severity (critical/warning/nit), one-sentence fix.

DIFF:
{diff}"""

    response = requests.post(
        url,
        headers={'Authorization': f'Bearer {token}'},
        json={'prompt': prompt, 'max_tokens': 500},
    )
    data = response.json()
    return data['choices'][0]['text']

if __name__ == '__main__':
    diff = get_diff()
    if not diff.strip():
        print('No diff to review.')
        sys.exit(0)
    print(review(diff))
Enter fullscreen mode Exit fullscreen mode

Stage 3: Test the Script Locally

Do not push to CI yet. Test on your machine first.

Create a sample diff file.

cat > /tmp/sample.diff << 'EOF'
+def calculate_total(items):
+    total = 0
+    for item in items:
+        total += item.price
+    return total
EOF
Enter fullscreen mode Exit fullscreen mode

Run the script.

export MONKEYCODE_TOKEN=your-token
export MONKEYCODE_URL=http://localhost:3000
python review.py < /tmp/sample.diff
Enter fullscreen mode Exit fullscreen mode

Verify: You see a list of issues. The format includes line numbers and severity. If you get an error, fix it now. CI debugging is slower.

Stage 4: Wire It Into GitHub Actions

Create .github/workflows/ai-review.yml.

name: AI Code Review
on:
  pull_request:
    types: [opened, synchronize]

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Get diff
        run: |
          git diff origin/main...HEAD > /tmp/diff.txt
          echo "PR_DIFF=$(cat /tmp/diff.txt)" >> $GITHUB_ENV
      - name: Run AI review
        env:
          MONKEYCODE_TOKEN: ${{ secrets.MONKEYCODE_TOKEN }}
          MONKEYCODE_URL: ${{ vars.MONKEYCODE_URL }}
        run: |
          python review.py < /tmp/diff.txt > /tmp/review.txt
      - name: Post comment
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const review = fs.readFileSync('/tmp/review.txt', 'utf8');
            if (review.trim() === 'No diff to review.') {
              console.log('Nothing to review.');
              return;
            }
            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              body: '## AI Review\n\n' + review
            });
Enter fullscreen mode Exit fullscreen mode

Stage 5: Verify It Works

Open a test PR. Add a deliberate bug. Watch the CI run.

Verify:

  • The CI job passes
  • A comment appears on the PR
  • The comment mentions the bug you planted

If the comment does not appear, check the CI logs. Common causes: wrong token, wrong URL, empty diff.

Expected Failure Modes

Free tiers fail in predictable ways. Here is what you will hit.

Symptom Cause Fix
401 Wrong token Regenerate. Update the secret.
429 Quota exhausted Add a fallback. Or wait.
Empty comment Model returned nothing Increase max_tokens.
Timeout Free server slow Increase CI timeout.

Add a Fallback

A free tier can run out. Your CI should not break when it does. Add a fallback. If the review fails, post a warning instead of failing the build.

try:
    review_text = review(diff)
except Exception as e:
    print(f'AI review failed: {e}')
    print('Skipping AI review. Human review required.')
    sys.exit(0)
Enter fullscreen mode Exit fullscreen mode

This keeps the pipeline green. The AI review is a bonus. Not a gate.

Tune the Prompt

The default prompt is a starting point. Your codebase has its own patterns. Adjust the prompt to match.

Add your project's conventions. Add your security checklist. Add your common bug patterns.

prompt = f"""Review this diff for a Django project.
Check for: missing migrations, N+1 queries, missing CSRF protection.
Also check: {', '.join(EXTRA_CHECKS)}
...
"""
Enter fullscreen mode Exit fullscreen mode

A tuned prompt beats a generic one. Spend ten minutes on it.

Limit Diff Size

Large diffs burn tokens fast. A 1000-line diff can cost thousands of tokens. Set a limit.

MAX_DIFF_CHARS = 10000

if len(diff) > MAX_DIFF_CHARS:
    print('Diff too large for AI review. Skipping.')
    sys.exit(0)
Enter fullscreen mode Exit fullscreen mode

This protects your quota. It also keeps review quality high. Models lose focus on huge inputs.

Limitations

  • The free quota is finite. Heavy teams will exhaust it.
  • Free servers are shared. Latency varies.
  • Model quality varies. The review is a first pass. Not a guarantee.
  • The prompt matters. Tune it to your codebase.

Who Should Skip This

  • Teams with strict data policies. Code goes to a third-party server.
  • Teams needing guaranteed reviews. Free tiers have no SLA.
  • Teams with huge diffs. Token costs scale with diff size.

Your Pipeline, Upgraded

You now have a free AI reviewer. It catches obvious issues. It runs on every PR. It costs nothing until the quota runs out.

Start with a small repo. Tune the prompt. Watch the first few reviews. Then expand.

The script is yours. The workflow is yours. The free tier is the only dependency.

Top comments (0)