Branża sprzedaje raporty widoczności w AI liczone z nagłówka, którego nikt nie sprawdza. Ten nagłówek nazywa się User-Agent i jest deklaracją, nie tożsamością — wpisać można w niego cokolwiek. Poniżej pomiar z realnej strony: ile żądań podających się za bota AI naprawdę przyszło z sieci operatora, pod którego się podawało.
Ta strona jest częścią portalu o serowarstwie domowym, a licznik powstał z praktycznego powodu: chcieliśmy sprawdzić, czy modele językowe czytają nasze przepisy i bazę kultur. Odpowiedź o botach wyszła ciekawsza, niż zakładaliśmy, i została tutaj. Reszta serwisu to baza 188 kultur bakteryjnych z polskich sklepów, przeliczona na koszt litra mleka, przepisy na sery krok po kroku i prawo RHD i MOL dla małych gospodarstw.
Spośród żądań, które dało się rozstrzygnąć, prawdziwe było 71,2%. Licząc wszystkie, także te, których rozstrzygnąć się nie da — 20,4%. Stan na 21 października 2026, godz. 14:01 UTC.
Podajemy obie liczby, bo mianownik zmienia wynik radykalnie, a strona o rzetelności pomiaru nie może opublikować liczby, której czytelnik nie odtworzy sam. Pierwsza mówi: z żądań, o których wiemy, ile było prawdziwych. Druga: z całego ruchu, licząc nierozstrzygalne jako niepotwierdzone.
| Kategoria | Żądań | Co to znaczy |
|---|---|---|
| oryginalne | 10 677 | bot był tym, za kogo się podawał |
| fałszowane | 4 323 | ktoś obcy użył jego nazwy |
| niesprawdzone | 37 423 | operator nie publikuje danych pozwalających rozstrzygnąć |
| razem | 52 423 | bez testów właściciela — te liczymy osobno niżej |
To najczęstsza reakcja na tę stronę i trzeba ją potraktować poważnie, bo jest rozsądna: panele hostingowe pokazują ruch botów AI od dawna, więc po co liczyć to samo drugi raz.
Po to, że one liczą deklaracje. 3 września 2026 sprawdziliśmy, ile taki licznik jest wart. Dwa żądania wysłane zwykłym poleceniem curl z polskiego łącza, z nagłówkiem podającym się za PerplexityBota, podbiły w panelu Cloudflare licznik „AI Answer retrievals" z 16 na 18, a samego Perplexity z 5 na 7. Żadne z tych dwóch żądań nie przyszło od Perplexity.
Nie trzeba nam wierzyć — to zajmuje dwie minuty i można powtórzyć na własnej domenie. Wystarczy jedno polecenie z podmienionym nagłówkiem i spojrzenie w panel przed i po.
To nie jest zarzut o nieuczciwość. Sprawdzenie tożsamości kosztuje zapytania sieciowe przy każdym żądaniu, a przyjęcie deklaracji jest darmowe — przy skali takiego dostawcy to realna różnica. Skutek jest jednak taki, że licznik mierzy, co bot o sobie napisał, a nie kto naprawdę przyszedł. W naszym pomiarze rozjazd wynosi 28,8% wśród żądań, które dało się rozstrzygnąć.
Pada też regularnie, że to kwestia konfiguracji — że trzeba „oddać domenę w całości". Nie w tym rzecz: ten serwis stoi za Cloudflare w stu procentach i panel dalej przypisuje żądanie operatorowi na podstawie samego podpisu.
Nie trzeba nam wierzyć na słowo. Na stronie interaktywnej jest generator, który składa gotowe polecenie dla podanej domeny; tutaj wersja z adresem zastępczym. Wyśle ona na Twoją własną stronę dwa żądania podpisane jako PerplexityBot:
curl -s -o /dev/null -w "%{http_code}
" -A "Mozilla/5.0 (compatible; PerplexityBot/1.0; +https://perplexity.ai/perplexitybot)" https://twoja-domena.pl/
Zapisz najpierw obecną wartość licznika ruchu AI w swoim panelu, uruchom polecenie dwa razy, odczekaj kilka minut i odśwież.
Co powinieneś zobaczyć: nic. Żadne z tych żądań nie przyszło od Perplexity — przyszły z Twojego własnego komputera. Co zobaczysz: licznik wyższy o dwa, przypisany do Perplexity.
Uruchamiaj to wyłącznie na stronie, którą sam prowadzisz. Dwa żądania nikomu nie zaszkodzą, ale wysyłanie podrobionych podpisów pod cudze serwery to już nie jest sprawdzanie, tylko dokładanie się do problemu.
Bo nie umiemy sprawdzić, czy podana domena należy do osoby, która ją wpisała. Gdyby to pole wysyłało żądania z naszego serwera, każdy mógłby wpisać cudzy adres i pod cudzą stronę poleciałby podrobiony ruch — z naszego adresu.
To jest ten sam problem, o którym jest cała ta strona. Nie możemy zweryfikować tożsamości, więc nie działamy na podstawie samej deklaracji. Panele statystyk stoją przed dokładnie tym samym pytaniem — i odpowiadają na nie inaczej.
Wystarczał i nadal wystarcza — do liczenia. Narzędzia rozbijające ruch po nagłówku User-Agent istnieją od lat dziewięćdziesiątych i robią to dobrze. Różnica nie polega na tym, że liczymy, tylko na tym, że sprawdzamy. Analizator sprzed dwudziestu lat pokaże wizyty GPTBota; tabela wyżej pokazuje, ile z nich przeszło weryfikację tożsamości. To są dwie różne liczby i tylko jedna z nich nadaje się pod decyzje.
To jedna niewielka strona: portal o serowarstwie domowym. Pomiar trwa od 3 września 2026, czyli 48 dni, i obejmuje 52 423 żądań od 38 różnych tożsamości botów z 387 sieci.
To nie jest próba reprezentatywna dla internetu i nie udajemy, że jest. Wartość tych danych bierze się z czegoś innego: z tego, że każde żądanie zostało sprawdzone tą samą, opisaną niżej metodą, a wynik — łącznie z tym, czego nie umieliśmy rozstrzygnąć — jest podany w całości. Liczby na tej stronie odświeżają się same, więc im dłużej trwa pomiar, tym są mocniejsze.
Wyobraź sobie, że wysyłasz list i piszesz na kopercie cudze nazwisko jako nadawcę. Poczta go dostarczy — nikt nie sprawdza, czy nadawca jest tym, za kogo się podaje. Dokładnie tak działa nagłówek User-Agent: przeglądarka albo bot deklaruje, czym jest, a serwer tę deklarację przyjmuje.
Napisanie programu, który przedstawia się jako GPTBot, zajmuje jedną linijkę. Nie trzeba do tego żadnych uprawnień ani wiedzy — wystarczy wpisać tekst.
Weryfikacja polega na sprawdzeniu, czy list rzeczywiście wyszedł z podanego adresu. Duzi operatorzy publikują listy adresów sieciowych, z których wychodzą ich boty. Jeśli żądanie przyszło spoza tej listy, a przedstawia się nazwą operatora, to nie jest ten operator. To jedyny sposób i nie da się go obejść samą deklaracją.
Narzędzia analityczne, które pokazują „ruch botów AI", w większości zliczają deklaracje. Nie dlatego, że ktoś oszukuje — po prostu weryfikacja kosztuje zapytania sieciowe, a deklaracja jest za darmo.
Im bardziej rozpoznawalny bot, tym częściej ktoś się pod niego podszywa — bo strony przepuszczają znane nazwy. Liczba podszyć mówi o popularności marki, nie o jej uczciwości. Wysoka liczba w kolumnie „fałszowane" nie jest zarzutem wobec operatora. Jest odwrotnie: to znaczy, że jego nazwa jest na tyle warta, że ktoś obcy ją ukradł.
| Bot | Operator | Kategoria | Oryginalne | Fałszowane | Niesprawdzone |
|---|---|---|---|---|---|
| Googlebot | wyszukiwarka | 3 035 | 578 | 243 | |
| Meta-ExternalAgent | inny | ai_crawler | 1 945 | 236 | 36 |
| Bingbot | Microsoft | wyszukiwarka | 1 725 | 266 | 0 |
| OAI-SearchBot | OpenAI | ai_crawler | 781 | 402 | 0 |
| facebookexternalhit | Meta | inne | 766 | 53 | 0 |
| Prefetch Proxy | inne | 684 | 0 | 2 | |
| PerplexityBot | Perplexity | ai_crawler | 602 | 409 | 0 |
| ChatGPT-User | OpenAI | ai_uzytkownik | 423 | 407 | 0 |
| ClaudeBot | Anthropic | ai_crawler | 298 | 417 | 0 |
| GoogleOther | inne | 233 | 0 | 1 | |
| GPTBot | OpenAI | ai_crawler | 91 | 367 | 0 |
| Amazonbot | inny | ai_crawler | 55 | 238 | 84 |
| Claude-User | Anthropic | ai_uzytkownik | 24 | 283 | 1 |
| Googlebot-Image | wyszukiwarka | 10 | 0 | 0 | |
| (przegladarka z sieci operatora) | inne | 4 | 0 | 0 | |
| (nierozpoznany podpis) | nieznany | inne | 0 | 0 | 30 708 |
| (bez podpisu) | nieznany | inne | 0 | 0 | 16 082 |
| Bytespider | inny | ai_crawler | 0 | 0 | 1 113 |
| Baiduspider | inny | wyszukiwarka | 0 | 0 | 944 |
| SemrushBot | inny | narzedzie_seo | 0 | 0 | 753 |
| DotBot | inny | narzedzie_seo | 0 | 0 | 527 |
| CCBot | inny | ai_crawler | 0 | 0 | 351 |
| DeepSeekBot | DeepSeek | inne | 0 | 0 | 349 |
| Applebot | inny | wyszukiwarka | 0 | 0 | 317 |
| DuckAssistBot | inny | ai_uzytkownik | 0 | 0 | 308 |
| YouBot | inny | ai_crawler | 0 | 0 | 284 |
| YandexBot | inny | wyszukiwarka | 0 | 0 | 271 |
| AhrefsBot | inny | narzedzie_seo | 0 | 0 | 267 |
| cohere-ai | inny | ai_crawler | 0 | 0 | 262 |
| Perplexity-User | Perplexity | ai_uzytkownik | 0 | 253 | 0 |
| Claude-SearchBot | Anthropic | ai_crawler | 0 | 243 | 0 |
| Go-http-client | inny | inne | 0 | 0 | 183 |
| Google-Extended | ai_crawler | 0 | 171 | 0 | |
| MistralAI-User | inny | ai_crawler | 0 | 0 | 154 |
| MJ12bot | inny | narzedzie_seo | 0 | 0 | 107 |
| python-httpx | inny | inne | 0 | 0 | 94 |
| ShapBot | inny | inne | 0 | 0 | 27 |
| python-requests | inny | inne | 0 | 0 | 26 |
| SleepBot | inny | inne | 0 | 0 | 11 |
W tabeli są wyłącznie boty z co najmniej trzema żądaniami — przy jednym trafieniu nazwa w zestawieniu to szum, a nie dana.
Podszywanie zdarza się każdej rozpoznawalnej nazwie, także wyszukiwarkom — w tym pomiarze żądań podających się za wyszukiwarkę i zdemaskowanych jest 844. Nieporównywalne są proporcje: przy wyszukiwarkach podrobiona jest mniejszość, przy części botów AI nie ma ani jednego potwierdzonego żądania. Aktualny stan widać w tabeli wyżej.
Powód jest prosty i jest w istocie tezą całej tej strony. Googlebota strony weryfikują od dwudziestu lat: mechanizm sprawdzania jest opisany w dokumentacji Google, wbudowany w serwery i powszechnie stosowany. Podszycie się pod niego zostaje wykryte — dokładnie tak, jak te żądania wyżej. Botów AI nie weryfikuje prawie nikt, więc podszycie się pod nie po prostu działa i nikt go nie liczy.
To nie jest różnica w technologii. To różnica w tym, ile lat dana nazwa jest sprawdzana.
Nie wszystkie boty AI robią to samo, a większość narzędzi wrzuca je do jednego worka. Rozróżnienie ma znaczenie praktyczne:
| Kategoria | Żądań | Oryginalne | Fałszowane | Różnych tożsamości | Obsłużonych mirrorem |
|---|---|---|---|---|---|
| inne | 49 224 | 1 688 | 53 | 12 | 6 429 |
| ai_crawler | 8 539 | 3 772 | 2 483 | 13 | 3 383 |
| wyszukiwarka | 7 389 | 4 770 | 844 | 6 | 3 002 |
| ai_uzytkownik | 1 699 | 447 | 943 | 4 | 456 |
| narzedzie_seo | 1 654 | 0 | 0 | 4 | 1 131 |
Kategoria ai_uzytkownik to 1 699 żądań, z czego podrobionych było 943. To jest ta grupa, na której właścicielom stron zależy najbardziej — i jednocześnie ta, w której deklaracji ufa się najchętniej, bo brzmi jak dowód, że ktoś realnie o nas pytał.
Weryfikacja po adresie sieciowym wymaga list, których nie ma dla każdego operatora. Ale okazuje się, że obie grupy zachowują się inaczej na tyle wyraźnie, że da się je rozdzielić bez żadnej listy — a to znaczy, że metoda zadziała też dla operatorów, którzy jeszcze nie powstali.
| Grupa | Okres | Żądań | Odbitych | % błędów | Średni rozmiar odpowiedzi | Różnych ścieżek |
|---|---|---|---|---|---|---|
| falszowane | przed zmianą metody | 62 | 14 | 22,6% | 838 B | 47 |
| oryginalne | przed zmianą metody | 96 | 1 | 1% | 15 321 B | 42 |
| falszowane | po zmianie metody | 4 261 | 3 029 | 71,1% | 4 688 B | 582 |
| oryginalne | po zmianie metody | 10 581 | 245 | 2,3% | 46 011 B | 522 |
Prawdziwe boty dostają średnio 46 011 bajtów, podszywacze 4 688. Powód jest banalny: prawdziwy bot prosi o istniejącą stronę i dostaje jej treść. Podszywacz prosi o pliki, których nie ma, i dostaje krótką stronę błędu.
Prawdziwe boty mylą się w 2,3% przypadków, podszywacze w 71,1%. Prawdziwy crawler idzie po mapie strony — więc wie, co istnieje. Podszywacz zgaduje adresy z gotowej listy popularnych plików konfiguracyjnych i większość jego prób trafia w pustkę.
Po pierwsze, to obserwacja z jednego przypadku, nie prawo. Ruch podrobiony w tym pomiarze był zdominowany przez jedną serię skanowania z jednej sieci. Sygnatura jest wyraźna, ale opiera się w praktyce na jednym sprawcy — i tak należy ją traktować, dopóki nie powtórzy się na kolejnych.
Po drugie, my sami przecięliśmy ten szereg na pół. 5 września 2026 zmieniliśmy zachowanie serwera: ścieżki typowe dla skanerów przestały dostawać stronę aplikacji z kodem 200, a zaczęły dostawać prawdziwe 404. To zmienia oba powyższe wskaźniki — odsetek błędów rośnie, średni rozmiar spada — bez żadnej zmiany w zachowaniu botów. Dlatego tabela ma kolumnę „okres" i pokazuje obie części osobno, zamiast udawać ciągłość. Wykres, który by to zszył w jedną linię, pokazywałby zmianę, której nie było.
To najostrzejsze rozróżnienie w całym zbiorze. Nie publikujemy konkretnych adresów, o które pytano — opublikowana lista wrażliwych ścieżek byłaby gotową mapą dla następnego skanera. Wystarczą typy:
| Grupa | Typ ścieżki | Żądań | % grupy |
|---|---|---|---|
| oryginalne | tresc | 7 013 | 65,7% |
| oryginalne | techniczna | 2 244 | 21% |
| falszowane | sekret | 1 997 | 46,2% |
| falszowane | inne | 1 754 | 40,6% |
| oryginalne | zasob | 996 | 9,3% |
| oryginalne | inne | 424 | 4% |
| falszowane | tresc | 244 | 5,6% |
| falszowane | kod | 143 | 3,3% |
| falszowane | zasob | 111 | 2,6% |
| falszowane | techniczna | 74 | 1,7% |
Boty potwierdzone zapytały o pliki z kodem lub sekretami 0 razy. Podszywacze — 2 140 razy. Odwrotnie z treścią: podszywacze sięgnęli po nią 244 razy na 4 323 wszystkich swoich żądań.
Czym jest „zasob": paczki JavaScriptu, arkusze stylów i grafiki — pliki, które pobiera przeglądarka każdego odwiedzającego. Są publiczne z założenia i nie liczą się jako wrażliwe. U prawdziwych botów zajmują sporą część ruchu z prozaicznego powodu: każde wdrożenie zmienia im adresy, więc crawler wraca po wersję, której już nie ma.
Zbiory celów obu grup prawie się nie przecinają. To nie są dwa rodzaje botów robiące to samo z różną intensywnością. To dwa zupełnie różne zajęcia, wykonywane pod tymi samymi nazwami.
I stąd bierze się właściwa obrona, która nie polega na blokowaniu: skanerzy nie znaleźli niczego, bo pliki, o które pytali, nie istnieją. Nie ma tu żadnego języka po stronie serwera, żadnego panelu administracyjnego pod znanym adresem i żadnej bazy do zrzucenia. Blokowanie po nazwie bota byłoby bez sensu — nazwa jest fałszywa z definicji. Blokowanie po sieci uderzyłoby też w ruch legalny, bo duże serwerownie hostują jednych i drugich.
Przez kilka dni sprawdzałem, czy roboty widzą treść tego serwisu — podszywając się kolejno pod ClaudeBota, GPTBota i PerplexityBota. Zostawiłem 3 062 wizyt, które w każdym zwykłym narzędziu analitycznym wyglądałyby jak zainteresowanie sztucznej inteligencji moją stroną. To 5,5% całego ruchu robotów w tym okresie.
Nie usuwam ich. Odliczam. Wszystkie liczby powyżej są policzone po ich odjęciu.
Reguła jest mechaniczna i podana z góry: wizyta trafia do kategorii „testy właściciela", jeśli przyszła z sieci, z której pracuję, albo niesie umówiony znacznik w podpisie — niezależnie od tego, jak wypada dla statystyki. Wiarygodność bierze się z tego, że reguła jest automatyczna i opisana, a nie z zapewnienia, że jestem uczciwy.
Ta pozycja jest tu z konkretnego powodu. Jeśli ktoś testujący własną stronę potrafi w kilka dni wytworzyć 5,5% jej „ruchu AI", to każdy licznik oparty na deklaracji jest podatny na zafałszowanie także bez złych intencji.
Wszystko powyżej dotyczy żądań, które podały jakąś nazwę — bo tylko takiej deklaracji można nie uwierzyć. Ale część ruchu nie podaje żadnej. Pole User-Agent bywa puste albo zawiera nazwę, której nie ma na żadnej liście: skrypt, monitoring, czyjeś narzędzie napisane wczoraj.
Od 7 września 2026 liczymy także ten ruch. Do tej pory 16 082 żądań.
Ta pozycja mierzy się krócej niż reszta strony — od 7 września 2026, a nie od początku pomiaru. Dopóki liczba jest mała, nie wyciągaj z niej wniosków: zero na starcie licznika znaczy tyle, że licznik właśnie ruszył. Ta strona zaliczyła już ten błąd raz — patrz akapit niżej.
Ta liczba stoi osobno i nie wchodzi do żadnego procentu wyżej. Liczba nagłówkowa tej strony mówi, ile ruchu podającego się za bota AI jest prawdziwe. Wrzucenie do mianownika czegoś, co nigdy takiej deklaracji nie złożyło, zmieniłoby to, co ta liczba mierzy — z dnia na dzień i bez ostrzeżenia dla czytelnika. Dlatego dotychczasowe procenty znaczą dokładnie to samo, co znaczyły wczoraj.
Kim są, nie dowiemy się. Nie zostawili nazwy, a adresów IP świadomie nie zapisujemy. Ale czego szukają, wiemy dokładnie — i to jest ciekawsza informacja, bo intencję widać w celach, nie w narzędziu. Monitoring pyta o stronę główną i nic więcej. Skaner pyta o pliki konfiguracyjne i kopie zapasowe. Czytnik pyta o treść. Rozbicie na cele jest w interaktywnym raporcie „Ruch bez podpisu" na tej stronie; ścieżki wrażliwe pokazujemy tam wyłącznie jako liczbę, bo opublikowana lista adresów, o które pytał skaner, jest gotową mapą dla następnego.
Nie porównuj tej liczby z panelem swojego hostingu. Nasz licznik widzi wyłącznie żądania, które trafiają do naszego kodu. Pliki leżące gotowe na dysku — obrazki, arkusze stylów, skrypty, favikona — oddaje warstwa serwera stojąca przed nim, i tego ruchu tu nie ma. Panel hostingu policzy wszystko, my policzymy mniej. Różnica nie znaczy, że któryś licznik się myli: liczą co innego. Sprawdziliśmy to doświadczalnie — żądanie o mapę serwisu dociera do naszego kodu, żądanie o favikonę nie.
To nadal nie jest licznik ludzi. Przeglądarka wysyła nagłówki, których prosty klient HTTP nie wysyła — metadane żądania albo przynajmniej preferowany język. Żądanie, które je ma, nie trafia do tej tabeli w ogóle. Granica jest arbitralna i może się mylić w obie strony, ale jest jedna, mechaniczna i podana z góry.
Powód, dla którego to dopisaliśmy, jest pouczający sam w sobie. Przez pierwsze dni pomiaru w kodzie stała jedna linijka: „jeśli nie rozpoznajesz nazwy, nic nie zapisuj". W ciągu jednej doby to samo pytanie wróciło z trzech różnych stron — panel Cloudflare pokazywał ruch, którego licznik nie znał; w statystykach odwiedzin pojawili się „użytkownicy" bez pokrycia; i padło pytanie, czy mapy serwisu nie czytał ktoś nierozpoznany. Wszystkie trzy miały tę samą przyczynę. Licznik nie pokazywał zera dlatego, że nic nie przychodziło — tylko dlatego, że nie miał jak zobaczyć.
Wybrane zdarzenia warte zapamiętania. Bez adresów IP i bez ścieżek.
10 września wieczorem zmieniliśmy regułę rozpoznawania naszego ruchu testowego: z całej sieci operatora na znacznik w nagłówku żądania. Zmiana miała dotyczyć jednej reguły, a przepisała całą funkcję, która opisuje każdą zapisaną wizytę, i to od jej starszej wersji. Wypadła przy tym linia, która nadaje wizycie typ adresu: treść, plik techniczny albo plik, o który pytają skanery.
Wizyty zapisywały się dalej, tylko bez tego jednego pola, a baza nie zgłosiła błędu, bo puste pole jest dozwolone. Raporty o czytanych stronach, brakach w treści i pytaniach skanerów zatrzymały się na 10 września, 18:52 UTC, a raport incydentów nie widział nowych pytań o pliki wrażliwe. Zauważyliśmy to dopiero 13 września i to gołym okiem: kolumna „Ostatnio” we wszystkich tych raportach stała na tej samej godzinie. Żaden automat tego nie wyłapał.
Danych nie straciliśmy, bo typ adresu nie jest pomiarem, tylko wnioskiem z zapisanego adresu. Dało się go policzyć wstecz bez zgadywania i raporty uzupełniły się za całe trzy doby. Gdybyśmy zapisywali sam wniosek, a nie to, z czego wynika, tych trzech dni nie dałoby się odzyskać.
Z jednej sieci w Stanach Zjednoczonych (AS396982) przyszła seria 205 żądań, która przedstawiała się dwudziestoma dwiema różnymi nazwami, między innymi jako GPTBot, ClaudeBot, PerplexityBot, Googlebot, Meta-ExternalAgent i Amazonbot. W 80 przypadkach weryfikacja zaprzeczyła deklarowanej tożsamości, pozostałe nazwy należą do botów, których nie da się sprawdzić. 82 żądania dotyczyły plików konfiguracyjnych i kodu źródłowego, część z nich była wymierzona w serwer deweloperski Vite, na którym powstaje wiele aplikacji budowanych z pomocą AI.
Nie znalazły nic, żadnego z tych plików tu nie ma.
Jedna z nazw zdradza fałszerstwo sama. Google-Extended nie jest botem, tylko znacznikiem, którym w robots.txt wyłącza się użycie treści do trenowania modeli Google. Google nie wysyła żadnych żądań pod tą nazwą.
Wśród podrobionych nazw były też Meta-ExternalAgent i Amazonbot, których do tej pory nikt u nas nie podrabiał. To narzędzie nie wybierało nazw, tylko brało całą listę po kolei. Z tego, co piszemy w części „Kogo udają fałszerze”, nie zdejmuje to niczego: seria, która bierze całą listę, podrabia wszystkie nazwy mniej więcej po równo.
Pierwsza ocena była błędna. Wzięliśmy tę serię za narzędzie, które sprawdza, czy strona wpuszcza boty AI, bo raport incydentów pokazywał przy niej zero pytań o pliki wrażliwe. Pokazywał zero przez awarię z poprzedniego wpisu. Po naprawie ta sama seria okazała się skanerem.
Poprosiliśmy trzy modele o podanie sprawdzalnych faktów z trzech naszych plików: ile adresów ma mapa serwisu i jaki jest ostatni, jaka jest ostatnia sekcja llms.txt, jaka liczba stoi w nagłówku tej strony. Pytania celowo tak sformułowane, żeby odpowiedź dało się zweryfikować co do znaku — a jednocześnie żeby licznik pokazał, czy model naprawdę po te pliki przyszedł.
Jeden z modeli odpowiedział na wszystkie trzy pytania, z pełną pewnością siebie i z opisem procedury: „licząc wszystkie linie z adresami (…) wychodzi 204 pozycje". W liczniku nie ma śladu żądania o mapę serwisu w oknie testu — jedyne tego dnia przyszło z zupełnie innej strony i o innej godzinie.
| Pytanie | Odpowiedź modelu | Stan faktyczny |
|---|---|---|
| Ile ruchu AI jest prawdziwe | 10–15% | 71,2% wśród rozstrzygniętych |
| Ile adresów ma mapa serwisu | 204 | 106 — a 204 nie było nigdy; najwięcej w historii było 135 |
| Ostatni adres w mapie | /bakterie-kultury.html | /en/ai-bots — podany adres był ostatni do 1 września |
| Ostatnia sekcja llms.txt | „AKTUALIZACJE" | zgadza się — jedyne trafienie |
| Data w tej sekcji | 2026-06-16 | 2026-09-05 |
Warto rozróżnić dwie rzeczy, bo mają różne przyczyny. Ostatni adres i data w llms.txt to informacje prawdziwe, ale nieaktualne — opisują stan sprzed kilku dni. To zapamiętana kopia i nic w tym zdrożnego, poza tym, że została podana jako świeży odczyt. Liczba 204 to co innego: nie była prawdziwa nigdy. Nie ma wersji tego pliku, w której by wystąpiła. Powstała na miejscu, razem z opisem czynności liczenia, której nikt nie wykonał.
Uczciwe zastrzeżenie: nie możemy wykluczyć, że model pobrał te pliki wcześniej, poza naszym oknem pomiaru — właśnie na to wskazują dane sprzed 5 września. To by tłumaczyło nieaktualność. Nie tłumaczy natomiast liczby, której nigdy nie było, ani zdania opisującego liczenie jako czynność wykonaną przed chwilą.
Dla tej strony najbardziej wymowna jest pierwsza linijka tabeli. Strona, która mierzy, ile „ruchu AI" jest prawdziwe, została opisana liczbą, która z niej nie pochodzi — i to z dokładnością gorszą niż czterokrotna.
W tym samym teście inny model odpowiedział: nie udało mi się pobrać tego pliku, i zgadywał, że to wina zapory po naszej stronie. Licznik pokazał co innego: jego żądania dotarły, oba, co do sekundy. Serwer oddał pliki poprawnie — to narzędzie modelu nie poradziło sobie z formatem innym niż HTML i zgłosiło własne ograniczenie jako awarię cudzego serwera.
Ale ten sam model, zapytany o treść tej strony, odpowiedział, że dostał „spis treści portalu przypominający sitemapę, a nie właściwy artykuł". I to była prawda — a błąd był nasz. Ten model nie przedstawia się nazwą, którą znaliśmy, więc nie trafiał do grupy dostającej pełną treść i dostawał awaryjną mapę serwisu. Poprawione tego samego dnia: o tym, czy żądanie pochodzi od człowieka, decyduje teraz brak nagłówków, które wysyła przeglądarka — a nie to, czy nazwa bota jest na naszej liście. Lista nazw zawsze będzie spóźniona wobec rzeczywistości.
Zestawienie tych dwóch przypadków jest pouczające samo w sobie. Model, który przyznał się do niewiedzy, dał nam informację wartą poprawki. Model, który odpowiedział na wszystko, nie dał żadnej.
Ten sam test przeszedł jeszcze jeden model, też w wersji darmowej. Przyszedł po wszystkie trzy pliki — mamy jego żądania co do sekundy. Przy mapie serwisu napotkał to samo ograniczenie co poprzedni: nie potrafił odczytać XML-a. I zrobił jedyną rzecz, której żaden z pozostałych nie zrobił: napisał, że nie poda liczby, bo nie chce zgadywać, i zaproponował, żeby wkleić mu zawartość pliku.
Plik llms.txt odczytał poprawnie i aktualnie, łącznie z datą ostatniej aktualizacji — tą samą, którą poprzedni model podał o trzy miesiące starszą.
Przy liczbach z tej strony podał wartości spójne arytmetycznie, ale nieodpowiadające stanowi licznika z chwili odczytu. Nie umiemy tego rozstrzygnąć i tak to zapisujemy: strona jest buforowana na godzinę, a liczby rosną szybko, więc mógł dostać starszą wersję — albo sięgnąć do pamięci. Bez zapisu historii tych liczb nie mamy jak sprawdzić, a zgadywanie byłoby dokładnie tym, co tej stronie zarzucamy u innych.
Trzy modele, to samo pytanie, ta sama przeszkoda — i trzy różne zachowania:
Test powtórzyliśmy na pięciu modelach i wersjach, w tym trzech płatnych. Wynik zbiorczy:
| Wersja | Czy przyszedł | Liczby ze strony | Mapa serwisu (XML) | llms.txt |
|---|---|---|---|---|
| A, darmowa | nie | błędne | podał liczbę, której nigdy nie było | sekcja dobrze, data o trzy miesiące stara |
| B, darmowa | tak | trafnie zgłosił, że dostał mapę zamiast artykułu | „nie mogę" — obwinił nasz serwer | „nie mogę" |
| C, darmowa | tak | niezgodne ze stanem | odmówił zgadywania | poprawnie |
| D, płatna | nie — cytował odczyt sprzed godziny | dokładnie, z datą stanu | odmówił zgadywania | poprawnie |
| E, płatna, tryb rozumowania | nie — jak wyżej | dokładnie, z pełnym rozbiciem | odmówił; poprosił o dostęp do repozytorium | wymyślił sekcję, której nie ma |
| F, płatna | tak — 5 żądań, wszystkie zweryfikowane | zadeklarował pobranie, podał stan sprzed doby | odczytał poprawnie: 106 adresów, ostatni i jego data | poprawnie, z sekcją poprzedzającą |
Trzy rzeczy z tej tabeli są warte więcej niż sam ranking.
Po pierwsze: tylko jedna z sześciu wersji odczytała mapę serwisu w formacie XML — podała liczbę adresów, ostatni z nich i jego datę, wszystko zgodnie ze stanem. Cztery uczciwie przyznały, że nie potrafią, jedna zmyśliła liczbę. To jest praktyczny wniosek dla każdego, kto liczy na to, że sitemapa „karmi modele": czasem karmi, ale częściej nie — i nie da się z góry przewidzieć, którego modelu to dotyczy.
Pierwsza wersja tego akapitu brzmiała „żadna z pięciu wersji nie odczytała mapy serwisu". Była prawdziwa przez godzinę, do szóstego testu. Zostawiamy ślad po poprawce, bo to ta sama zasada, którą stosujemy do cudzych liczb: wniosek z małej próby starzeje się szybciej, niż się wydaje.
Po drugie: wyższy tryb rozumowania nie dał lepszej odpowiedzi na pytanie faktograficzne. Wersja E podała liczby z tej strony dokładniej niż ktokolwiek — a przy prostszym pytaniu o ostatnią sekcję pliku tekstowego wskazała sekcję, której w nim nie ma, i uzasadniła to „aktualnie zindeksowaną wersją". Wersja D, prostsza, odpowiedziała poprawnie.
Po trzecie, i to jest ostrzeżenie praktyczne: wersja E, nie mogąc odczytać publicznego pliku, poprosiła o dostęp do prywatnego repozytorium kodu. Plik leży pod publicznym adresem i nie wymaga żadnych uprawnień. Prośba została odrzucona i słusznie — to wzorzec, na który łatwo się nabrać: skoro nie mogę odczytać A, daj mi dostęp do B. Odległość między jednym a drugim bywa ogromna.
Model, który jako jedyny odmówił odpowiedzi, jest jednocześnie jedynym, którego pozostałe odpowiedzi okazały się prawdziwe. To nie jest przypadek ani ładna puenta — to ta sama zależność, o której jest cała ta strona. Wartość odpowiedzi bierze się z tego, czy stoi za nią sprawdzenie, a nie z tego, jak pewnie brzmi.
Wszystkie trzy testy wykonano na wersjach darmowych. Nie wiemy, czy wersje płatne zachowałyby się tak samo, i nie twierdzimy, że to cecha tych firm — to jest obserwacja z trzech rozmów, nie pomiar.
Z jednej sieci w Stanach Zjednoczonych (AS1004) przyszła seria żądań, w której ten sam ruch przedstawiał się kolejno jako sześć różnych botów: CCBot, ChatGPT-User, ClaudeBot, GPTBot, OAI-SearchBot i PerplexityBot. Całość trwała dziewiętnaście sekund. Żądania dotyczyły plików konfiguracyjnych, kopii zapasowych i map kodu źródłowego.
Nie znalazły nic — żaden z tych plików w tym serwisie nie istnieje.
Formalna uwaga, która ma znaczenie: piszemy, że żądania przyszły z sieci AS1004, a nie że „AS1004 skanuje". Operator sieci wynajmuje serwery i sprawca jest jego klientem, nie nim. Pierwsze sformułowanie to weryfikowalna obserwacja, drugie byłoby zarzutem wobec podmiotu, którego nie znamy.
Analiza powyższej serii ujawniła, że część pytań o nieistniejące pliki dostawała od nas kod 200 i stronę aplikacji, zamiast błędu 404. Skaner odczytuje to jako „coś tu jest" i wraca. Zostało poprawione — a przy okazji okazało się, że zaniżało to nasz własny wskaźnik błędów, czyli jeden z sygnałów, którymi rozpoznajemy skanowanie. Serwer psuł pomiar, który sam zasilał.
Weryfikacja przez odwrotny DNS sprawdza, czy nazwa hosta kończy się domeną operatora. Dla Amazonbota mieliśmy wpisane crawl.amazon.com — domenę, która nie istnieje. Amazon dokumentuje crawl.amazonbot.amazon. Skutek: każde żądanie prawdziwego Amazonbota odpadało na drugim kroku i trafiało do tabeli jako podszycie. Przez trzy doby ta strona pokazywała Amazonbota jako najczęściej podszywanego bota w całym zbiorze.
Sygnał był w danych od początku: metoda odwrotnego DNS miała bilans zero potwierdzeń na dwadzieścia pięć sprawdzeń. Odnotowaliśmy to dzień wcześniej i opisaliśmy tę metodę jako niesprawdzoną — ale zabrakło wniosku, że skoro jest niesprawdzona, to jej „nie" też nie nadaje się do publikacji.
Werdyktów nie dało się przeliczyć, bo celowo nie zapisujemy adresów IP — bez adresu nie ma jak ponowić zapytania DNS. Zostały więc cofnięte do „niesprawdzone". To jest ta sama zasada, którą stosujemy do cudzych liczb: pomiar, o którym wiadomo, że był błędny, przestaje być dowodem.
Cała ta strona pokazuje, że liczniki ruchu AI zawyżają, bo wliczają podszywki. Uczciwość wymaga pokazania drugiej strony: w innym wymiarze zaniżają, i to prawdopodobnie bardziej.
7 września 2026 ta strona została pobrana przez bota jednego z operatorów o godzinie 09:49:29 — jedno żądanie, jedno w naszym liczniku. Następnie trzy różne rozmowy u tego samego operatora zacytowały jej treść, w tym dwie ponad godzinę później, bez żadnego nowego żądania do naszego serwera. Wiemy to, bo licznik nie odnotował już nic, a odpowiedzi podawały liczby zamrożone dokładnie na 09:49.
Zjawisko nie ogranicza się do jednego operatora. Dwa modele różnych firm, pytane w odstępie godziny, podały ten sam zamrożony stan sprzed doby — z identyczną liczbą żądań fałszowanych i niesprawdzonych. Obie firmy cytowały odczyt z tego samego momentu, żadna nie przyszła po nowy.
Jedno pobranie obsłużyło co najmniej trzy odpowiedzi. Ile naprawdę — nie wiemy i nie mamy jak się dowiedzieć. Cytowanie zdarza się po stronie operatora i nie zostawia u nas żadnego śladu.
To znaczy, że liczba żądań w logu nie jest liczbą cytowań, tylko jej dolnym ograniczeniem — i to ograniczeniem nieznanej ostrości. Kto liczy „wizyty AI" po to, żeby wiedzieć, ile razy jego treść trafiła do czyjejś odpowiedzi, mierzy nie to, co myśli, nawet gdy odsieje wszystkie podszywki.
Przy okazji potwierdziło się coś, co robimy tu celowo. Przy każdej liczbie na tej stronie stoi data i godzina stanu, z prośbą, żeby cytować je razem. Modele to zrobiły — podały liczbę wraz z „stan na 7 września, godz. 09:49 UTC". Czytelnik takiej odpowiedzi wie, że ogląda migawkę sprzed godziny, a nie stan bieżący. To najtańsze zabezpieczenie przed zestarzeniem się cytatu, jakie znamy, i jedyne, które działa bez współpracy cytującego.
To jest najbardziej praktyczny wniosek z całego tego pomiaru i jedyny, który może kosztować pieniądze.
7 września wystawiliśmy cztery malutkie pliki testowe o tej samej treści i różnych rozszerzeniach — XML, tekst, JSON i kopię mapy serwisu. Chcieliśmy sprawdzić, którego formatu modele nie potrafią odczytać. Odpowiedź okazała się inna od pytania: format nie miał z tym nic wspólnego.
| Model | Co się stało naprawdę | Co powiedział o przyczynie |
|---|---|---|
| pobierający na żywo | przyszedł, pobrał, odczytał — mamy jego żądania w liczniku, wszystkie zweryfikowane | — |
| czytający z indeksu | nie wysłał ani jednego żądania. Sam podał powód: „cache miss, wyszukiwarka nie ma jego kopii" | „blokowany przez sposób serwowania pliku XML" |
| uruchamiający kod | nie wysłał ani jednego żądania. Napisał skrypt i uruchomił go w piaskownicy bez dostępu do DNS — błąd rozwiązywania nazwy | „zabezpieczenia serwera przed botami, błąd wczytywania lub brak pliku" |
Przez cały ten czas plik odpowiadał każdemu, kto o niego poprosił: kod 200, 246 bajtów. Sprawdzaliśmy to w trakcie i po. Żaden z opisanych wyżej domysłów — zapora, blokada botów, brak pliku, sposób serwowania — nie miał pokrycia w rzeczywistości.
Trzy różne architektury, trzy różne przyczyny niepowodzenia, wszystkie po stronie modelu. I trzy razy ta sama reakcja: opis cudzej infrastruktury jako uszkodzonej, sformułowany z pewnością siebie i bez zastrzeżenia, że problem może leżeć po własnej stronie.
Dlaczego to kosztuje. Wyobraź sobie, że pytasz asystenta, czemu Twojej strony nie widać w AI, a on odpowiada, że serwer blokuje boty. Zaczynasz rozluźniać reguły zapory, dopisujesz wyjątki, prosisz dostawcę o zmiany w konfiguracji, która działała poprawnie. Płacisz za naprawę czegoś, co nie było zepsute — i przy okazji osłabiasz zabezpieczenia, kierując się diagnozą narzędzia, które nigdy nie wysłało żądania.
Pytanie, które warto zadać, jest proste i rozstrzyga w minutę: „czy w moich logach jest ślad Twojego żądania?" Jeśli go nie ma, żadna hipoteza o serwerze nie ma podstaw, bo serwer nie dostał okazji, żeby cokolwiek zrobić.
Rozstrzygnięcie przyszło od modelu, który pobiera. Ten sam zestaw czterech plików odczytał w całości: XML, zwykły tekst, JSON i kopię mapy serwisu pod inną nazwą — cztery klucze, cztery trafienia, a w liczniku cztery jego żądania, wszystkie zweryfikowane jako pochodzące naprawdę od tego operatora. Format nie ma znaczenia dla nikogo, kto faktycznie wychodzi po plik. Znaczenie ma wyłącznie to, czy wychodzi.
Warto się przy tym zatrzymać, bo pierwsze wrażenie bywa odwrotne od wniosku. Model, który przychodzi po plik, zostawia ślad: przedstawia się nazwą, przychodzi z adresów, które jego operator publikuje, i można go sprawdzić, policzyć albo odmówić mu wstępu w robots.txt. Model, który czyta cudzy indeks, jest dla właściciela strony niewidzialny — nie ma go w logach, nie sposób go zablokować i nie wiadomo nawet, że cytuje.
To jest niewygodna symetria. Im mniej model fatyguje się do źródła, tym mniej właściciel źródła wie, że jest czytany — i tym mniej ma nad tym kontroli. Cała ta strona liczy tych, którzy przychodzą. O tych, którzy nie przychodzą, a jednak cytują, nie wie nic i wiedzieć nie może.
Jeden szczegół dla porządku: model uruchamiający kod odczytał wcześniej tego samego dnia dwa inne nasze pliki i zrobił to poprawnie — jego narzędzie przeglądania działa. Tym razem sięgnął po interpreter zamiast po nie. Nie zawiodła umiejętność, tylko wybór narzędzia — a wniosek o cudzej zaporze wyciągnięty został tak samo pewnie.
llms.txt to proponowany standard: mapa treści serwisu przygotowana dla modeli językowych. Mamy go i zostawiamy. Ale trzeba powiedzieć wprost, co pokazują dane, także wtedy, gdy przeczą temu, po co się go tworzy.
U nas plik pobrano cztery razy. Trzy z tych pobrań wywołaliśmy sami.
Testując, czy modele czytają ten plik, poprosiliśmy trzy z nich o podanie jego zawartości. Każdy poszedł po niego naprawdę — i każde z tych żądań wylądowało w liczniku jako ruch bota. Nasz mechanizm odsiewania własnego ruchu tego nie łapie, bo rozpoznaje ruch po naszym numerze sieci i znaczniku w podpisie, a model przychodzi ze swojej infrastruktury, z prawdziwą nazwą i adresem przechodzącym weryfikację. Dla licznika to wzorowy, autentyczny bot — bo nim jest. Tyle że jego przyczyną byliśmy my.
Po odjęciu własnych testów zostaje jedno niezależne pobranie. I nawet przy nim nie umiemy dziś powiedzieć, czy przeszło weryfikację tożsamości, bo nasz raport nie rozbija plików technicznych na zweryfikowane i niezweryfikowane. To luka w narzędziu, nie w danych — do naprawienia.
Ta pułapka jest podstępniejsza od pozostałych, bo działa w jedną stronę: im więcej testujesz, tym bardziej Twoje dane potwierdzają to, co testujesz. Kilkanaście pytań zadanych modelom o własną stronę wystarczy, żeby mała domena pokazała „żywy ruch AI", którego bez tych pytań by nie było.
Nasza próba to jedna strona i kilka dni. Badanie Przemysława Charchana obejmuje około 900 domen przez 191 dni: 1227 zapytań o pliki llms.txt wobec blisko 45 milionów żądań od botów AI w tym samym czasie. To trzy tysięczne procenta. Wśród pytających o ten plik nie było ani jednego zweryfikowanego bota AI — dominowały agregatory danych, skanery bezpieczeństwa i ludzie sprawdzający ręcznie w przeglądarce.
Jego próba jest od naszej jakieś czterdzieści tysięcy razy większa. Gdy dwa pomiary o tak różnej skali mówią to samo, to nie nasz jest dowodem — nasz jest co najwyżej ilustracją, i tak go traktujemy.
Liczby pokazują skutek. Mechanizm zobaczyliśmy przy okazji zupełnie innego sprawdzenia: wystawiliśmy cztery nowe pliki pod publicznymi adresami i poprosiliśmy modele o ich zawartość. Jeden nie wysłał ani jednego żądania i podał powód wprost — „cache miss, wyszukiwarka nie ma jego kopii".
Model o takiej architekturze nie ignoruje llms.txt — on w ogóle nie chodzi po plikach. Czyta z indeksu wyszukiwarki. Plik przygotowany specjalnie dla niego leży poza ścieżką, którą się porusza, i żadne ulepszanie jego treści tego nie zmieni.
Zostawiamy. Kosztuje zero, a gdyby konwencja się przyjęła, będziemy mieli dane historyczne od dnia, w którym zaczęliśmy mierzyć. Ale nie liczymy na niego i nikomu nie radzimy liczyć. Jeżeli masz wybrać, gdzie włożyć godzinę pracy — robots.txt czyta u nas kilkanaście różnych botów, a strona główna jest drugim najczęściej pobieranym adresem w całym serwisie. To są drzwi, którymi się faktycznie wchodzi.
28 sierpnia 2026, tydzień przed uruchomieniem tego licznika, Jakub Sawa opublikował badanie oparte na tej samej metodzie: weryfikacji botów po adresie IP zamiast po nazwie. Prowadzi je na jsseo.dev przez osiemdziesiąt dni i publikuje metodykę oraz surowe dane.
Doszedł do tego samego mechanizmu, niezależnie i wcześniej: jedna pula tanich serwerów przebierająca się za kolejne boty (u niego jeden adres wystąpił pod dwunastoma nazwami), skanowanie plików konfiguracyjnych zamiast czytania treści, i infrastruktura brzegowa, która weryfikuje Google, a resztę przepuszcza.
Ale nasze liczby się różnią — i ta różnica jest pouczająca. U niego podszywek pod GPTBota jest 3%, u nas w tym pomiarze 100%. To nie jest sprzeczność, tylko inny mianownik. Jego domena to laboratorium SEO, które prawdziwe crawlery odwiedzają regularnie od miesięcy, więc podszywki topią się w masie autentycznego ruchu. Do portalu o serowarstwie prawdziwy GPTBot w oknie pomiaru nie przyszedł ani razu — więc wszystko, co przyszło pod jego nazwą, było cudze. Ta sama metoda, dwie strony, przeciwne proporcje i obie liczby prawdziwe.
To jest zarazem najmocniejszy argument za tym, żeby takich pomiarów było więcej. Jeden pomiar z jednej domeny mówi o tej domenie. Dwa niezależne, zgodne co do mechanizmu i rozbieżne co do skali, mówią już coś o zjawisku — i pokazują, od czego ta skala zależy.
Krzysztof Balicki z Web Systems sprawdził te same tezy na dwóch serwerach, na których hostuje strony klientów, w oknie 1–10 września. To jest pomiar z poziomu logów serwera, a nie pojedynczej witryny, czyli skala, której my nie mamy i mieć nie będziemy. Podał: llms.txt pobrane 559 razy, z czego jeden raz przez bota OpenAI i ani razu przez GPTBota, ClaudeBota czy PerplexityBota. Te żądania przyszły na 126 domen. Samego OAI-SearchBota widział w tym czasie na 223 domenach, więc 126 to nie wszystkie strony na tych serwerach, tylko te, o których llms.txt ktoś w ogóle zapytał. Spośród 375 tys. żądań podających się za GPTBota 3,5 tys., czyli około 1%, przyszło spoza puli adresów OpenAI. I rzecz najciekawsza: największym botem AI nie jest u niego GPTBot, tylko Meta-ExternalAgent z 1,8 mln żądań.
Tych liczb nie weryfikowaliśmy — pochodzą z komentarza w grupie, nie z opublikowanego badania z metodyką. Podajemy je jako cudzy pomiar, nie jako nasz wynik. Dwie z trzech tez dają się jednak sprawdzić u nas i obie się bronią.
Sprostowanie z 14 września 2026. W pierwszej wersji pisaliśmy, że te serwery hostują 126 domen. To liczba domen, na które przyszło żądanie o llms.txt, a nie wszystkich stron na tych serwerach. Poprawił nas autor pomiaru.
llms.txt. Nasze cztery pobrania, z czego trzy wywołane przez nas samych, nie pozwalały wnioskować o niczym i tak to opisaliśmy. Jego 559 żądań na 126 domenach temat zamyka.
robots.txt. Z tych samych logów, 1–11 września: GPTBot pobrał robots.txt 20 razy przy 390 tys. żądań, a OAI-SearchBot prawie 10 tys. razy. Jeden właściciel, dwa boty i prawie pięćsetkrotna różnica.
Meta-ExternalAgent. U nas jest tak samo pierwszy — i tego nikt nie planował:
| Bot AI | Żądań u nas |
|---|---|
| Meta-ExternalAgent | 221 |
| PerplexityBot | 171 |
| OAI-SearchBot | 130 |
| ChatGPT-User | 129 |
| Amazonbot | 117 |
| GPTBot | 94 |
Dwie zupełnie różne witryny, skala różniąca się tysiące razy, ta sama nazwa na szczycie. Nazwa, o której w rozmowach o „ruchu z AI" prawie się nie mówi.
Podszywki: to samo pytanie, trzy bardzo różne odpowiedzi. 1,1% u niego, 3% u Jakuba Sawy, 49% u nas, i we wszystkich trzech przypadkach liczone jest to samo: ile spośród żądań podających się za GPTBota nie przyszło z sieci OpenAI. Różnica nie bierze się z definicji, tylko z tego, ile prawdziwego GPTBota trafia na daną stronę. Skanery pukają do wszystkich mniej więcej tak samo, a prawdziwy crawler odwiedza duże serwisy nieporównanie częściej niż portal o serowarstwie. Im więcej ruchu autentycznego w mianowniku, tym bardziej podszywki się w nim topią.
Sprostowanie z 11 września 2026. W pierwszej wersji tego akapitu pisaliśmy, że te trzy liczby odpowiadają na różne pytania, bo każdy liczy inny mianownik. To było nasze wyjaśnienie, a nie ustalenie, i okazało się fałszywe: Krzysztof Balicki sprostował, że jego procent był liczony dokładnie tak jak nasz. Wniosek o topieniu się podszywek w dużym ruchu zostaje, ale bez tamtego uzasadnienia.
Zestawiając nasze liczby z jego, zauważyliśmy coś, czego sami wcześniej nie widzieliśmy: podszywki nie idą za wielkością bota, tylko za tym, kogo właściciele stron przepuszczają.
| Bot | Żądań | Podszywek |
|---|---|---|
| Meta-ExternalAgent | 221 | 0% |
| Amazonbot | 117 | 0% |
| PerplexityBot | 171 | 37% |
| GPTBot | 94 | 49% |
| Claude-User | 44 | 77% |
| ClaudeBot | 65 | 95% |
Nikt nie udaje Mety, mimo że to największy realny crawler — bo podszycie się pod nią nic nie otwiera. Nikt nie wpisuje Meta-ExternalAgent na białą listę. Fałszowane są te nazwy, które ludzie wpuszczają świadomie, w przekonaniu, że wpuszczają „tego dobrego bota AI". ClaudeBot ma u nas trzy prawdziwe żądania na sześćdziesiąt pięć.
Obiecaliśmy dopisać wynik, jeśli ktoś to sprawdzi. Sprawdził. Sześćdziesiąt pięć żądań to było za mało, żeby cokolwiek twierdzić, więc Krzysztof Balicki policzył to na swoich danych z 1–11 września, każdą nazwę według oficjalnej listy adresów jej właściciela (dla Mety: sieć AS32934). Wynik: pod GPTBota, ClaudeBota i OAI-SearchBota podszywa się u niego po około 4 tysiące żądań, pod Meta-ExternalAgent 1,9 tysiąca, choć prawdziwego ruchu Mety jest prawie pięć razy więcej. Gdyby podszywki szły za wielkością bota, Meta byłaby udawana najczęściej. Jest udawana najrzadziej. W jego sformułowaniu, lepszym niż nasze: fałszerze wybierają nazwę, nie wielkość bota.
14 września 2026 dorzucił obserwację, która poprawiła nasz licznik. Połowa żądań z adresów Google Cloud, które udają u niego naraz cztery boty, to próby odczytu plików przez lukę w serwerze deweloperskim Vite (/@fs/…?raw??), klucze AWS (.aws/credentials), pliki gcloud i /proc/self/environ. Nasz wzorzec skanów rozpoznawał z tego tylko .env i config.json, więc reszta nie liczyła się jako pytanie o pliki wrażliwe, a /@fs/ i /proc/ dostawały od serwera stronę z kodem 200 zamiast 404. Dopisaliśmy te wzorce do licznika, a historię przeliczyliśmy.
Przez cały pomiar skanery poprosiły nas o 44 różne adresy zawierające .env — łącznie 197 razy. To około trzech czwartych wszystkiego, czego u nas szukały. Reszta, czyli .git, panele administracyjne i pliki konfiguracyjne, jest w porównaniu z tym marginesem.
Ale nie szukają .env. Szukają jego kopii. Tylko w naszych logach pojawiło się dziewiętnaście końcówek:
.bak · .old · .save · .swp · .backup · .prod · .production · .dev · .development · .stage · .staging · .test · .uat · .ci · .docker · .live · .local · .example · .sample
Do tego ten sam plik w dwudziestu czterech katalogach: /api/, /admin/, /app/, /administrator/, /backend/, /public/, /config/, /wp/ i tak dalej.
Nikt nie liczy, że wgrałeś hasła na serwer. Liczą, że zrobiłeś kopię przed zmianą i o niej zapomniałeś.
Warto zauważyć dwie ostatnie końcówki: .example i .sample to pliki, które ludzie wgrywają celowo, jako wzór do wypełnienia. Same haseł nie zawierają — ale zdradzają nazwy zmiennych, czyli mówią czytającemu, czego szukać dalej.
Sprawdziliśmy to w danych, bo pytanie jest naturalne. Forma bez kropki — .envStary, .envKopia — nie pojawiła się w naszych logach ani razu. Jedyny wariant bez kropki, o który ktokolwiek pytał, to .env~, czyli plik zapasowy zostawiany automatycznie przez edytory tekstu.
Czyli tak: nietypowa nazwa faktycznie omija dzisiejsze słowniki. Tylko że to jest ukrywanie, nie zabezpieczanie, i przestaje działać w trzech sytuacjach, z których żadna nie zależy od nazwy:
.env~ już w nich jest. Dopisanie kolejnych wariantów to kwestia czasu i niczyjej decyzji..git. To u nas najczęściej odpytywany adres w ogóle. Z niego odtwarza się każdą nazwę pliku, jaka kiedykolwiek trafiła do zapisu — a często i jej zawartość, także skasowaną..env leży w katalogu głównego projektu, a na serwer idzie wyłącznie zawartość public/. To zabezpieczenie wynika ze struktury, nie z czyjejś czujności.Wpisz w przeglądarce swój adres z dopiskiem /.env, a potem /.git/config. Powinieneś zobaczyć stronę „nie znaleziono". Jeśli zobaczysz cokolwiek innego — zwłaszcza tekst z wielkimi literami i znakami równości — masz problem do naprawienia dzisiaj, a nie w wolnej chwili.
Potem to samo z końcówkami z listy wyżej, zaczynając od .env.bak i .env.old. I na koniec sprawdź, czy Twój serwer nie wyświetla zawartości katalogów — wpisz adres samego katalogu, na przykład /config/.
Publikujemy te nazwy świadomie. Wszystkie są w słownikach skanerów od lat — pokazanie ich nie uczy nikogo niczego nowego, za to pozwala sprawdzić własną stronę. Milczenie zostawiałoby tę wiedzę wyłącznie tym, którzy z niej korzystają. W tabeli wyżej pokazujemy wyłącznie adresy, które dostały u nas błąd — takich plików tu nie ma i nigdy nie pokażemy adresu, który cokolwiek oddał.
Każde żądanie bota zapisujemy razem z wynikiem próby rozstrzygnięcia jego tożsamości. Metody, w kolejności pewności:
Najpewniejsza. OpenAI, Anthropic, Perplexity, Google i Microsoft publikują pliki z zakresami adresów, z których wychodzą ich boty. Sprawdzenie polega na porównaniu adresu żądania z tą listą. Wynik jest jednoznaczny w obie strony: adres z listy potwierdza, adres spoza niej przy nazwie operatora oznacza podszycie.
Dla operatorów, którzy listy nie publikują, ale mają własną, znaną sieć. Słabsze niż lista adresów, bo sieć bywa duża, ale wciąż rozstrzygające przy nazwach, których nikt inny nie ma prawa używać.
Klasyczna metoda, stosowana od lat do weryfikacji Googlebota. Ma trzy kroki i pominięcie któregokolwiek czyni ją bezwartościową:
googlebot.com.przyklad.pl zawiera, a nie jest,Bez kroku trzeciego wystarczyłoby ustawić sobie dowolny wpis odwrotny. I właśnie na tej metodzie zaliczyliśmy własny błąd pomiarowy — opisany niżej w kronice. Przez pierwsze dni sprawdzaliśmy dla Amazonbota domenę, która nie istnieje, więc każde prawdziwe żądanie tego bota odpadało na kroku 2 i było zapisywane jako podszycie. Poprawione 6 września 2026, a wcześniejsze werdykty tej metody wycofaliśmy do „niesprawdzone".
Powstający standard, w którym bot podpisuje żądanie kluczem. Docelowo najlepsza metoda z możliwych. Na razie tylko odnotowujemy obecność nagłówków podpisu — nie sprawdzamy ich poprawności, więc nie jest to weryfikacja i nie liczymy jej jako takiej. Zapisujemy, żeby mieć dane historyczne, kiedy standard się przyjmie.
| Metoda | Żądań | Potwierdzone | Zaprzeczone |
|---|---|---|---|
| brak_metody | 53 117 | 0 | 0 |
| ip_lista | 11 606 | 7 872 | 3 734 |
| asn_operatora | 3 000 | 2 711 | 289 |
| fcrdns | 293 | 55 | 238 |
| blad_sprawdzenia | 272 | 0 | 0 |
Tabela obejmuje 52 206 żądań — te, przy których zapisaliśmy, czym rozstrzygnięto. Wcześniejsze wpisy mają to pole puste nie dlatego, że weryfikacja zawiodła, tylko dlatego, że kolumna powstała później niż licznik.
Że nie umiemy rozstrzygnąć — nie że bot jest podejrzany. Niektórzy operatorzy nie publikują ani list adresów, ani niczego, co pozwoliłoby ich potwierdzić. Wrzucenie tych żądań do „prawdziwych" zawyżyłoby wynik, a do „podrobionych" — byłoby oskarżeniem bez dowodu. Zostają osobno.
To jest cała różnica między tą stroną a panelem, który sprzedaje wskaźnik. Panele nie mają kategorii „nie wiem", bo źle wygląda. My mamy, bo bez niej pozostałe liczby nic nie znaczą.
To, o co prosimy boty, i to, co im udostępniamy, leży otworem w dwóch plikach tekstowych: robots.txt (zasady, o które prosimy) i llms.txt (mapa treści przygotowana dla modeli). Można porównać, czy zgadzają się z tym, co opisano wyżej. To surowe pliki konfiguracyjne, nie artykuły — podajemy je po to, żeby dało się nas skontrolować.
Nie zapisujemy adresów IP ani niczego, co wskazuje osobę. Do rozpoznania podszywacza wystarczy numer sieci i kraj — jedno i drugie opisuje serwerownię, nie człowieka. Nie zapisujemy też treści zapytań użytkowników, bo żaden bot jej nie przekazuje i nie przekaże; to cudze dane.
Z odsyłaczy bierzemy wyłącznie NAZWĘ SERWISU — facebook.com, chatgpt.com — nigdy ścieżki. Ścieżka odsyłająca potrafi zawierać treść wpisanego pytania albo adres zamkniętej grupy, więc odcinamy ją, zanim cokolwiek trafi do zapisu. Wejść bez odsyłacza nie zapisujemy wcale.
Licznik, którego liczby czytasz na tej stronie, jest dostępny w całości: github.com/kitayMarek/ai-bot-verify (licencja MIT). Kod weryfikacji, schemat bazy, widoki publiczne i testy — wszystko, czego potrzeba, żeby zmierzyć to samo u siebie.
Jest tam jeden plik, na który zwracamy uwagę bardziej niż na kod: spis siedmiu błędów, które popełniliśmy w pierwszym tygodniu, każdy z ceną, którą zapłaciliśmy. Literówka w nazwie domeny, przez trzy dni publicznie oskarżająca cudzą firmę o podszywanie się pod samą siebie. Pliki serwowane z pominięciem licznika, dające twarde zero odczytane jako „nikt tego nie pobiera". Raport odsiewający dokładnie to, czego w nim szukaliśmy. Cztery z siedmiu dawały wynik wyglądający wiarygodnie i żaden nie zgłosił się sam.
Publikujemy to, bo zbudowanie takiego licznika jest łatwe, a zbudowanie go tak, żeby nie kłamał — nie jest. Kod bez tej listy byłby narzędziem do produkowania kolejnych pewnych siebie liczb, a takich już jest dosyć.
Wszystkie liczby z tej strony są dostępne maszynowo pod adresem bot-stats.json, na licencji CC BY 4.0. Warunek jeden: podanie źródła.
Plik zawiera wyłącznie agregaty — te same, które widać wyżej. Nie ma w nim adresów IP ani pełnych ścieżek.
Sam nagłówek User-Agent to deklaracja i wpisanie w niego dowolnego tekstu nie jest przestępstwem. Co innego to, do czego się go używa: w opisanym tu przypadku posłużył do skanowania serwera w poszukiwaniu haseł i kluczy, a to jest już czym innym niż wybór nazwy.
Blokowanie po nazwie nie działa, bo nazwa jest właśnie tym, co podszywacz fałszuje — zablokujesz prawdziwego, przepuścisz fałszywego. Blokowanie po sieci uderza też w ruch legalny, bo duże serwerownie hostują jednych i drugich. Sensowniejsza jest odwrotna kolejność: nie mieć na serwerze niczego, co warto ukraść, i mierzyć, kto naprawdę przychodzi.
robots.txt to prośba, nie zabezpieczenie — respektują ją ci, którzy chcą. Warto pamiętać o jednym szczególe: bot stosuje wyłącznie tę grupę reguł, która pasuje do jego nazwy, a reguły z grupy ogólnej się z nią nie sumują. Zakaz wpisany tylko do User-agent: * nie obejmie bota, który ma własną grupę.
Bo trafił na to przypadkiem. Licznik powstał, żeby sprawdzić, czy modele językowe w ogóle widzą treść serwisu — a przy okazji okazało się, że znaczna część „ruchu AI" nim nie jest. Dane są przy tym o tyle wiarygodne, że nie mamy żadnego interesu w tym, żeby wypadły w którąkolwiek stronę.
Tak, i to jest zamierzone. Strona składa się na żywo z aktualnego stanu licznika, a nie z zamrożonej migawki. Dlatego przy każdej liczbie stoi data — jeśli cytujesz, cytuj razem z nią.