Co skrypty AI zepsuły na naszej stronie: 8 defektów z liczbami

Co skrypty AI zepsuły na naszej stronie: 8 defektów z liczbami

Ostatnio zweryfikowano: 29 września 2026
10 min czytania
Case study
Techniczne SEO
Integracja AI

Każdy z ośmiu defektów opisanych niżej przeszedł przez skrypt albo agenta, który zakończył pracę komunikatem o sukcesie. Żaden nie rzucił wyjątku. Wszystkie trafiły na produkcję wielojęzycznej strony, którą budujemy i utrzymujemy od lat, i wszystkie znaleźliśmy dopiero wtedy, gdy zaczęliśmy porównywać wynik z czymś innym niż raport samego narzędzia.

W skrócie: między sierpniem a wrześniem 2026 masowe przebiegi AI wstawiły na naszą stronę 22 202 akapity wypełniacza, zniszczyły nagłówek, zostawiły 358 angielskich zdań na stronach w pięciu innych językach i 518 niepoprawnych niemieckich złożeń. Agenci piszący strony miast dopisali zmyślone case studies i 30 linków do stron, które nie istnieją. Opisujemy mechanizm każdego defektu i bramkę, która łapie go dzisiaj.

Piszemy to o własnej stronie, bo tylko tu mamy pełne dane: commit, liczbę plików, stan przed i po. Search Engine Land opublikował w tym tygodniu tekst o dziesięciu sposobach, na jakie Claude może wykoleić SEO, jeśli nie sprawdza się jego pracy. To jest wersja z paragonami.

#Skala i kontekst

wppoland.com działa na Astro i jest budowana statycznie w sześciu językach: polskim, angielskim, niemieckim, norweskim, portugalskim i hiszpańskim. Ostatni build produkcyjny z 29 września 2026 wygenerował 13 733 strony. Treść powstaje i jest poprawiana przez agentów kodujących oraz przez skrypty Node, które przechodzą przez tysiące plików naraz. Mamy ponad 70 bramek jakości w CI i lokalnie.

Mimo to każdy z opisanych defektów przeszedł przez wszystkie bramki. Powód jest za każdym razem ten sam i wracamy do niego na końcu.

DefektCo trafiło na produkcjęJak to znaleźliśmyBramka dzisiaj
Dopychanie do liczby słów22 202 akapity w 873 plikach59 kopii jednego akapitu na żywej stroniecheck:no-batch-filler
Wypełniacz stron miast7567 bloków w 2621 plikachNumerowane nagłówki “Ateny (1)” do “Ateny (26)“ta sama, rozszerzona na miasta
Regex cen1 zniszczony nagłówekSkaner sklejonych słówcheck:glued-words
Tłumaczenie tylko spójników358 angielskich zdań w 104 plikachPorównanie z angielskim odpowiednikiemdetektor oparty na wpId
Zamiana terminu bez złożeń518 złożeń w 356 plikachRęczny odczyt stronywyszukiwanie klasy, nie literału
Zmyślone case studies13 stron, 30 martwych linkówPrzegląd agentów przed publikacjąwalidacja linków wewnętrznych
Deploy, który rozgrzał stary cache5 z 6 stron głównych ze starą treściąPorównanie treści, nie kodów HTTPdrugi purge po smoke teście
Pogłębianie, które podmieniało treść142 do 206 elementów na commitPorównanie z poprzednią wersją plikucheck:element-loss

#1. Dopychanie do liczby słów: 22 202 akapity

Nasze wytyczne redakcyjne mówią, że wpis na blogu ma około 2500 słów. To była wskazówka dla człowieka. Seria skryptów wsadowych potraktowała ją jak cel do spełnienia i dopychała krótsze teksty wygenerowanym wypełniaczem.

Efekt, zmierzony przy sprzątaniu 29 sierpnia: 22 202 numerowane akapity typu “Notatka wdrożeniowa 47” w 873 plikach, do 60 identycznych kopii w jednym wpisie, plus 4 144 szablonowe sekcje rotowane z puli pięciu na język. Dwie z tych sekcji były wewnętrznymi instrukcjami redakcyjnymi, opublikowanymi jako treść artykułu. Na żywej stronie o aktualizacjach bezpieczeństwa WordPressa ten sam akapit stał 59 razy.

Skrypt nie miał błędu. Robił dokładnie to, o co go poproszono: podnosił liczbę słów. Błąd był w tym, że liczbę słów, miarę pomocniczą, uznano za cel.

Bramka dzisiaj: check:no-batch-filler w każdym przebiegu npm run check. Pierwsza wersja szukała literałów generatora i przepuściła wypełniacz, który wrócił z innym tekstem. Obecna patrzy na kształt: ten sam nagłówek drugiego poziomu trzy razy w jednym pliku to błąd, niezależnie od słów.

#2. Strony miast: ten sam wypełniacz, inny katalog

Kolekcję stron miast przez tygodnie omijała każda bramka, bo żadna jej nie skanowała. Przebiegi 11 do 14 dopychały te strony do 2200, a potem 2500 słów. Przy sprzątaniu 30 sierpnia usunęliśmy 7567 numerowanych bloków i około 21 tysięcy powtórzonych sekcji z 2621 plików. Strona /pl/woocommerce-programista-ateny/ podawała sekcje od “Ateny (1)” do “Ateny (26)”.

Gorzej: jeden z przebiegów dopisywał bloki po hiszpańsku do każdego języka poza norweskim. Polskie, niemieckie i portugalskie strony miast miały sekcje “Entrega y seguimiento”.

Druga lekcja przyszła przy usuwaniu. Pierwsza wersja skryptu czyszczącego porównywała całe literały i zgłosiła sukces, zostawiając 9642 sekcje, bo późniejsze skrypty naprawcze poprawiły ten wypełniacz na miejscu (na przykład hiszpańską odmianę rodzaju w 1506 plikach). Dokładne porównanie bajtów nie widziało żadnego bloku, którego dotknął naprawiacz. Teraz dopasowujemy nagłówek plus pierwsze cztery słowa.

Po usunięciu wypełniacza 724 strony spadły poniżej progu 2000 słów. Sprawdziliśmy je w Google Search Console, zanim cokolwiek zdecydowaliśmy: tylko 2 miały jakiekolwiek kliknięcie w 90 dni, 575 miało zero wyświetleń. 723 przenieśliśmy na noindex, zamiast dopychać je z powrotem.

#3. Regex cen, który zjadł nagłówek

Strony usług nie podają cen poza cennikiem, więc skrypt zamieniał kwoty w złotych na “wycena indywidualna”. Regex dopasowywał “zł” bez rozróżniania wielkości liter i bez granicy słowa po nim.

Na polskiej stronie audytu bezpieczeństwa nagłówek “2. Złośliwe przekierowania” wyglądał dla tego regexa jak cena “2. Zł”. Na produkcji stał jako “wycena indywidualna ośliwe przekierowania”. Ten sam regex siedział w drugim skrypcie, od cen na stronach miast.

Znaleźliśmy to przypadkiem, budując skaner nagłówków ze sklejonymi słowami, który przy tej samej okazji wykrył 13 nagłówków bez spacji przed przyimkiem (“Is AMP deadin 2026?”). Poprawka to negatywne dopasowanie wprzód w obu skryptach. W całym korpusie ofiarą padł jeden nagłówek, ale był to nagłówek strony sprzedażowej.

#4. Tłumaczenie, które zamieniało tylko spójniki

Pole faktów (llmCard) wyświetla się widocznie pod artykułami i trafia do danych dla modeli językowych. Na stronach w pięciu językach innych niż angielski 358 takich zdań było po angielsku, w 104 plikach. Część była przetłumaczona w połowie: dawny skrypt zamienił tylko spójnik, więc niemiecka strona portfolio pisała “Contact und inquiry forms”, a polska “granite, conglomerate, i marble countertops”.

Najciekawsze było wykrywanie. Pierwszy detektor, oparty na udziale angielskich słów funkcyjnych, znalazł 172 zdania. Agenci tłumaczący sami zgłosili, że w tych samych plikach zostały inne angielskie zdania, i mieli rację. Drugi przebieg porównywał każde zdanie z faktami angielskiego odpowiednika tej samej strony (to samo wpId). Bez dodatkowego filtra zwracał 4004 trafienia, głównie listy technologii na stronach miast i norweskie “for”. Z wymogiem co najmniej dwóch angielskich słów funkcyjnych zostało 170 prawdziwych. Ostatnie 12 poprawiliśmy ręcznie.

Każde z pięciu tłumaczeń sprawdziliśmy skryptem, nie raportem agenta: w każdym pliku zmieniły się tylko wskazane pozycje, każda liczba przetrwała, nie ma długich myślników.

#5. Zamiana terminu, która nie znała złożeń

Przebieg ujednolicający słownictwo zamienił niemiecki termin na “laufende Betreuung”. Nie obsłużył złożeń, więc strony pisały “laufende Betreuung-Commitments”, “laufende Betreuung-Übergabe” i “Wartungs-laufende Betreuung”. To nie jest niemiecki. Razem 518 wystąpień w 356 plikach, wszystkie na stronach indeksowanych.

Pozycja w naszym backlogu miała komendę weryfikującą, która szukała tylko formy z łącznikiem po terminie. Poprawienie dokładnie tego, co wskazała, zmieniłoby ją na zieloną i zostawiło 157 złożeń w drugiej formie w 118 plikach. Szukaliśmy więc klasy defektu (dowolny łącznik stykający się z terminem), a nie literału, który ktoś wpisał do zadania.

Metoda naprawy była prosta: 497 z 518 wystąpień pochodziło z czterech zdań szablonowych. Każde przepisaliśmy raz, ręcznie, poprawnym niemieckim (“Übergabe in die laufende Betreuung”, “Wartungsbetreuung”) i podmieniliśmy jako dokładne zdanie. Pozostałe 21 poprawialiśmy pojedynczo.

#6. Agenci, którzy zmyślają referencje

Trzynaście kuratorskich stron miast napisali agenci. Przegląd przed publikacją, 26 sierpnia, znalazł w nich sekcje “Case Study 1: Dystrybutor B2B z Bielan Wrocławskich” z precyzyjnymi liczbami: +52% zapytań, LCP z 4,5 s do 0,7 s, 100/100 w PageSpeed. Żaden z tych klientów nie istnieje. Te same liczby siedziały też w polu faktów i w danych speakable, nie tylko w treści.

Do tego sekcje “Inne lokalizacje” linkowały do miast, które zgadywano geograficznie: Lubeka, Kilonia, Ratyzbona, Girona, Tromsø. 30 martwych linków w 8 plikach.

Tego nie łapie żadna bramka tekstowa, bo zmyślone case study jest poprawne składniowo. Łapie to reguła procesu: agent dostaje w poleceniu listę istniejących adresów, a każde twierdzenie liczbowe o kliencie wymaga źródła w repozytorium albo znika.

#7. Deploy zakończony sukcesem, produkcja ze starą treścią

Skrypt wdrożeniowy 8 września zakończył się czysto: wgranie, czyszczenie cache, smoke test 81/81 OK, kod wyjścia 0. Na żywej stronie pięć z sześciu stron głównych pokazywało stare kafle.

Kolejność była: wgranie, purge, 8 sekund przerwy, smoke test. Cloudflare Pages nie zdążył aktywować nowego wdrożenia, więc 81 zapytań testu trafiło w poprzedni build i wypełniło nim cache na godzinę. Krok weryfikacyjny unieważnił purge, który wykonano chwilę wcześniej. Żaden sygnał nie był fałszywy. Żaden nie mierzył tego, co poszło źle: test sprawdzał kody HTTP, nie treść.

Dzisiaj: skrypt czyści cache drugi raz, po teście, a wdrożenie potwierdzamy frazą z konkretnej zmiany na żywej stronie, z parametrem omijającym cache.

#8. Pogłębianie, które podmieniało treść

Przebiegi “pogłębiające” krótkie wpisy miały dopisywać treść. W praktyce część z nich podmieniała całe ciało artykułu. Dziewięć wpisów przywracaliśmy z historii gita.

Po tym zbudowaliśmy bramkę, która porównuje każdy zmieniony plik z jego wersją bazową i zgłasza utratę elementu: tabeli, komponentu, iframe, obrazu, bloku kodu, pytania FAQ, kroku howTo, linku wewnętrznego. Puszczona wstecz po ostatnich 60 commitach z treścią oznaczyła każdy przebieg pogłębiania od 128 do 185, z których każdy gubił od 142 do 206 elementów, w tym tabele, osadzone wideo i bloki kodu.

Pierwsza wersja tej bramki rozpoznawała nagłówki po tekście. Na bieżącej gałęzi zgłosiła 17 utraconych nagłówków i wszystkie 17 były naprawami: rozdzielone sklejone słowa, przywrócony zjedzony nagłówek. Zmiana nazwy to nie utrata. Nagłówki, linki i FAQ liczymy więc ilościowo, a tożsamość zostawiamy tylko obrazom, komponentom i iframe.

#Wspólny mechanizm: sukces z perspektywy narzędzia

Wszystkie osiem przypadków ma ten sam kształt. Narzędzie mierzyło to, co samo zrobiło, i na tej podstawie zgłaszało sukces. Skrypt dopychający mierzył liczbę słów. Skrypt czyszczący mierzył, czy znalazł swoje literały. Weryfikacja z backlogu mierzyła jedną formę złożenia. Smoke test mierzył kody HTTP.

Każdy defekt znaleźliśmy dopiero wtedy, gdy wynik porównaliśmy z czymś zewnętrznym:

  • z poprzednią wersją tego samego pliku (utracone tabele i sekcje),
  • z odpowiednikiem w innym języku (angielskie zdania na stronach niemieckich),
  • z żywą stroną zamiast z logiem wdrożenia (stary cache),
  • z klasą defektu zamiast z literałem z zadania (druga forma złożeń),
  • z danymi o popycie (723 strony miast bez jednego wyświetlenia).

Z tego wynika praktyczna reguła, którą stosujemy od września: raport agenta albo skryptu to hipoteza. Wynik sprawdza osobny skrypt, który nie wie, co narzędzie zamierzało zrobić, i porównuje stan przed ze stanem po.

#Co zmieniłbym przed pierwszym przebiegiem masowym

  1. Żadnego celu liczbowego dla skryptu, który pisze prozę. Liczba słów, liczba linków i liczba FAQ to miary do czytania, nie do spełniania.
  2. Bramka porównująca z poprzednią wersją pliku przed pierwszym commitem wsadowym, nie po trzydziestym.
  3. Każdy regex na tekście testowany na nagłówkach i na słowach z polskimi znakami, bo “Zł” jest początkiem wielu słów.
  4. Tłumaczenia weryfikowane porównaniem z odpowiednikiem w języku źródłowym, nie listą słów.
  5. Komenda weryfikująca zadanie szuka klasy defektu. Jeśli zadanie nazywa jeden przykład, szukaj też jego wariantów.
  6. Wdrożenie potwierdzone treścią na żywej stronie, w każdym języku.

#Czego ten tekst nie dowodzi

Nie twierdzimy, że te defekty kosztowały nas ruch, bo tego nie zmierzyliśmy w sposób, który by to rozstrzygał. Część stron z wypełniaczem nie miała wyświetleń także przed nim.

Wrześniowa aktualizacja Google dotycząca spamu ruszyła 25 września 2026 i ma trwać około dwóch tygodni. Według podsumowania Search Engine Roundtable z 28 września uderzyła w strony programatyczne i treści generowane przez AI, a Google w tym samym tygodniu opublikował pracę o systemie SAFE do wykrywania masowego “AI slop”. Nasze strony miast to dokładnie ta kategoria. Odczyt w Search Console, osobno dla stron miast, bloga i stron usług, zrobimy po zakończeniu aktualizacji i opiszemy go, niezależnie od wyniku.

Ostatnia uwaga dotyczy nas samych: ten tekst też powstał z pomocą agenta. Każda liczba w nim pochodzi z commita albo z pomiaru w naszym repozytorium i przeszła przez te same bramki, które tu opisujemy.

Następny krok

Przekuj artykuł w realne wdrożenie

Pod tym wpisem dokładam linki, które domykają intencję użytkownika i prowadzą dalej w strukturze serwisu.

Chcesz wdrożyć ten temat na swojej stronie?

Jeśli zależy Ci na widoczności w Google i systemach AI, mogę przygotować architekturę treści, FAQ, schema i linkowanie pod GEO, AEO i SEO.

Powiązany klaster

Sprawdź inne usługi WordPress i bazę wiedzy

Wzmocnij swój biznes dzięki profesjonalnemu wsparciu technicznemu w kluczowych obszarach ekosystemu WordPress.

Czy AI może zepsuć SEO strony, jeśli każdy krok kończy się sukcesem?#
Tak, i u nas tak właśnie było. Skrypt dopychający teksty do liczby słów, skrypt usuwający ceny i agent tłumaczący kończyły pracę bez błędu, a na produkcję trafiły 22 202 akapity wypełniacza, zniszczony nagłówek i 358 angielskich zdań na stronach w innych językach. Narzędzie raportuje sukces ze swojej perspektywy, a nie z perspektywy strony.
Jak wykryć tekst angielski, który został na stronach tłumaczonych?#
Lista słów wystarcza tylko na część. Pierwszy detektor oparty na udziale angielskich słów funkcyjnych znalazł u nas 172 zdania z 358. Resztę znaleźliśmy, porównując każde zdanie z angielskim odpowiednikiem tej samej strony (ten sam wpId) i wymagając co najmniej dwóch angielskich słów funkcyjnych, bo samo podobieństwo łapało też listy nazw technologii.
Jaka bramka łapie treść, którą skrypt po cichu usunął?#
Porównanie pliku z jego poprzednią wersją. Nasza bramka check:element-loss liczy tabele, komponenty, iframe, obrazy, bloki kodu, pytania FAQ i kroki howTo w wersji bazowej i w nowej, i zgłasza każdy spadek. Puszczona wstecz po 60 commitach oznaczyła każdy przebieg pogłębiania treści, który gubił od 142 do 206 elementów na commit.
Czy strony miast generowane masowo można utrzymać w indeksie?#
Tylko te, które mają własną treść i dowód popytu. Po usunięciu wypełniacza 724 strony miast spadły poniżej naszego progu 2000 słów. Z nich tylko 2 miały jakiekolwiek kliknięcie w 90 dni, a 575 zero wyświetleń, więc 723 przenieśliśmy na noindex zamiast dopychać je z powrotem.

Potrzebujesz FAQ dopasowanego do branży i rynku? Przygotujemy wersję pod Twoje cele biznesowe.

Porozmawiajmy

Polecane artykuły

Czyszczenie treści AI-slop

Diagnostyka YMYL dla WordPress: fałszywe statystyki, zmyślone cytowania, zduplikowane strony AI, błędne daty i wymyślone biogramy zespołu, zanim zniszczą zaufanie, zgodność lub cytowania w AI.

Generatywna AI w Search Console

Nowa sekcja Generatywna AI w Google Search Console pokazuje wyświetlenia z AI Overviews i AI Mode. Co dokładnie mierzy, czego nie pokazuje i jak czytać te dane, żeby nie wyciągać z nich fałszywych wniosków.