Agentic AI Code Reviewer — A Complete Developer Guide

How to create Agentic AI Code Reviewer

Complete Developer Guide

Agentic AI Code Reviewer

An autonomous AI agent that reads GitHub Pull Requests, analyzes code changes with a local LLM, and posts automated review comments — simulating a senior engineer’s review process.

Python 3.10+runtime
Ollamalocal llama3.2:3b
PyGithub + httpxgithub + async http
Agenticautonomous loop
Download / Source Code

Full project source on GitHub: Click Here

01
Overview

What Is This Project For?

The Agentic AI Code Reviewer is a Python-based autonomous agent that monitors a GitHub Pull Request, extracts the code diff, feeds it to a locally-running Large Language Model (Ollama), and posts an AI-generated code review directly as a comment on the PR — all without any manual intervention.

“It simulates how a senior engineer reviews pull requests — detecting bugs, code quality issues, performance risks, and improvement suggestions.”

3
Core Modules
100%
Local LLM — No Cloud Cost
0
UI Required — Pure CLI
~45s
Avg Review Time

How It Works — System Architecture

System Architecture
👨‍💻 Developer Opens Pull Requeston any GitHub repository
📡 GitHub REST APIfetches PR file diffs via PyGithub
🤖 CodeReviewAgentagents/review_agent.py — orchestrates the workflow
📝 Prompt Builderinjects diff into structured review prompt
🧠 Local LLM via Ollamallama3.2:3b running at localhost:11434
🔍 AI Code Analysisbugs · quality · performance · security
💬 GitHub Comment Botposts review as PR comment via PyGithub

What the AI Reviews

The agent instructs the LLM to focus on four pillars:

🐛

Bugs

Logic errors, null dereferences, off-by-one errors, and missing edge case handling.

🧹

Code Quality

Naming conventions, type hints, docstrings, function decomposition, and readability.

Performance

Inefficient algorithms, unnecessary re-computation, redundant API calls.

02
Setup

Project Requirements

⚠ Important — Local LLM Required

This project does not call OpenAI, Anthropic, or any cloud AI API. It runs a local LLM through Ollama. You must install Ollama and pull a model before running the agent.

1 · Python 3.10+

The project uses async/await (asyncio) and modern type hints, requiring Python 3.10 or newer.

shell
# Check your version
python --version
# Should show Python 3.10.x or higher

# Install on Ubuntu/Debian
sudo apt update && sudo apt install python3.11 python3-pip -y

# Install on macOS via Homebrew
brew install python@3.11

2 · Ollama — Local LLM Runtime

Ollama runs large language models locally on your machine. The project defaults to llama3.2:3b, a fast and capable 3-billion-parameter model.

1

Install Ollama

# macOS / Linux (one-liner installer)
curl -fsSL https://ollama.com/install.sh | sh

# Windows
winget install Ollama.Ollama
2

Pull the LLaMA 3.2 3B model

ollama pull llama3.2:3b
3

Start the Ollama server

ollama serve
# Server now runs at http://localhost:11434
4

Verify it works

curl http://localhost:11434/api/generate 
  -d '{"model":"llama3.2:3b","prompt":"hello","stream":false}'

3 · Python Dependencies

The requirements.txt only lists two packages, but you’ll also need python-dotenv (used in test files):

# requirements.txt
httpx — async HTTP client used to call Ollama’s REST API
PyGithub — GitHub REST API wrapper for reading PRs & posting comments
shell
# Create and activate a virtual environment (recommended)
python -m venv venv
source venv/bin/activate        # macOS/Linux
venvScriptsactivate           # Windows

# Install required packages
pip install httpx PyGithub python-dotenv
ℹ Note on python-dotenv

The test_github.py file uses from dotenv import load_dotenv to load your .env file. You should install python-dotenv even though it’s not listed in requirements.txt.

4 · Git (optional but recommended)

# Clone the repository
git clone https://github.com/gauravsinghshl/agentic-code-reviewer.git
cd agentic-code-reviewer

03
Configuration

External Keys & Configuration

This project requires exactly one external credential: a GitHub Personal Access Token. There is no cloud LLM key because all AI inference runs locally via Ollama.

GITHUB_TOKEN Required

A GitHub Personal Access Token (PAT) with permissions to read repository contents and post PR comments. Used by GitHubService in services/github_service.py.

  • Go to github.com → Settings → Developer settings → Personal access tokens → Tokens (classic)
  • Click “Generate new token (classic)”
  • Give it a descriptive name, e.g. ai-code-reviewer
  • Set expiration (90 days recommended for testing)
  • Under Scopes, check: repo (full control of private repositories) — this covers both reading PRs and posting comments
  • Click “Generate token” and copy the token immediately (it won’t be shown again)

Setting Up Your .env File

The project reads GITHUB_TOKEN from environment variables. Create a .env file in the project root:

shell
# Create .env file in project root
touch .env

# Add your token
echo 'GITHUB_TOKEN=ghp_your_actual_token_here' >> .env

Or create the file manually with this content:

.env
# .env — DO NOT commit this file to git
GITHUB_TOKEN=ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
🔐 Security Warning

The .env file is already listed in .gitignore — never commit it. Never hardcode the token in any source file. If a token is accidentally exposed, revoke it immediately at github.com/settings/tokens.

How the Token Is Consumed

github_service.py
import os
from github import Github

class GitHubService:
    def __init__(self):
        token = os.getenv("GITHUB_TOKEN")  # reads from environment
        if not token:
            raise Exception("GITHUB_TOKEN not set")
        self.github = Github(token)

All Variables At a Glance

Variable Where Used Required? Description
GITHUB_TOKEN github_service.py REQUIRED GitHub Personal Access Token with repo scope
model llm_service.py (constructor arg) OPTIONAL Ollama model name. Default: llama3.2:3b. Change to any pulled Ollama model.
url (Ollama) llm_service.py (hardcoded) OPTIONAL Ollama server endpoint. Default: http://localhost:11434/api/generate
repo_name test_pr_reader.py, test_pr_review.py REQUIRED Target GitHub repository in OWNER/REPO format
pr_number test_pr_reader.py, test_pr_review.py REQUIRED Pull Request number integer to review

04
Code Reference

File-by-File Reference

Project Structure

agentic-code-reviewer/
├─ agents/
│ └─ review_agent.py Core agent — builds prompt, calls LLM
├─ services/
│ ├─ github_service.py GitHub API wrapper — reads PRs, posts comments
│ └─ llm_service.py Ollama client — sends prompts, returns text
├─ prompts/
│ └─ review_prompt.txt System prompt template (for reference)
├─ test_agent.py Test: agent on a hardcoded mock diff
├─ test_github.py Test: verify GitHub token is valid
├─ test_pr_reader.py Test: read a real PR diff only
├─ test_pr_review.py ⭐ Main runner: end-to-end review & post comment
├─ test_token.py Test: print current GITHUB_TOKEN value
├─ requirements.txt
├─ README.MD
└─ .gitignore

review_agent.py agents/review_agent.py

Role: The central orchestrator — the “agent brain”. It holds a LocalLLM instance and exposes review_diff(diff), an async method that builds the review prompt and calls the LLM.

Name Type Description
self.llm LocalLLM Instance of the Ollama client, injected at construction
diff str Raw GitHub diff text passed into review_diff()
prompt str (f-string) Full instruction + diff text sent to the LLM. Instructs it to act as a senior developer and focus on Bugs, Code quality, Performance, Security
review str The LLM’s response text, returned from review_diff()
review_agent.py
class CodeReviewAgent:
    def __init__(self):
        self.llm = LocalLLM()          # instantiates Ollama client

    async def review_diff(self, diff: str):
        prompt = f"""
        You are a senior developer reviewing a GitHub pull request.
        ...
        GitHub Diff: {diff}
        Return feedback in bullet points."""

        review = await self.llm.generate(prompt)
        return review

llm_service.py services/llm_service.py

Role: A thin async HTTP wrapper around Ollama’s /api/generate endpoint. Sends a prompt and returns the response text. Uses httpx.AsyncClient with a 120-second timeout (LLM inference can be slow).

Name Type Description
self.url str Ollama API endpoint — hardcoded as http://localhost:11434/api/generate
self.model str Ollama model name. Default llama3.2:3b. Passed in constructor — change here to use a different model.
prompt str The full text prompt received from the agent
temperature float (0) LLM generation temperature. Set to 0 for deterministic/consistent reviews.
stream bool (False) Streaming disabled — waits for complete response before returning
timeout int (120) HTTP timeout in seconds for the Ollama call
llm_service.py
class LocalLLM:
    def __init__(self, model="llama3.2:3b"):
        self.url = "http://localhost:11434/api/generate"
        self.model = model

    async def generate(self, prompt: str):
        async with httpx.AsyncClient(timeout=120) as client:
            response = await client.post(
                self.url,
                json={
                    "model": self.model,
                    "prompt": prompt,
                    "stream": False,
                    "options": {"temperature": 0}
                }
            )
        return response.json()["response"]

github_service.py services/github_service.py

Role: GitHub API abstraction layer. Provides two capabilities: (1) reading the unified diff of all changed files in a PR, and (2) posting a text comment on that PR. Uses the PyGithub library and reads the token from environment.

Name Type Description
token str Read from os.getenv("GITHUB_TOKEN") — raises Exception if missing
self.github Github Authenticated PyGithub client instance
repo_name str “OWNER/REPO” format, e.g. "gauravsinghshl/my-project"
pr_number int Pull Request number, e.g. 1
diff str Accumulated diff string built by iterating pr.get_files()
file.filename str Name of each changed file in the PR
file.patch str The actual unified diff (lines added/removed) for each file
comment str The AI-generated review text to post on the PR
github_service.py
def get_pull_request_diff(self, repo_name, pr_number):
    repo = self.github.get_repo(repo_name)
    pr = repo.get_pull(pr_number)
    diff = ""
    for file in pr.get_files():
        diff += f"File: {file.filename}n"
        diff += file.patch + "n"
    return diff

def comment_on_pr(self, repo_name, pr_number, comment):
    repo = self.github.get_repo(repo_name)
    pr = repo.get_pull(pr_number)
    pr.create_issue_comment(comment)

review_prompt.txt prompts/review_prompt.txt

Role: A standalone prompt template for reference or alternative use. It is not currently imported by any code — the inline prompt in review_agent.py is what’s actually used. However, this file documents the intended review structure and can be extended for more structured output.

review_prompt.txt
You are a senior software engineer reviewing code.

Analyze the following code and provide:

1. Bugs
2. Code quality issues
3. Security risks
4. Suggested improvements

Code:
{code}

Return structured feedback.
💡 How to use this file

To use this template instead of the hardcoded prompt, read it in review_agent.py via open("prompts/review_prompt.txt").read() and format it with the diff string.

Test & Runner Scripts

test_pr_review.py ⭐ Main end-to-end runner

This is the primary script to run. It connects all three components: reads a real GitHub PR, sends the diff to the LLM, and posts the review as a PR comment.

Variable You Must Change? Description
repo_name YES Change to your target repo: "OWNER/REPO"
pr_number YES Change to the PR number you want reviewed
test_agent.py Offline LLM test (no GitHub needed)

Tests the agent with a hardcoded mock diff. Useful for verifying Ollama is running correctly without needing a GitHub token. Run this first to sanity-check your LLM setup.

test_github.py Token validation test

Calls GitHub with your token and prints your username. If this works, your token is valid and correctly loaded from .env.

test_pr_reader.py PR diff reader (no LLM)

Reads a PR diff and prints it to console without calling the LLM. Useful for checking what code the agent sees before sending it for review.

test_token.py Env var debug

Simply prints the value of os.getenv("GITHUB_TOKEN"). If this prints None, your .env file is not being loaded — remember to use python-dotenv or export the variable manually.

05
Run

How to Start the Project

1

Clone the repository

git clone https://github.com/gauravsinghshl/agentic-code-reviewer.git
cd agentic-code-reviewer
2

Create & activate a Python virtual environment

python -m venv venv
source venv/bin/activate      # macOS / Linux
venvScriptsactivate         # Windows PowerShell
3

Install Python dependencies

pip install httpx PyGithub python-dotenv
4

Install Ollama and pull the LLM model

# Install Ollama (macOS/Linux)
curl -fsSL https://ollama.com/install.sh | sh
# Windows
winget install Ollama.Ollama

# Pull the default model (~2GB download)
ollama pull llama3.2:3b

# Start the Ollama server (keep this terminal open)
ollama serve
# Verify: http://localhost:11434/api/tags
5

Create your .env file with your GitHub token

# In the project root directory
cat > .env << 'EOF'
GITHUB_TOKEN=ghp_your_github_personal_access_token
EOF
6

Verify your setup — run the quick tests first

# 6a: Check token is loaded
python test_token.py
# Expected: prints your token (not None)

# 6b: Verify GitHub authentication
python test_github.py
# If certificate issue: pip install pip-system-certs
# Expected: prints your GitHub username

# 6c: Test the LLM (no GitHub needed)
python test_agent.py
# Expected: AI review printed to console
7

Edit test_pr_review.py with your target PR

# Open test_pr_review.py and change these two lines:
repo_name = "YOUR_GITHUB_USERNAME/YOUR_REPO_NAME"
pr_number = 1  # the PR number you want reviewed
8

Run the full end-to-end agent

python test_pr_review.py

The agent will: read the PR diff → send to Ollama → generate review → post as GitHub PR comment. This may take 30–120 seconds depending on diff size and your hardware.

✅ Success Indicators

When the run completes successfully you should see: AI review posted to GitHub PR! printed in the terminal, and a new comment on your GitHub Pull Request from your bot account containing the AI code review.

Troubleshooting Common Errors

Error Cause Fix
GITHUB_TOKEN not set .env not loaded or missing Load env manually: export GITHUB_TOKEN=ghp_xxx or use python-dotenv
ConnectionRefusedError localhost:11434 Ollama server not running Run ollama serve in a separate terminal
404 Not Found from Ollama Model not pulled Run ollama pull llama3.2:3b
GithubException 401 Invalid or expired token Generate a new token at github.com/settings/tokens
GithubException 403 Token lacks required scope Regenerate token with repo scope checked
AttributeError: 'NoneType' has no 'patch' A PR file has no diff (e.g. binary file) Add a check: if file.patch: diff += file.patch

06
Walkthrough

Sample Demo Walkthrough

Scenario

A developer opens PR #1 on the repository gauravsinghshl/genai-rag-document-qa. The PR changes a Python utility function. We run the agent to get an automated review.

Step 1 — The Pull Request Code Change

The PR modifies a function — here is what the diff looks like:

GitHub Diff (PR #1)
File: utils/calculator.py

- def calculate(x,y):
-  return x+y
+ def add_numbers(x: int, y: int) -> int:
+     return x + y

Step 2 — Running the Agent

Terminal

$ python test_pr_review.pyReading repo: gauravsinghshl/genai-rag-document-qa
PR number: 1

Pull Request Code Changes:

File: utils/calculator.py
– def calculate(x,y):
– return x+y
+ def add_numbers(x: int, y: int) -> int:
+ return x + y

Sending diff to Ollama (llama3.2:3b)…
Waiting for LLM response… [~45 seconds]

AI Code Review:

• Bugs:
– No input validation: the function does not check if x or y
are integers; passing strings or floats could cause unexpected behavior.

• Code Quality:
– Function rename from `calculate` to `add_numbers` is a good
improvement — the name is now self-documenting.
– Type hints (x: int, y: int) and return annotation (-> int)
significantly improve readability and tooling support. Good change.
– Missing docstring: add a brief description of the function’s purpose.

• Performance:
– No performance concerns for this simple operation.

• Security:
– No security risks identified in this diff.

• Suggested Improvement:
– Add a docstring: `”””Add two integers and return their sum.”””`
– Consider raising `TypeError` if inputs are not integers.

AI review posted to GitHub PR!

Step 3 — The GitHub PR Comment (What It Looks Like)

After the script completes, a comment is automatically posted by your GitHub account on the Pull Request:

GitHub PR Comment — Posted by the Agent

🤖 AI Code ReviewBugs:
• No input validation — passing strings or floats could cause unexpected behavior.

Code Quality:
• ✅ Function rename from `calculate` to `add_numbers` improves clarity.
• ✅ Type hints improve readability and IDE/tooling support.
• ⚠ Missing docstring — add a description of the function’s purpose.

Performance:
• No performance concerns for this operation.

Security:
• No security risks identified.

Suggested Improvements:
• Add docstring: `”””Add two integers and return their sum.”””`
• Consider raising `TypeError` if inputs are not integers.

Testing with the Offline Mock (No GitHub Required)

To test just the LLM part without touching GitHub, run test_agent.py:

python test_agent.py

# Output:

AI PR Review

• Bugs:
  - No input validation on x and y parameters.

• Code Quality:
  - Good: added type hints and descriptive function name.
  - Missing docstring for the function.

• Performance:
  - No issues for this simple operation.

• Security:
  - No security concerns.
✅ You’re Done!

The agent is fully functional. To review any PR on any repository you have access to, simply update repo_name and pr_number in test_pr_review.py and run it again.

Customization Tips

Change the LLM Model

In llm_service.py, change model="llama3.2:3b" to any Ollama model you’ve pulled — e.g. codellama:7b or mistral:7b.

Customize the Review Prompt

Edit the inline prompt string in review_agent.py or load prompts/review_prompt.txt to change the focus areas or output format.

Add Loop / Automation

Wrap test_pr_review.py logic in a polling loop or GitHub webhook handler to automatically review every new PR.

Different LLM Temperature

Change "temperature": 0 in llm_service.py to e.g. 0.3 for slightly more varied, creative review suggestions.

Download / Source Code

Clone or download the full project:Click Here

Leave a Reply

Your email address will not be published. Required fields are marked *