Dokument AGENTS.md firmy Vercel uczy asystentów AI 70 najlepszych praktyk w React.
Praktyczny przegląd umiejętności Vercel react-best-practices agent, pokazujący, jak włącza 70 sprawdzonych w warunkach produkcyjnych zasad React bezpośrednio do kodu generowanego przez AI.
Kolega z zespołu platformy udostępnił link w wewnętrznym kanale Slack bez żadnego wyjaśnienia — tylko surowy adres URL i emoji w postaci wzruszenia ramion. Link prowadził do repozytorium vercel-labs/agent-skills, a konkretnie do umiejętności react-best-practices. Oczekiwano kolejnego artykułu typu „wskazówki dotyczące wydajności Reacta”, przerobionego pod aktualne trendy związane z sztuczną inteligencją. Okazało się jednak inaczej. Jest to zbiór 70 reguł podzielonych na 8 kategorii, który Vercel opisuje jako wynik ponad dekady obserwacji aplikacji React i Next.js w środowisku produkcyjnym, które awariiją w określonych sposób. Co istotne, został on stworzony przede wszystkim z myślą o asyście kodującej opartej na sztucznej inteligencji, a dopiero w drugiej kolejności dla programistów ludzkich.
To ujęcie stanowi właśnie sedno tego, co czyni to tak istotnym, i warto na nie zatrzymać się przed przejściem do samego treści reguł.
Co tak naprawdę znajduje się w repozytorium
Zainstalowanie tej umiejętności wymaga jednego polecenia:
npx skills add vercel-labs/agent-skills
W tle proces ten składa się do pliku AGENTS.md — to konwencja, która zyskuje na popularności jako sposób dostarczania ustrukturyzowanego kontekstu projektu agentom programistycznym (narzędzia takie jak Claude Code, Cursor, Codex i OpenCode wszystkie szukają tego pliku). Gdy już się pojawi, agent ma dostęp do książki zasad, do której może się odwoływać podczas pisania lub sprawdzania kodu, zamiast polegać wyłącznie na różnych tutorialach dotyczących Reacta, które przypadkowo znalazły się w jego danych treningowych.
70 reguł jest podzielonych na osiem kategorii, z których każda ma oznaczenie priorytetu od CRITICAL do LOW. Dwie kategorie oznaczone jako CRITICAL to, co oczywiste, te, które zespół Vercel wskazuje jako główne przyczyny problemów w praktyce: sekwencyjne operacje asynchroniczne tworzące efekt „wodospadu” oraz niekontrolowany wzrost rozmiaru pliku bundle. Typowa reguła z kategorii „wodospadu” przedstawia tę ideę w następujący sposób:
// Flagged: sequential awaits create a waterfall
async function getThreadPage(threadId) {
const thread = await getThread(threadId)
const author = await getAuthor(thread.authorId)
const replies = await getReplies(threadId)
return { thread, author, replies }
}
// Preferred: parallelize independent fetches
async function getThreadPage(threadId) {
const [thread, replies] = await Promise.all([
getThread(threadId),
getReplies(threadId),
])
const author = await getAuthor(thread.authorId)
return { thread, author, replies }
}
To wszystko nie jest niczym rewolucyjnym, jeśli spędziłeś czas na pracy z Reactem. Rzeczywiście interesujące jest nie samo treściowość reguły — lecz to, że reguła ta istnieje teraz w formie, którą maszyna może zinterpretować i stosować jednolicie we całym kodzie, nawet o 2 w nocy, przy pull requestu, który nikt dokładnie nie sprawdził, bez zmęczenia czy oszczędności, które pojawiają się pod presją terminu.
Dlaczego to różni się od lintera
Pierwszą reakcją jest zastanowienie się, czy nie jest to po prostu ESLint w innej oprawie. Pod pewnymi względami tak – ale to mechanizm odróżnia je od siebie. Linter wskazuje na problem po tym, jak kod już istnieje. Ten podejście ma na celu wpływanie na kod w trakcie jego tworzenia, wykrywając błędy zanim zostaną one w ogóle wpisane. Jeśli asystent AI odpowiada za od 30 do 60 procent różnic w danym pull request (a szacunki dotyczące tej liczby znacznie się różnią w zależności od osoby w zespole, do której się zwracamy), wbudowanie reguł bezpośrednio w proces generowania stanowi zupełnie inny rodzaj wpływu w porównaniu z wykrywaniem błędów a posteriori.
Istnieje również kategoria wskazówek, które linter po prostu nie nadaje się do wyrażenia: decyzje architektoniczne oparte na osądzie. Zasada taka jak „unikaj tworzenia struktury typu waterfall” jest przynajmniej w przybliżeniu czymś, co linter mógłby realizować przy odpowiedniej konfiguracji i tolerancji na błędne wyniki. Natomiast coś w rodzaju „ten komponent powinien prawdopodobnie stać się komponentem serwerowym, ponieważ nie ma żadnego interaktywnego zachowania, a granica klienta wokół niego wydaje się arbitralna” wymaga rzeczywistego rozumowania dotyczącego intencji i struktury — dokładnie tego rodzaju decyzji, w których chciałoby się zaufać agencie, a nie czegoś narzucanego poprzez dopasowywanie wzorców.
Gdzie pojawia się sceptycyzm
Warto bezpośrednio wskazać na nieprzyjemną kwestię. Zbiór zasad opracowany przez tę samą firmę, która tworzy framework, a której platforma hostingowa przypadkowo nagradza określone wzorce wydajności, nie jest domyślnie dokumentem neutralnym. Niektóre z wytycznych na poziomie CRITICAL dotyczących rozmiaru plików pakietowych zbyt idealnie pokrywają się z tymi wzorcami, które sprawiają, że własne panele analityczne Vercel oraz rozwiązania cache’owania działają doskonale. To pokrywanie się nie oznacza automatycznie, że te porady są złe. Unikanie struktur typu async waterfall to solidna praktyka inżynieryjna, niezależnie od tego, kto serwuje aplikację. Mimo to warto pamiętać, że „najlepsze praktyki” opracowane przez dostawcę nigdy nie są czysto technicznymi rozwiązaniami – zawsze jest w nich domieszka elementów marketingowych obok porad inżynieryjnych.
Drugi problem ma charakter bardziej strukturalny: co się stanie, gdy 70 reguł przekształci się w 200, albo gdy umiejętności od konkurencyjnych dostawców zaczną trafiać do tego samego pliku AGENTS.md i wzajemnie się sprzeczać? Obecnie, przy jednym repozytorium i zupełnie nowym podejściu, wszystko wydaje się uporządkowane i łatwe do zrozumienia. Jednak po osiemnastu miesiącach łatwo jest sobie wyobrazić, że każda platforma, każdy dostawca hostingu oraz każdy system projektowy będzie chciał mieć zainstalowane własne umiejętności. W takiej sytuacji agent mógłby musiał radzić sobie z serią książek z regułami zawierającymi sprzeczne wskazówki, a nie będzie oczywistego sposobu, by określić, która z nich powinna przeważyć.
Testowanie w rzeczywistym kodzie
Z ciekawości, a nie z konieczności, umiejętność ta została wypróbowana na średniej wielkości wewnętrznym panelu kontrolnym, aby zobaczyć, co faktycznie ujawni. Stwierdzenia o krytycznym i wysokim stopniu znaczenia okazały się dość błahe: kilka sekwencyjnych wywołań await, które mogłyby zostać wykonane równolegle, kilka komponentów klienckich, które nie miały rzeczywistego powodu, by nimi być, oraz jeden dość żenujący przypadek użycia całej biblioteki do obsługi dat tylko po to, by sformatować pojedynczą wartość. Nic z tego nie zdziwiłoby osoby, która już przeprowadziła dokładną analizę wydajności kodu napisanego w React. Rzeczywiście uderzająca była szybkość – agent potrzebował około czterech minut, aby znaleźć i zaznaczyć wszystkie te problemy, podczas gdy człowiek zajmujący się przeglądaniem potrzebowałby znacznie więcej czasu, by dostrzec te same błędy rozproszone w dużym wniosku o zmiany.
Różnica w szybkości jest właśnie główną wartością, którą tutaj oferujemy. Same zasady nie są przełomowe – większość doświadczonych inżynierów posiada tę wiedzę już instynktownie. Zmienia się to tym, że zasady są teraz stosowane z taką spójnością i tempem, jakiego człowiek sprawdzający, zwłaszcza ten, który jest już przy trzeciej weryfikacji dnia, po prostu nie jest w stanie utrzymać.
Niedoceniona korzyść: nauczanie, a nie tylko egzekwowanie
To, co naprawdę zmieniło podejście do analizy kodu, to nie same sprawdzania wydajności — lecz obserwowanie tego, jak nowy członek zespołu korzysta z narzędzia. Ta osoba była w zespole zaledwie kilka miesięcy i wciąż zapoznawała się z bazą kodu. Zanim otworzyła prośbę o połączenie zmian, poprosiła swojego agenta o jej wstępną ocenę. Agent zauważył wzorzec typu „waterfall” i zamiast go jedynie oznaczyć, wyjaśnił prostym językiem — bezpośrednio powiązując to z konkretną zasadą — dlaczego wykonywanie tych operacji równolegle ma znaczenie w tym konkretnym kontekście. To zupełnie inna sytuacja niż w przypadku narzędzia do wykrywania błędów, które podaje tylko identyfikator zasady i krótką wiadomość, którą trzeba potem osobno szukać. Było to bardziej podobne do komentarza od doświadczonego inżyniera, który naprawdę pomaga w ocenie kodu, z tą różnicą, że informacje te trafiły jeszcze przed tym, jak prośba o połączenie zmian opuściła fazę projektu.
To może być bardziej przekonujący przypadek zastosowania w tym kontekście niż stwierdzenie „sztuczna inteligencja pisze lepszy kod”. Jest to bliższe koncepcji „sztuczna inteligencja uczy lepszych nawyków”, w sposób ciągły i bez konieczności poświęcania czasu na mentoring lub tworzenie dokumentacji wprowadzającej, która po sześciu miesiącach staje się przestarzała. Czy ta korzyść będzie istnieć, gdy zespół będzie miał zainstalowane pięćdziesiąt nakładających się plików z umiejętnościami — każdy z własnymi opiniami, z których niektóre nieuchronnie będą się sprzeczać — pozostaje otwartym pytaniem. Jednak dla małego zespołu składającego się z jednego doświadczonego inżyniera i kilku osób, które wciąż szukają swojej drogi, wydaje się to już prawdziwym wzmacniaczem efektywności.
Jak to wygląda obecnie
Ta umiejętność trafiła do wspólnej konfiguracji zespołu, głównie dlatego, że jej wady są minimalne, a zalety – agent, który przestaje pisać kod w stylu „waterfall” – stanowią rozsądny kompromis. Czy ten model stanie się standardowym sposobem, w jaki frameworki przekazują swoje zasady agentom AI, czy też po prostu stanie się kolejnym plikiem konfiguracyjnym, który cicho ulega zepsuciu po ustaniu nowości i gdy nikt nie zajmie się jego aktualizacją, jest jeszcze niejasne. To pytanie warto ponownie rozważyć za sześć miesięcy, a nie odpowiadać na nie teraz.
Literatura pokrewna
- Wnętrze przepisania TypeScript 7 na Go: szybsza kompilacja bez zmian w kodzie — Dowiedz się, jak kompilator TypeScript 7 oparty na Go zapewnia 8–12 razy szybszą kompilację, dlaczego ta zmiana architektury jest skuteczna oraz jak bezpiecznie aktualizować istniejące projekty.