Komentarz pod ostatnim wpisem dał mi do myślenia: gdzie kończy się AI, a zaczyna analiza statyczna? Tak rysuję tę granicę — na podstawie systemu, którego używam na produkcji.

Kolega zostawił komentarz pod moim ostatnim wpisem, który nie schodzi mi z głowy:
"Część z tych zadań można w pełni zautomatyzować bez AI. Analiza statyczna kodu radzi sobie z wieloma rzeczami — od prostego dopasowywania wzorców po testy architektoniczne."
Ma rację. I właśnie o to chodzi.
Większość dyskusji na temat AI w procesach inżynierskich stawia sprawę jako wybór: AI albo analiza statyczna? To złe ujęcie.
Prawidłowe pytanie to to samo, które zadaję, dobierając modele w moim systemie wieloagentowym:
Jaki rodzaj myślenia jest naprawdę potrzebny do tego zadania?
AI i analiza statyczna nie są konkurentami. Rozwiązują różne problemy. Łączenie ich w jedną kategorię to prosta droga do odrzucenia AI w całości — albo, co gorsza, używania jej tam, gdzie wystarczyłby linter, który zrobi to w milisekundy za darmo.
Dopasowywanie wzorców na dużą skalę, deterministycznie, bez halucynacji.
| Zadanie | Narzędzie |
|---|---|
Egzekwowanie konwencji importów (<Link> zamiast <a>) | Reguła ESLint |
| Naruszenia konwencji nazewnictwa | ESLint / reguła niestandardowa |
| zmienne, martwy kod | Analiza statyczna |
| architektoniczne (np. ArchUnit, Dependency Cruiser) | |
| Kompilator TypeScript | |
| lintera |
Te zadania mają jedną wspólną cechę: odpowiedź nie zależy od kontekstu. Albo import jest zły, albo nie. Albo zmienna jest nieużywana, albo nie. Nie potrzeba tu rozumowania.
Dla takich zadań analiza statyczna jest szybsza, tańsza, bardziej niezawodna i w pełni deterministyczna. Nie ma powodu, by angażować AI.
Będę szczery: w moim systemie trzech z dziewięciu agentów — Standardy TypeScript, Style i CSS oraz Egzekutor Komponentów Storybook — działa na Haiku, dokładnie dlatego, że ich zadaniem jest dopasowywanie wzorców. Nie rozumują. Dopasowują. I gdybym mógł zastąpić część ich pracy dobrze napisaną regułą ESLint, zrobiłbym to. Część tej pracy prawdopodobnie powinna być linterem.
Mur pojawia się w momencie, gdy odpowiedź zależy od kontekstu.
Oto prawdziwy przykład z mojego agenta bezpieczeństwa:
Funkcja przeszła wszystkie reguły ESLint. Żadnego any. Żadnych brakujących
sprawdzeń null. Czyste typy na każdym kroku. Analiza statyczna nie miała nic
do zgłoszenia.
Ale dane z niezwalidowanego formularza płynęły — przez dwie warstwy abstrakcji — prosto do surowego zapytania.
Linter widzi węzeł. Agent AI widzi ścieżkę.
"Czy to wektor XSS?" to nie pytanie binarne. Odpowiedź zależy od tego, jak ta wartość została wygenerowana, skąd pochodzi i co dzieje się z nią dalej. To wymaga rozumowania — i właśnie to robi Sonnet w moim agencie bezpieczeństwa.
Ta sama logika dotyczy:
Żadne z tych pytań nie ma binarnej odpowiedzi. Wszystkie wymagają kontekstu. Analiza statyczna nie pomoże tutaj.
Aby uczynić to konkretnym — oto trzy rzeczy, które moje agenty wychwyciły ostatnio, a żaden linter by ich nie złapał:
Algorytm, który działał dobrze dzisiaj, ale by się zawiesił przy większej skali Pętla wyszukiwania, która radziła sobie z obecnymi danymi bez problemów, ale zawaliłaby się, gdyby zbiór danych podwoił swoją wielkość. Agent Algorytmów i Wydajności zgłosił złożoność obliczeniową. ESLint nie miał nic do powiedzenia — kod był syntaktycznie poprawny.
Nowy hook napisany od zera — mimo że prawie identyczny już istniał w bazie kodu Mamy współdzielone hooki w projekcie, które obsługują np. filtry. Deweloper napisał całkiem nowy hook obok nich, robiący praktycznie to samo. Agent Ponownego Użycia Kodu rozpoznał duplikację między plikami. Linter widzi poszczególne pliki w izolacji. Agent widzi całą bazę kodu.
Łańcuch operatorów warunkowych (ternary), który był technicznie poprawny, ale bolesny w utrzymaniu Trzy poziomy zagnieżdżenia, perfekcyjnie typizowane, czyste dla ESLint. Agent React zgłosił to jako problem czytelności, który spowolni każdego przyszłego recenzenta. Analiza statyczna może mieć reguły dla zagnieżdżonych operatorów warunkowych, ale dostrojenie ich, by nie zgłaszały każdego krótkiego ternary, jest trudne. Agent może użyć osądu.
Teraz myślę o narzędziach w ten sposób: | Typ pytania | Narzędzie | Dlaczego? | |------------------------------------------|-----------------------------|----------------------------------------| | Binarne — dobre/źle, bez kontekstu | Analiza statyczna / linter | Deterministyczne, szybkie, darmowe | | Dopasowywanie wzorców o znanych kształtach | Agent klasy Haiku lub linter | Tanie, wystarczająco dokładne | | Rozumowanie zależne od kontekstu | Agent klasy Sonnet | Wymaga zrozumienia relacji | | Syntetyzowanie przekrojowo | Orkiestrator (Opus) | Wymaga dużego kontekstu i osądu |
W momencie, gdy łapię się na pisaniu promptu AI do czegoś, co mogłoby być regułą ESLint, to sygnał. Nie że AI jest zła — ale że używam złego narzędzia.
Mój system ma dziewięciu agentów i bazę kodu z ESLint, Prettier, TypeScript w trybie strict, Stylelint i Dependency Cruiser, które uruchamiają się przy każdym commicie. Nie kłócą się ze sobą — pokrywają różne warstwy.
To ta sama logika, co dobór modeli. Nie używaj senior architekta do sprawdzania nazw zmiennych. Nie używaj agenta AI do egzekwowania konwencji importów.
Dopasuj koszt myślenia do złożoności zadania.
Addy Osmani argumentuje w Code Review in the Age of AI, że prawidłowo skonfigurowani AI recenzenci łapią 70–80% niskowiesłych błędów, uwalniając ludzi do skupienia się na architekturze i intencji. Martin Fowler nazywa szerszą koncepcję harness engineering — łączeniem deterministycznych narzędzi z agentami AI wokół samego modelu.
Obaj podkreślają to samo: warstwy, a nie zastępowanie.
Jeśli budujesz system AI do recenzji kodu — lub jakiekolwiek narzędzie oparte na agentach — sugerowałbym zaudytować swoich agentów w ten sposób:
Czy to znalezisko można wyrazić jako regułę lintera? Jeśli tak, napisz regułę zamiast tego.
Czy odpowiedź zależy od kontekstu poza obecnym plikiem? Jeśli tak, prawdopodobnie potrzebujesz agenta.
Czy twój agent zgłasza rzeczy, które złapałby grep? To sygnał, że
twój prompt jest zbyt ogólny.
Agenci, które generują najwięcej wartości w moim systemie, to ci, którzy łapią rzeczy, których żadne inne narzędzie nie złapie. To jest standard, jaki im stawiam.
Analiza statyczna nie jest konkurencją. To fundament.
Ten wpis jest częścią serii o budowaniu wieloagentowego systemu AI do recenzji kodu z Claude Code:
Czy ten wpis był pomocny?