Dlaczego sam raport Search Console nie wystarcza do automatycznych alertów
Search Console udostępnia widok ostatnich 24 godzin, funkcję porównywania okresów oraz raport Insights, które pomagają w ręcznej analizie, lecz nie zastępują automatycznych alertów SEO precyzyjnie dopasowanych do architektury konkretnego serwisu. Średnia dla całej domeny potrafi skutecznie ukryć poważny problem w jednej sekcji, a trzeba jeszcze pamiętać o regularnym otwieraniu raportu i ręcznym ustawianiu właściwych filtrów.
Największym zagrożeniem są spadki częściowe. Gdy strona główna trzyma się mocno, a blog rośnie, katalog /poradniki/ może tracić widoczność tuż po wdrożeniu nowego layoutu. W efekcie ogólne statystyki domeny wyglądają pozornie dobrze, choć w firmowej kasie sytuacja wygląda zupełnie inaczej. To z kolei wymusza przeniesienie wykrywania anomalii znacznie bliżej surowych danych.
Dane z Google Search Console: czego szukać w eksporcie do BigQuery
Bulk Data Export z Google Search Console zapisuje dane do BigQuery codziennie. W praktyce najczęściej pracujesz na dwóch tabelach danych i tabeli ExportLog:
searchdata_site_impression: dane zagregowane na poziomie właściwości, z zapytaniami, krajem, typem wyszukiwania i urządzeniem.searchdata_url_impression: dane na poziomie URL, dobre do analizy katalogów, szablonów i konkretnych stron.ExportLog: rejestr udanych zapisów do każdej z tabel danych.
Do pierwszej wersji systemu alertów biorę tabelę URL. Daje mniej „ładny” obraz, ale lepiej odpowiada na pytanie, które naprawdę pada w firmie: co dokładnie spadło?
Załóżmy, że tabela nazywa się:
W danych masz między innymi datę, URL, kraj, urządzenie, typ wyszukiwania, kliknięcia, impresje i sumę pozycji. CTR i średnią pozycję liczysz samodzielnie, bo eksport przechowuje liczniki potrzebne do ponownej agregacji.
Warto znać kilka szczegółów, zanim zaczniesz pisać alerty:
data_datejest datą danych w czasie Pacific Time, więc nie próbuj dopasowywać jej co do godziny do polskiej strefy czasowej,eksport jest przyrostowy i może zawierać powtarzające się klucze, dlatego prawie zawsze ponownie agregujesz metryki,
ExportLogzapisuje wyłącznie udane eksporty, a tabele URL i site mogą zakończyć zapis o różnych porach,tekst zapytania może zostać ukryty z powodów prywatności,
dane URL i site mają różną semantykę agregacji, więc ich sumy i średnie pozycje nie zawsze są bezpośrednio porównywalne,
metryki są zwykle przypisywane do adresu kanonicznego wybranego przez Google, a nie zawsze do URL-a, na który ostatecznie trafił użytkownik.
W tabeli URL Google używa pola sum_position, a w tabeli site pola sum_top_position. W obu przypadkach pozycja jest liczona od zera. Średnią pozycję w stylu raportu GSC liczysz więc jako SUM(sum_position) / SUM(impressions) + 1 dla tabeli URL albo SUM(sum_top_position) / SUM(impressions) + 1 dla tabeli site.
Funkcja Bulk Data Export zaczyna zbierać dane dopiero od momentu konfiguracji – nie uzupełnia automatycznie wcześniejszej historii. Zapisane w BigQuery informacje zostaną tam tak długo, dopóki ich nie usuniesz lub nie skonfigurujesz wygaśnięcia partycji. Pamiętaj więc, że jeśli Twój detektor korzysta z kilkumiesięcznej bazy odniesienia, okres przechowywania danych w bazie musi być odpowiednio dłuższy niż samo okno analizy.
Dane godzinowe z Search Analytics API a eksport do BigQuery
Bulk Data Export świetnie sprawdza się jako źródło pełnych danych dobowych, ale nie działa w czasie rzeczywistym. Z kolei Search Analytics API obsługuje wymiar godzinowy ze statusem HOURLY_ALL, który pozwala pobrać do 10 dni danych z podziałem na godziny, przy czym najnowsze wpisy pojawiają się z kilkugodzinnym opóźnieniem.
Unikaj łączenia tych danych z zamkniętymi dniami w BigQuery bez wyraźnego oznaczenia. Ostatnie godziny mają charakter wstępny i mogą ulec zmianie. Najbezpieczniejsze podejście opiera się na dwóch niezależnych alarmach:
-
Wczesny alarm godzinowy porównuje zakończone godziny z analogicznymi godzinami z poprzednich dni.
-
Alarm dobowy potwierdza problem dopiero po poprawnym zapisie tabeli w
ExportLog.
W sytuacji, kiedy biznes nie wymaga natychmiastowej reakcji tego samego dnia, prostszym i mniej podatnym na fałszywe alarmy rozwiązaniem będzie oparcie się wyłącznie na eksporcie dobowym.
Segment URL przed alertem: jak ograniczyć fałszywe alarmy SEO
Alert obejmujący całą domenę może początkowo wydawać się dobrym pomysłem, ale w praktyce okazuje się mało użyteczny, ponieważ ogólny spadek nie wskazuje przyczyny. Gdy spadek o 42% dotyczy katalogu /blog/ na urządzeniach mobilnych w Polsce, można od razu rozpocząć analizę: sprawdzić ostatnie wdrożenia, działania robotów indeksujących, strukturę szablonu, linkowanie wewnętrzne oraz nowe błędy w kodzie HTML.
Właśnie dlatego najpierw sklasyfikuj adresy według ścieżki, zamiast analizować cały adres. Dzięki temu parametry zapytania zawierające ciąg /blog/ nie przypiszą strony do niewłaściwej grupy.
Widok agreguje od razu do poziomu używanego przez detektor. Przechowywanie w nim każdego URL-a i gotowego CTR byłoby zbędne, ponieważ kolejne zapytanie ponownie grupuje dane według page_group, kraju i urządzenia. Zwróć też uwagę na pozycję: eksport z GSC nie dostarcza gotowej średniej, lecz wartość sum_position. Faktyczną średnią obliczasz dopiero podczas odczytu za pomocą wyrażenia SAFE_DIVIDE(SUM(sum_position), SUM(impressions)) + 1. Nie wolno ponownie uśredniać średnich, ponieważ dałoby to niepoprawny wynik.
Prosta detekcja anomalii SEO na kompletnych danych
Na start nie potrzebujesz uczenia maszynowego. Możesz porównać ostatni pomyślnie wyeksportowany dzień z medianą ośmiu wcześniejszych wystąpień tego samego dnia tygodnia. Poniedziałek porównujesz z poniedziałkami, a nie z niedzielą.
Samo CURRENT_DATE() - 3 jest kruche. Eksport może pojawić się później, a korekta starszych danych może zostać zapisana ponownie. Datę raportową wybierz z ExportLog. Następnie zbuduj pełną siatkę segmentów i poprawnych dat. Bez tego segment, który spadł do zera i nie ma żadnego wiersza w tabeli, zniknie również z wyniku alertu.
Zapytanie stosuje osobne progi dla kliknięć, wyświetleń, CTR i pozycji. Dla kliknięć wymaga sensownego poziomu bazowego, minimalnej bezwzględnej różnicy oraz spadku procentowego albo dużego odchylenia względem medianowego odchylenia bezwzględnego, czyli MAD. Współczynnik 1.4826 skaluje MAD do wartości zbliżonej do odchylenia standardowego przy rozkładzie normalnym. Nie zamienia to prostej reguły w dowód statystyczny, ale ogranicza alarmy wywołane zwykłym szumem. Progi 20, 10, 100, 50, 25%, 2 pp i 2 pozycje są wartościami startowymi, a nie uniwersalną definicją anomalii — trzeba je dostroić do wolumenu i wartości biznesowej segmentów.
click_gap_vs_baseline jest różnicą względem poziomu bazowego, a nie wiarygodnym szacunkiem utraconego ruchu. Popyt, sezonowość, święta, kampanie marki i zmiany w wynikach wyszukiwania również wpływają na liczbę kliknięć.
Lepszy alert SEO: rozbij przyczynę na typ spadku
W powyższym zapytaniu instrukcja CASE nadaje etykietę na podstawie przekroczonych progów kliknięć, wyświetleń, CTR i średniej pozycji. Jeżeli jednocześnie wystąpią co najmniej dwa sygnały, alert otrzymuje etykietę mixed. W przeciwnym razie reguły rozróżniają spadek kliknięć, widoczności, CTR albo pogorszenie pozycji.
To nie jest diagnoza. To skrót, który mówi zespołowi, od którego obszaru zacząć. Warto też liczyć click_gap_vs_baseline, ponieważ alerty sortowane wyłącznie po procencie spadku promują małe segmenty. Różnicę względem poziomu bazowego traktuj jako miarę priorytetu, a nie dowód utracenia konkretnej liczby kliknięć przez błąd SEO.
AI w monitoringu SEO: autor notatki, nie sędzia
Wrzucenie danych do modelu z pytaniem „czy mamy problem?” nie tworzy wiarygodnego detektora. Model może dopowiedzieć wzorzec, którego nie ma w danych. Reguła SQL też może być źle zaprojektowana, ale pozostaje jawna, testowalna i audytowalna.
Lepszy układ wygląda tak:
- SQL wykrywa segmenty, które przekroczyły progi.
- Query dopisuje typ anomalii i metryki.
- AI dostaje tylko wyniki alertu i pisze krótką notatkę dla człowieka.
Przykładowy prompt:
Wartość ctr_delta w tym kontrakcie jest różnicą zapisaną jako ułamek. -0.04 oznacza spadek o 4 punkty procentowe, a nie o 4%. Jednostki powinny być jawne zarówno w tabeli alertów, jak i w prompcie.
Wynik analizy powinien być w pełni konkretny i wyraźnie rozdzielać twardą obserwację od samej hipotezy, co oznacza, że model może na przykład wykazać spadek wyświetleń, a następnie wskazać indeksację, zmiany w szablonie czy wahania popytu jako potencjalne obszary do sprawdzenia, nie powinien jednak pochopnie stwierdzać, że odnalazł ostateczną przyczynę problemu.
Jeśli chcesz wygenerować takie notatki z poziomu BigQuery, możesz użyć AI.GENERATE_TEXT z modelem zdalnym skonfigurowanym w BigQuery ML. Funkcja nadal wysyła prompt do wskazanego modelu w Vertex AI albo obsługiwanej usłudze modelowej, więc nie oznacza to, że dane pozostają wyłącznie w silniku BigQuery. Lokalizacja datasetu, połączenia i endpointu oraz wymagania dotyczące przetwarzania danych muszą być świadomą decyzją.
Model zdalny można utworzyć na przykład tak:
Przed uruchomieniem potrzebujesz aktywnych API, połączenia Cloud Resource oraz odpowiedniej roli dla konta usługi tego połączenia. Dataset i połączenie powinny znajdować się w zgodnej lokalizacji. Globalnego endpointu nie używaj, jeśli musisz kontrolować region przetwarzania.
Najpierw wybierz maksymalnie kilka najważniejszych alertów dla jawnie wskazanego @report_date, zbuduj z nich prompty według powyższego kontraktu i zapisz do małej tabeli stagingowej daily_prompts. Dopiero tę tabelę przekaż do modelu:
Jawny filtr daty podczas budowania tabeli stagingowej jest potrzebny także dlatego, że tabela alertów wymaga filtra partycji. Samo LIMIT w zapytaniu przekazanym bezpośrednio do AI.GENERATE_TEXT ogranicza liczbę wynikowych promptów, ale nie gwarantuje, że BigQuery pominie wcześniejsze przetwarzanie całego wejścia. Po wywołaniu kontroluj również status odpowiedzi modelu i obsłuż błędy limitów oraz nieudane wywołania, zamiast zakładać, że każdy wiersz otrzymał poprawny tekst.
Harmonogram wykrywania anomalii SEO: raz dziennie i do tabeli alertów
BigQuery Scheduled Queries pozwala uruchamiać zapytanie cyklicznie. Dla eksportu GSC wystarczy jedno uruchomienie dziennie. Zapytanie powinno jednak wybrać najnowszą datę potwierdzoną w ExportLog, a nie zakładać stałego opóźnienia dwóch lub trzech dni.
Wyniki zapisuję do tabeli:
Minimalny schemat może wyglądać tak:
Zapytanie cykliczne może zostać uruchomione ponownie po błędzie lub wykonane ręcznie. Z kolei, zwykłe polecenie WRITE_APPEND utworzy w takiej sytuacji duplikaty danych. Aby taka sytuacja nie miała miejsca, zapisuj wyniki za pomocą operacji MERGE z kluczem złożonym z daty i wymiarów albo nadpisuj wyłącznie partycję dotyczącą konkretnego dnia. Do samego uruchamiania zadań użyj dedykowanego konta usługi z minimalnymi uprawnieniami zamiast poświadczeń pojedynczego pracownika.
Najprostszy idempotentny wariant w zapytaniu skryptowym zapisuje najpierw wynik detektora do tabeli tymczasowej detected, a następnie atomowo zastępuje alerty dla przetwarzanej daty:
W kodzie produkcyjnym zastąp komentarz pełnym zapytaniem detektora i utrzymuj identyczną kolejność kolumn w tabeli tymczasowej oraz docelowej. Alternatywą jest MERGE; usunięcie i ponowne wstawienie jednej partycji jest jednak krótsze, a zarazem usuwa alert, który po ponownym przeliczeniu przestał spełniać warunki.
Wartość epoch_version w tabeli ExportLog rośnie w sytuacji, gdy Google dokonuje poprawek wcześniej zapisanych danych. W sytuacji, gdy zajmujesz się materializowaniem agregatów, pamiętaj o zapamiętywaniu najwyższej przetworzonej wersji dla każdej pary namespace oraz data_date. Ewentualna zmiana tej wersji powinna automatycznie uruchomić ponowne przeliczenie odpowiedniej partycji danych oraz powiązanych alertów, których poziom bazowy korzysta z poprawionej daty.
Dopiero na tej tabeli budujesz powiadomienie do Slacka, poczty, Looker Studio albo webhooka. Powiadomienie nie powinno uruchamiać się dla każdego wiersza. Lepiej zebrać anomalie w jeden dzienny raport i posortować je po click_gap_vs_baseline, prawdopodobieństwie anomalii albo własnej wartości biznesowej.
Google Cloud pozwala oprzeć alert na metryce liczby wierszy zwróconych przez Scheduled Query, ponieważ zapytanie zwraca wiersze tylko w przypadku wykrycia anomalii, a Cloud Monitoring reaguje na wartość większą od zera. Metryka oparta na ostatniej liczbie wierszy może jednak utrzymywać swoją poprzednią wartość przez wiele tygodni po wyłączeniu lub awarii harmonogramu, dlatego należy osobno monitorować completed_runs, historię uruchomień albo logi usługi BigQuery Data Transfer Service. Pamiętaj, że całkowity brak nowego wykonania nie może wyglądać jak poprawny i bezpieczny stan systemów monitorowania.
Co sprawdzić po alercie
Alert sygnalizuje jedynie problem, a nie jego ostateczną przyczynę, dlatego po zauważeniu spadku w segmencie postępuję według następującej kolejności:
- kompletność ExportLog i status wykonania pipeline'u,
oficjalną listę anomalii danych Search Console, aby wykluczyć błąd raportowania po stronie Google,
dane z analityki lub logów serwera, aby odróżnić problem raportowania od realnej zmiany wejść,
- ostatnie zmiany w szablonie lub layoucie,
zmiany w robots.txt, sitemapie, linkach kanonicznych i meta robots,
- raport indeksowania w GSC dla przykładowych URL-i,
logi crawlowania, jeśli masz Cloudflare lub serwerowe access logi,
- zmiany title i description,
- nowa treść konkurencji albo zmiana intencji w SERP,
problemy z renderowaniem, szczególnie przy React/Next.js.
Kolejność zależy od sygnału. Kiedy problem pojawił się bezpośrednio po wdrożeniu i dotyczy konkretnego szablonu, sprawdzenie kodu ma wysoki priorytet. Jeśli natomiast spadły wyświetlenia w całej branży, trzeba uwzględnić sezonowość, popyt i zmiany w wynikach wyszukiwania. Warto przechowywać obok szeregu daty wdrożeń, migracji, kampanii, świąt oraz incydentów. Korelacja czasowa co prawda nie dowodzi przyczyny, ale pomaga ustalać kolejność pracy.
Dobry alert SEO nie ma imponować. Ma skrócić drogę od spadku do pierwszej sensownej decyzji.
Kiedy dołożyć model anomalii
Zwykłe reguły SQL wystarczą na długi czas. Zaawansowany model analityczny ma uzasadnienie dopiero wtedy, gdy zarządzasz wieloma segmentami, uwzględniasz silną sezonowość, prowadzisz działania w różnych krajach lub obsługujesz zróżnicowane typy stron. Funkcja AI.DETECT_ANOMALIES korzysta z wbudowanego modelu TimesFM, który porównuje aktualne wyniki z prognozowanym przedziałem. W wyniku otrzymujesz m.in. flagę is_anomaly, granice przedziału, prawdopodobieństwo oraz status wywołania.
Zanim uruchomisz funkcję, musisz przygotować uporządkowaną, gęstą tabelę z dokładnie jednym wierszem dla każdej poprawnie wyeksportowanej daty oraz kombinacji identyfikatorów. Unikaj przekazywania surowej, nieregularnej tabeli, w której brak wpisu może oznaczać zarówno zerowy ruch, jak i zwykły błąd eksportu danych.
BigQuery domyślnie korzysta obecnie z TimesFM 2.5 i automatycznie dobiera najmniejsze obsługiwane context_window, które mieści wejściowy szereg, dlatego w podstawowym przykładzie nie trzeba podawać tych parametrów. Wybór okna i próg detekcji nie mają jednak uniwersalnego charakteru, dlatego należy je walidować na historycznych incydentach oraz w stabilnych okresach, kiedy nic szczególnego się nie działo. Pamiętaj, że wyższy próg ogranicza liczbę anomalii, ponieważ poszerza przedział ufności. W przypadku segmentów z bardzo małym ruchem nawet poprawnie skonfigurowany i uruchomiony model może jednak nie dostarczyć użytecznego sygnału.
Dlatego traktuj model jako drugą warstwę:
- Warstwa pierwsza obejmuje kontrolę danych i reguły SQL. Jest szybka, przewidywalna i zrozumiała dla zespołu.
- Warstwa druga wykorzystuje model anomalii. Pomaga przy sezonowości i wielu szeregach czasowych.
- Warstwa trzecia wykorzystuje generatywne AI. Redaguje streszczenie i sugeruje pytania do sprawdzenia.
Kontrola kosztów i jakości danych
Koszt zależy od wybranego modelu rozliczeń w BigQuery, ilości faktycznie przetworzonych danych oraz liczby wywołań BigQuery ML i modeli zdalnych, przy czym w standardowym trybie rozliczeń on-demand klauzula LIMIT w żaden sposób nie zmniejsza liczby skanowanych bajtów. W praktyce:
filtruj bezpośrednio po partycji
data_datei sprawdzaj plan zapytania,zapisuj dzienne agregaty do tabeli partycjonowanej i klastrowanej zamiast za każdym razem czytać surowy eksport,
używaj progów wolumenu, żeby nie generować alertów i promptów dla mikrosegmentów,
sprawdzaj
ExportLog, zanim uznasz spadek za problem SEO,materializuj mały zbiór promptów przed wywołaniem modelu,
ogranicz
max_output_tokensi liczbę segmentów wysyłanych do modelu,używaj dry run oraz
maximum bytes billeddo kontroli zapytań,ustaw retencję partycji zgodną z potrzebnym oknem historycznym i polityką danych.


