Lokalny agent do przeglądu kodu: zastosowanie, w którym małe modele są naprawdę dobre

Autor: Jakub Rusinowski · Ostatnia aktualizacja 2026-08-04 · Wartości sprzętowe wyliczone naszym silnikiem VRAM

Przegląd kodu to zastosowanie lokalnego agenta o najlepszym stosunku jakości do VRAM-u. Przeglądanie diffa jest ograniczone, tylko do odczytu i nie wymaga wielokrokowego planowania — więc model 14–27B wykonuje naprawdę użyteczną pracę tam, gdzie ten sam model miałby kłopoty jako autonomiczny edytor. Podaj mu diff razem z plikami, których dotyka, poproś o konkretne klasy defektów i bramkuj według istotności, żeby nigdy nie zamienił się w szum.

Większość rozczarowań lokalnymi agentami bierze się z proszenia średniej wielkości modelu o najtrudniejszą dostępną rzecz: zaplanuj, zmień wiele plików i utrzymaj spójność przez godzinę. Przegląd odwraca każdą z tych trudności. Wejście jest ograniczone — diff plus pliki, których dotyka. Nic nie jest zapisywane, więc pomyłki kosztują uwagę, a nie kod. Zadanie polega na rozpoznawaniu wzorców na tle znanych klas defektów, czyli na tym, w czym te modele są najlepsze. A wynik trafia do człowieka, który i tak go przefiltruje.\n\nJest też prosty powód, żeby chcieć tego lokalnie. Przegląd oznacza wysłanie gdzieś całego diffa — często najwrażliwszego kodu w repozytorium, czasem razem z poświadczeniami, zawsze z twoją architekturą. Na własnym GPU to pytanie w ogóle nie pada, dlatego przegląd bywa pierwszym zastosowaniem lokalnej AI, które organizacja zatwierdza.

Czego agent przeglądający ma szukać, a czego nie

Różnica między użytecznym recenzentem a generatorem szumu leży w całości w zakreśleniu zadania. Lintery, formatery i kontrolery typów już istnieją i w swojej robocie są lepsze od dowolnego modelu. Proś model o to, czego one nie widzą.\n\nProś o to:\n- Błędy logiczne, które typy przepuszczą — off-by-one, odwrócony warunek, zła zmienna w skopiowanym bloku\n- Brak obsługi błędu przy wywołaniu, które może się nie powieść\n- Problemy współbieżności i kolejności — await w pętli, współdzielony zmienny stan, brakująca granica transakcji\n- Wzorce istotne dla bezpieczeństwa — zapytania bez parametryzacji, niezwalidowane wejście docierające do powłoki albo systemu plików, sekrety w kodzie, zbyt liberalny CORS\n- Wycieki zasobów — niezamknięte uchwyty, nieograniczone cache'e, brak paginacji\n- Niespójność z konwencjami panującymi w otaczającej bazie kodu\n- Brak pokrycia testami dla gałęzi, którą wprowadza ten diff — często najcenniejsze pojedyncze znalezisko\n\nNigdy nie proś o to:\n- Formatowanie ani kolejność importów (to robi twój formater, deterministycznie)\n- Cokolwiek, co zgłasza już twój kontroler typów albo linter — zdublowane znaleziska uczą ludzi ignorować narzędzie\n- Subiektywne opinie o architekturze, chyba że zadałeś konkretne pytanie\n- „Rozważ dodanie komentarza” — klasyczny wypełniacz, który niszczy zaufanie do całego wyniku\n\nUżyteczny recenzent mówi mniej, niż się spodziewasz. Pięć prawdziwych znalezisk bije czterdzieści.

Skrypt przeglądu, który uruchomisz w hooku pre-commit

Całość to diff, prompt i lokalny endpoint. Ta wersja przegląda zmiany z poczekalni z zapasem otoczenia wystarczającym, by była trafna.

#!/usr/bin/env bash
# review.sh — lokalny przegląd zmian z poczekalni
MODEL=${MODEL:-qwen3.6:27b-32k}

DIFF=$(git diff --cached --unified=15)                    # hojnie dużo linii kontekstu
[ -z "$DIFF" ] && { echo "nothing staged"; exit 0; }

PROMPT=$(cat <<'EOF'
You are reviewing a diff before commit. Report ONLY defects you can point at.

Look for: logic errors, missing error handling, concurrency/ordering bugs,
security-relevant patterns (injection, unvalidated input, secrets), resource
leaks, and untested new branches.

Do NOT report: formatting, import order, naming preferences, anything a linter
or type checker would catch, or suggestions to "consider adding a comment".

For each finding output exactly:
SEVERITY (high|medium|low) | file:line | one-sentence defect | why it breaks

If there are no defects, output exactly: NO FINDINGS
EOF
)

printf '%s\n\n--- DIFF ---\n%s\n' "$PROMPT" "$DIFF" \
  | ollama run "$MODEL" \
  | tee /tmp/review.txt

grep -qi '^high' /tmp/review.txt && exit 1 || exit 0   # blokuj przy wysokiej istotności

Trzy decyzje w tym skrypcie warto skopiować. --unified=15 — wąskie diffy to główna przyczyna fałszywych alarmów, bo model nie widzi, że sprawdzenie na null jest trzy linijki nad hunkiem. Jawna lista „do NOT report” — bez niej połowa wyjścia to porady o formatowaniu. Ustalony format wyjścia — dzięki niemu wyniki łatwo wygrepować, a hook możesz oblewać wyłącznie przy wysokiej istotności, więc przegląd informuje, zamiast blokować.

Sam prompt zostaje po angielsku celowo: to instrukcja dla modelu, a modele kodujące trzymają się angielskich instrukcji wyraźnie lepiej.

Jak dać mu dość kontekstu, żeby miał rację

Jakość przeglądu idzie za jakością kontekstu ostrzej niż w większości zadań, bo diff jest z definicji wycinkiem. Z grubsza w kolejności wpływu:\n\n1. Poszerz diff. --unified=15 albo więcej. Tanie, a od ręki usuwa sporą część fałszywych alarmów.\n2. Dołącz cały plik, gdy diff jest gęsty. Jeśli zmiana dotyka więcej niż jakiejś jednej trzeciej pliku, wyślij plik. Rozumowanie na wycinku mocno przerobionego pliku to zgadywanie.\n3. Przy zmianach sygnatury dołącz wywołujących. Wyjście git grep -n "functionName", doklejone na końcu. Tu recenzent zarabia na siebie — model widzący trzy miejsca wywołania wyłapie to jedno, którego nie zaktualizowano.\n4. Dołącz AGENTS.md. Twoje konwencje to dokładnie to, czego ogólny recenzent nie może znać, a kosztują kilkaset tokenów (pliki z regułami).\n5. Przy dużych zmianach przeglądaj plik po pliku, nie cały pull request. Diff na czterdzieści plików przekracza każde lokalne okno, a uwaga degraduje się na długo przed limitem. Przejdź pętlą po plikach i sklej znaleziska — wolniej na zegarze, dramatycznie lepiej pod względem sygnału (context engineering).

Modele do przeglądu, według progu

Przegląd jest tylko do odczytu i ograniczony, więc użyteczna podłoga leży o próg niżej niż przy autonomicznej edycji. VRAM to wagi Q4_K_M z silnika obliczeniowego tej strony — dolicz cache KV pod diffy, którymi będziesz go karmić.

ModelVRAM (Q4)Uruchomi się naKontekstLicencja
Qwen3-Coder 8B
8 GB — przegląd jednego pliku — Wyłapuje oczywiste defekty w obrębie jednego pliku. Licz się z pudłami przy rozumowaniu międzyplikowym; trzymaj diffy małe.
ollama pull qwen3-coder:8b
5.6 GB8 GB GPU (RTX 3060/4060)
Mac: 16 GB pamięci zunifikowanej
125KApache-2.0
Devstral-2 22B (Unverified Listing)
16 GB — praktyczna podłoga — Mocny w klasach defektów i w konsekwentnym formatowaniu znalezisk. Wybór za rozsądne pieniądze do przeglądu.
ollama pull devstral:22b
14.1 GB16 GB GPU (RTX 4060 Ti 16GB / 5060 Ti)
Mac: 24 GB pamięci zunifikowanej
125KApache-2.0
Qwen 3.6 27B
24 GB — recenzent na co dzień — Rozumowanie międzyplikowe robi się godne zaufania; odsetek fałszywych alarmów zauważalnie spada.
ollama pull qwen3.6:27b
17.6 GB24 GB GPU (RTX 3090/4090)
Mac: 24 GB pamięci zunifikowanej
256KApache-2.0
Qwen 2.5 Coder 32B
24–32 GB — alternatywa wyspecjalizowana w kodzie — Od dawna obecny specjalista od kodu; dobra druga opinia, gdy chcesz modelu z innej rodziny.
ollama pull qwen2.5-coder:32b
20.1 GB24 GB GPU (RTX 3090/4090)
Mac: 32 GB pamięci zunifikowanej
128KApache-2.0

Trzymanie fałszywych alarmów w ryzach

Recenzent, który zbyt często krzyczy „wilk!”, zostaje wyłączony w tydzień. Traktuj precyzję jako miarę, nie czułość.\n\n- Żądaj dowodu. Wymaganie file:line plus jednozdaniowego mechanizmu tłumi mgliste znaleziska, bo model musi zobowiązać się do czegoś sprawdzalnego.\n- Bramkuj według istotności. Blokują wyłącznie znaleziska o wysokiej istotności. Cała reszta się wypisuje i ma charakter doradczy. Samo to dzieli narzędzie, które ludzie zostawiają, od takiego, które zaczynają obchodzić.\n- Odsiewaj duplikaty względem lintera. Puść najpierw lint i odetnij znaleziska nazywające regułę, którą linter już obejmuje.\n- Niska temperatura. 0,1–0,2. Twórczy przegląd to nie jest rzecz, której chcesz.\n- Dwa przebiegi na ważnych ścieżkach. Przy diffach wrażliwych na bezpieczeństwo puść raz pod logikę i raz pod bezpieczeństwo, z osobnymi promptami. Dwa skupione przebiegi biją jeden prompt proszący o wszystko — a lokalnie ten drugi kosztuje tylko czas.\n- Prowadź dziennik fałszywych alarmów. Gdy to samo błędne znalezisko wraca, dopisz dla niego linijkę do „do NOT report”. Ta sama metapętla co wszędzie indziej: każda powracająca korekta staje się trwałą poprawką.

Gdzie to uruchomić

Trzy miejsca, coraz ambitniejsze. Zacznij od pierwszego.\n\nHook pre-commit (lokalnie, blokujący tylko przy wysokiej istotności). Najszybsze sprzężenie zwrotne, zero infrastruktury, a diff nigdy nie opuszcza maszyny. Trzymaj to poniżej jakichś trzydziestu sekund, bo inaczej ludzie zaczną go omijać — małe diffy i model trzymany w pamięci sprawiają, że jest to łatwe.\n\nPre-push albo lokalny krok CI. Więcej dostępnego kontekstu (diff całej gałęzi), mniejsza presja czasu. Dobre miejsce na dwuprzebiegowy przegląd bezpieczeństwa.\n\nWłasne CI, publikujące znaleziska przy pull requeście. Runner z kartą albo wspólna maszyna serwująca model przez sieć runnerowi, który karty nie ma. Tu zespół dostaje spójny przegląd przy każdym pull requeście bez wypuszczania kodu poza firmę — z tego powodu prywatną AI stawianą u siebie łatwiej przepchnąć wewnętrznie na przegląd niż na cokolwiek innego. Publikuj jako komentarze, nigdy jako blokujący status, dopóki odsetek fałszywych alarmów na to nie zasłuży.\n\nCokolwiek wybierzesz: agent działa tylko do odczytu. Bez automatycznych poprawek, bez automatycznych commitów. Przegląd, który jednocześnie pisze kod, to dwa zadania naraz, a ich połączenie odbiera tę własność — ograniczoność i brak konsekwencji — która na starcie uczyniła przegląd dobrym dopasowaniem do lokalnego modelu.

Najczęstsze pytania

Czy lokalny LLM potrafi zrobić użyteczny przegląd kodu?
Tak i jest to lokalne zastosowanie o najlepszym stosunku jakości do VRAM-u. Przegląd jest ograniczony, tylko do odczytu i ma kształt rozpoznawania wzorców, więc model 16–24 GB wykonuje naprawdę użyteczną pracę tam, gdzie ten sam model miałby kłopoty jako autonomiczny edytor. Ograniczeniem jest zakreślenie zadania: proś o klasy defektów, których linter nie zobaczy, i wymagaj dowodu w postaci plik:linia przy każdym znalezisku.
Jakiego modelu potrzebuję do lokalnego przeglądu kodu?
Devstral-2 22B na karcie 16 GB to praktyczna podłoga i wybór za rozsądne pieniądze. Qwen 3.6 27B na 24 GB to próg, na którym rozumowanie międzyplikowe robi się godne zaufania, a fałszywe alarmy zauważalnie spadają. Model 8B nadaje się do diffów w obrębie jednego pliku, ale przegapia wszystko, co wymaga kontekstu spoza hunka.
Jak powstrzymać recenzenta AI przed produkowaniem szumu?
Daj mu jawną listę „nie zgłaszaj”, obejmującą formatowanie, nazewnictwo i wszystko, co wyłapie linter; wymagaj plik:linia plus jednozdaniowego mechanizmu przy każdym znalezisku; blokuj wyłącznie przy wysokiej istotności; pracuj na niskiej temperaturze; i prowadź dziennik powracających fałszywych alarmów, który zawijasz z powrotem do promptu. Pięć prawdziwych znalezisk jest warte więcej niż czterdzieści.
Dlaczego mój agent przeglądający zgłasza rzeczy obsłużone gdzie indziej w tym samym pliku?
Bo ich nie widzi. Diff jest wycinkiem, a sprawdzenie na null często leży trzy linijki poza hunkiem. Poszerz diff (git diff --unified=15 albo więcej), przy zmianie obejmującej dużą część pliku wyślij cały plik, a przy zmianach sygnatury doklej miejsca wywołań. Szerokość kontekstu naprawia większość fałszywych alarmów wcześniej niż jakiekolwiek dostrajanie promptu.
Czy agent przeglądający powinien naprawiać znalezione problemy?
Nie — zostaw go w trybie tylko do odczytu. Recenzent, który jednocześnie edytuje, wykonuje dwa zadania naraz i traci własność, która czyniła go dobrym dopasowaniem do lokalnego modelu: ograniczoną pracę bez konsekwencji. Niech na znaleziskach działa człowiek albo osobna, odizolowana sesja edycyjna.
Czy da się to uruchomić w CI bez wysyłania kodu do dostawcy?
Tak. Albo daj kartę własnemu runnerowi, albo serwuj model z jednej wspólnej maszyny przez sieć runnerom, które karty nie mają. Znaleziska trafiają jako komentarze przy pull requeście, a żaden diff nie opuszcza twojej infrastruktury — dlatego przegląd bywa pierwszym zastosowaniem lokalnej AI, które organizacja zatwierdza.

Co dalej