Il code review manuale è uno dei colli di bottiglia più costosi nel ciclo di sviluppo. I reviewer impiegano 30-60 minuti per PR, spesso si concentrano su stile e formattazione invece che sulla logica, e le review arrivano ore o giorni dopo l’apertura. Con Claude AI e GitHub Actions puoi avere un primo feedback automatico entro 30 secondi dall’apertura di ogni PR — non come sostituto della review umana, ma come primo filtro che elimina i problemi ovvi e lascia ai reviewer solo le decisioni che richiedono giudizio umano.
Architettura della pipeline
Il flusso è semplice: (1) sviluppatore apre una PR su GitHub, (2) GitHub Actions triggerizza il workflow, (3) uno script Node.js recupera il diff della PR tramite GitHub API, (4) invia il diff a Claude con un prompt di review strutturato, (5) posta il feedback come commento sulla PR. L’intero processo richiede 20-40 secondi.
GitHub Actions workflow YAML
# .github/workflows/ai-code-review.yml
name: AI Code Review
on:
pull_request:
types: [opened, synchronize]
paths:
- "src/**/*.ts"
- "src/**/*.tsx"
- "src/**/*.js"
permissions:
contents: read
pull-requests: write
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"
- run: npm ci
- name: Run AI Code Review
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_NUMBER: ${{ github.event.pull_request.number }}
REPO: ${{ github.repository }}
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: node scripts/ai-review.mjsLo script Node.js di review
// scripts/ai-review.mjs
import Anthropic from "@anthropic-ai/sdk";
const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
const GITHUB_TOKEN = process.env.GITHUB_TOKEN;
const [owner, repo] = process.env.REPO.split("/");
const prNumber = parseInt(process.env.PR_NUMBER);
// 1. Recupera il diff dalla GitHub API
async function getPRDiff() {
const response = await fetch(
`https://api.github.com/repos/${owner}/${repo}/pulls/${prNumber}/files`,
{
headers: {
Authorization: `Bearer ${GITHUB_TOKEN}`,
Accept: "application/vnd.github+json",
},
}
);
const files = await response.json();
// Limita a 4000 token (~3000 parole) per non eccedere il contesto
const diff = files
.filter((f) => !f.filename.includes("package-lock.json"))
.map((f) => `File: ${f.filename}
${f.patch ?? "(file binario)"}`)
.join("
---
")
.slice(0, 12000); // ~3000 token
return { diff, fileCount: files.length };
}
// 2. Analisi Claude
async function reviewWithClaude(diff, fileCount) {
const response = await anthropic.messages.create({
model: "claude-opus-4-6",
max_tokens: 1500,
system: `Sei un senior developer che fa code review.
Analizza il diff e fornisci feedback CONCISO in italiano.
Struttura la risposta con queste sezioni (usa solo quelle rilevanti):
🚨 **Problemi critici** (bug, security issues, race conditions)
⚠️ **Miglioramenti** (performance, leggibilità, best practice)
✅ **Cosa funziona bene**
💡 **Suggerimenti** (opzionali, non bloccanti)
Sii diretto. Max 400 parole. Non commentare su stile o formattazione se ci sono linter configurati.`,
messages: [
{
role: "user",
content: `Review questa PR (${fileCount} file modificati):
${diff}`,
},
],
});
return response.content[0].text;
}
// 3. Posta il commento sulla PR
async function postComment(review) {
const body = `## 🤖 AI Code Review
${review}
---
*Generato automaticamente da Claude AI. Non sostituisce la review umana.*`;
// Cerca se esiste già un commento AI per aggiornarlo invece di crearne uno nuovo
const commentsRes = await fetch(
`https://api.github.com/repos/${owner}/${repo}/issues/${prNumber}/comments`,
{ headers: { Authorization: `Bearer ${GITHUB_TOKEN}` } }
);
const comments = await commentsRes.json();
const existing = comments.find((c) => c.body.startsWith("## 🤖 AI Code Review"));
const url = existing
? `https://api.github.com/repos/${owner}/${repo}/issues/comments/${existing.id}`
: `https://api.github.com/repos/${owner}/${repo}/issues/${prNumber}/comments`;
await fetch(url, {
method: existing ? "PATCH" : "POST",
headers: {
Authorization: `Bearer ${GITHUB_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ body }),
});
}
// Main
const { diff, fileCount } = await getPRDiff();
if (!diff.trim()) {
console.log("Nessun diff rilevante — skip review");
process.exit(0);
}
const review = await reviewWithClaude(diff, fileCount);
await postComment(review);
console.log("Review postata sulla PR");Configurare il secret ANTHROPIC_API_KEY
Vai su GitHub → Repository → Settings → Secrets and variables → Actions → New repository secret. Aggiungi ANTHROPIC_API_KEY con la tua chiave Anthropic. Il GITHUB_TOKEN è automaticamente disponibile in ogni workflow senza configurazione aggiuntiva — fornisce i permessi per leggere la PR e postare commenti.
Filtrare i falsi positivi
Claude occasionalmente segnala “problemi” che non lo sono — pattern che non conosce, convenzioni del tuo team, decisioni architetturali volontarie. Alcune strategie per ridurre il rumore:
Context nel system prompt: aggiungi una sezione con le convenzioni del tuo progetto — “Usiamo react-query per il data fetching, non useEffect per le chiamate API. Non segnalare questo come problema.” File da ignorare: il filtro nel workflow YAML (paths:) limita già la review ai file rilevanti. Aggiungi pattern per escludere test files se vuoi review solo sul codice di produzione, o viceversa. Soglia di confidenza: aggiungi nel system prompt “Se non sei sicuro al 70% che sia un problema reale, mettilo in Suggerimenti, non in Miglioramenti”.
Configurazione avanzata: review differenziata per tipo di PR
Puoi personalizzare il prompt in base al tipo di cambiamento. Usa le GitHub Actions expressions per rilevare il contesto:
// Adatta il focus della review in base ai file modificati
const hasDatabaseChanges = files.some((f) =>
f.filename.includes("migration") || f.filename.includes("schema")
);
const hasAPIChanges = files.some((f) =>
f.filename.includes("api/") || f.filename.includes("route")
);
const systemPrompt = `Sei un senior developer che fa code review.
${hasDatabaseChanges ? "ATTENZIONE: Questa PR include modifiche al database. Concentrati su: backward compatibility delle migration, indici mancanti, rischio di data loss." : ""}
${hasAPIChanges ? "ATTENZIONE: Questa PR include modifiche alle API. Controlla: validazione input, autenticazione, rate limiting, gestione errori HTTP." : ""}
...`;Risorse correlate
Approfondisci sul blog
- Streaming con Claude API in JavaScript
- GitHub Actions CI/CD: pipeline completa 2026
- Creare un agente AI con JavaScript e Claude
Documentazione e strumenti
FAQ
Quanto costa questo sistema per team con molte PR?
Con Claude Opus 4.6 a ~$15/M token output, una review media di 1500 token di output costa ~$0,022. Per un team che apre 50 PR/mese, il costo è ~$1,10/mese. Se vuoi ridurre i costi, usa Sonnet per review standard e Opus solo per PR con label “needs-careful-review”.
La review AI può approvare automaticamente le PR?
Tecnicamente sì — puoi usare l’API GitHub per approvare PR. Non è consigliato in produzione: Claude può sbagliare, e la responsabilità dell’approvazione deve rimanere umana. Usa la review AI come primo filtro, non come gate finale. Configura branch protection rules che richiedano comunque almeno 1 review umana.
Funziona con repository privati?
Sì. Il GITHUB_TOKEN ha i permessi di leggere il contenuto del repository privato e postare commenti. Il diff viene inviato all’API Anthropic — verifica che sia accettabile secondo le policy di sicurezza del tuo team prima di abilitarlo su repository con codice sensibile.
Come gestisco PR con diff enormi (100+ file)?
Il codice già include un truncate a 12.000 caratteri. Per PR molto grandi, considera di fare review solo dei file più critici: ordina i file per “additions + deletions” decrescente e prendi i top 10-15. Una PR con 100 file è spesso il sintomo di un problema di processo (commit troppo grandi) — Claude può segnalarlo nel suo feedback.

