
Bot do wstępnego przeglądu pull requestów z OpenAI i Vercel
Przegląd kodu wymaga skupienia, ale jego pierwszą, powtarzalną część można wspomóc automatyzacją. W tym poradniku zbudujemy prostego asystenta, który pobiera różnicę z GitHub, analizuje ją przez OpenAI Responses API i dodaje komentarz do pull requesta.
To narzędzie nie zatwierdza zmian i nie zastępuje reviewera. Model nie zna całego kontekstu produktu, dlatego każda uwaga wymaga weryfikacji przez człowieka.
Zakres
Bot będzie:
- odbierał zdarzenia GitHub,
- pobierał zmienione pliki,
- szukał konkretnych ryzyk poprawności, bezpieczeństwa i utrzymania,
- publikował jeden zbiorczy komentarz.
Konfiguracja projektu
1mkdir github-pr-reviewer2cd github-pr-reviewer3npm init -y4npm install @octokit/rest openai dotenv express
Potrzebujesz GITHUB_TOKEN, OPENAI_API_KEY, OPENAI_MODEL oraz WEBHOOK_SECRET. Token GitHub powinien mieć tylko uprawnienia niezbędne do odczytu pull requesta i publikacji komentarza.
Handler webhooka
1const express = require('express');2const { Octokit } = require('@octokit/rest');3const OpenAI = require('openai');45const router = express.Router();6const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });7const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });89router.post('/webhook', async (req, res) => {10 verifyWebhookSignature(req);1112 const { action, pull_request, repository } = req.body;13 if (!pull_request || !['opened', 'synchronize', 'ready_for_review'].includes(action)) {14 return res.status(200).send('Event ignored');15 }1617 const owner = repository.owner.login;18 const repo = repository.name;19 const pullNumber = pull_request.number;2021 const { data: files } = await octokit.pulls.listFiles({22 owner,23 repo,24 pull_number: pullNumber,25 });2627 const diff = files28 .filter((file) => file.patch)29 .map((file) => `${file.filename}:\n${file.patch}`)30 .join('\n\n');3132 const response = await openai.responses.create({33 model: process.env.OPENAI_MODEL || 'gpt-5.6-sol',34 instructions: `35 Przeanalizuj diff pod kątem konkretnych błędów poprawności,36 bezpieczeństwa i utrzymania. Wskaż plik i fragment, którego dotyczy uwaga.37 Nie zgłaszaj problemów opartych wyłącznie na brakującym kontekście.38 Jeśli nie widzisz istotnego problemu, napisz to wprost.39 `,40 input: diff,41 max_output_tokens: 700,42 });4344 await octokit.issues.createComment({45 owner,46 repo,47 issue_number: pullNumber,48 body: `## Automatyczny przegląd — szkic\n\n${response.output_text}`,49 });5051 return res.status(200).send('Review added');52});
Weryfikacja webhooka
GitHub podpisuje żądania nagłówkiem x-hub-signature-256. Podpis należy obliczać z surowego ciała żądania, nie z ponownie zserializowanego obiektu JSON. Do porównania użyj crypto.timingSafeEqual, a błędnie podpisane żądanie odrzuć przed wykonaniem jakiejkolwiek operacji.
Jak ograniczać fałszywe alarmy
Najlepszy efekt daje wąski zakres. Zamiast prosić model o „pełny code review”, określ rodzaje problemów i wymagaj wskazania dowodu w diffie. Warto też:
- pomijać pliki wygenerowane i lockfile,
- ograniczać wielkość pojedynczego wejścia,
- nie publikować komentarza, jeśli model nie znalazł konkretnego problemu,
- oznaczać wynik jako szkic,
- mierzyć, ile uwag zostało zaakceptowanych przez reviewerów.
Wdrożenie
Po wdrożeniu funkcji na Vercel dodaj adres /api/webhook w ustawieniach repozytorium GitHub, wybierz zdarzenia pull requestów i ustaw ten sam sekret po obu stronach. Najpierw przetestuj rozwiązanie na repozytorium demonstracyjnym, bez kodu klienta i danych wrażliwych.
Automatyczny przegląd ma największą wartość jako filtr przed właściwą rozmową o kodzie. Powinien kierować uwagę reviewera, a nie udawać, że podjął za niego decyzję.

Michał Winiarski
Founder of Devbrains and senior software developer


