Limity wydatków (spend caps) w Google Cloud pozwalają automatycznie wstrzymać użycie objętej nimi usługi po przekroczeniu ustalonej kwoty. Cloud Anomaly Detector pomaga odpowiedzieć na inne pytanie – czy wydatki są normalne dla tego konta i co spowodowało zmianę. Limit pilnuje kwoty. Detektor mówi, gdzie szukać przyczyny.
Jeśli odpowiadasz za konto rozliczeniowe Google Cloud, na którym ktokolwiek ma klucz API do usługi AI, ten tekst jest dla Ciebie. Dowiesz się, co taki limit daje i gdzie się kończy, jak rozłożyć limity na kilkadziesiąt projektów bez zatrzymania produkcji, i dostaniesz trzy komendy, którymi sprawdzisz swoje konto jeszcze dziś.
W pierwszej części opisaliśmy dwa incydenty LLMjackingu i detektor, który drugi z nich zatrzymał w kilka godzin. Od tego czasu system przepracował pełny miesiąc na setkach kont billingowych, zmienił nazwę na Cloud Anomaly Detector i dostał drugą zakładkę, poświęconą limitom wydatków. Zaczynamy od nich, bo to one zmieniają układ sił.
Limit wydatków – jak działa Spend Caps
Budżety w Cloud Billing istniały od dawna, ale tylko powiadamiały. Limit wydatków, po angielsku spend cap, to budżet z włączoną egzekucją: gdy szacowany koszt wskazanej usługi we wskazanym projekcie przekroczy kwotę, Google zatrzymuje nowe żądania do tej usługi. Zakres to jeden projekt i jedna usługa: Gemini API, Gemini Enterprise Agent Platform (dawniej Vertex AI), Cloud Run albo Cloud Run functions. Okres wyłącznie miesięczny, status Preview. Stan dokumentacji na 14 września 2026. Google zapowiada objęcie kolejnych usług w następnych wydaniach. Im więcej usług obejmą Spend Caps, tym więcej da się nimi zatrzymać. Detektor anomalii odpowiada na inne pytanie: czy ten wydatek jest normalny i skąd się wziął.
Co blokuje limit
- Nowe wywołania API wskazanej usługi w tym projekcie
- Do czasu ręcznej edycji budżetu
Co działa dalej
- Compute, storage i inne zasoby trwałe
- Inne projekty i inne usługi
- Koszt żądań w locie, egzekucja nie jest natychmiastowa
Każdemu, kto ma w organizacji choć jeden klucz API do usługi AI, powtarzamy to samo: tam, gdzie Spend Caps są dostępne, załóż limit na każdym projekcie, w którym ta usługa jest włączona, i na każdym, w którym nie jest. Ten drugi przypadek jest ważniejszy. Majowy incydent z części pierwszej to atakujący włączający usługę AI w projekcie, który nigdy jej nie używał. Limit na sto euro w projekcie, który nie ma prawa wydać ani centa na AI, pomaga ograniczyć koszt takiego nadużycia. Kwotę trzeba dobrać świadomie, uwzględniając opóźnienie egzekucji.
Limit na projekcie i monitoring całego konta
Limit wydatków chroni wskazaną parę projekt × usługa. Monitoring całego konta obejmuje również koszty nowo podłączanych projektów. Domyślna konfiguracja Google Cloud nadaje rolę Project Creator wszystkim użytkownikom domeny, a Billing Account User bywa rozdany szerzej, niż ktokolwiek pamięta. Przy takich uprawnieniach skrypt może założyć nowy projekt, podpiąć billing i uruchomić usługę AI. Wszystkie Twoje limity i budżety projektowe stoją w starych projektach.
W jednym z włamań, przy których pomagaliśmy, atakujący utworzył nowy projekt i podpiął go pod konto rozliczeniowe ofiary. Klient zobaczył rachunek, którego nie umiał sobie wytłumaczyć, i poprosił nas o pomoc. Pierwsze pytanie nie brzmiało „kto", tylko „który projekt". Dopóki koszt nie ma adresu, w logach nie ma czego szukać.
Gdy projekt był już znany, resztę dopowiedziały logi audytowe. Ten projekt nie należał do żadnego środowiska, które klient rozpoznawał, bo ktoś założył go od zera i podpiął pod konto rozliczeniowe. Ten przypadek pokazuje, dlaczego warto obserwować zmiany na całym koncie rozliczeniowym. Nowy projekt pojawił się na nim jako nowa pozycja kosztowa. Nowa encja, która od pierwszej godziny wydaje, jest dla detektora osobnym typem anomalii.
Stąd zasada dla całego portfela: limit wydatków egzekwuje ustaloną kwotę, a detekcja na poziomie konta rozliczeniowego rozpoznaje nietypowe zmiany, także w nowych projektach. Do tego dwie rzeczy po stronie IAM, które kosztują niewiele: odebranie domyślnej roli Project Creator całej domenie i przegląd, kto naprawdę ma Billing Account User.
Kiedy wystarczą limity i ręczny przegląd
Kilka projektów, jeden zespół, Project Creator odebrany domenie: wtedy limity na obsługiwanych parach projekt × usługa AI, budżet na całe konto i regularny przegląd wydatków mogą wystarczyć do codziennej kontroli kosztów. Ta rada przestaje działać, gdy projektów jest kilkadziesiąt, a lista osób z prawem do tworzenia projektów jest dłuższa niż lista ludzi, którzy o tym wiedzą.
Jak podeszliśmy do limitów w skali
Przy setkach kont i tysiącach projektów potrzebna jest mapa. Zbudowaliśmy ją jako drugą zakładkę dashboardu detektora. Kilka decyzji z tej pracy przenosi się na każdą skalę.
Pierwsza dotyczy mianownika, czyli tego, co w ogóle wchodzi do rachunku pokrycia. Liczymy każdy projekt podpięty do konta, także taki, który nigdy nie dotknął AI. Gdybyśmy liczyli wyłącznie projekty już używające AI, mapa świeciłaby się na zielono i nie mówiła nic o ryzyku. Zabezpieczasz to, co atakujący dopiero włączy.
Druga: budżet bez filtra usługi nie jest limitem, tylko alertem, i nie wolno go wliczać do pokrycia. Gdy policzyliśmy to naiwnie, pokrycie wyszło kilkadziesiąt razy lepsze, niż było naprawdę.
Trzecia dotyczy kwoty. Proponuje ją historia konta: większa z dwóch wartości, średniej z pełnych miesięcy i ostatniego pełnego miesiąca. Bieżący miesiąc jest wykluczony, bo limit policzony w połowie miesiąca jest policzony z połowy ruchu. Zaokrąglamy zawsze w górę – limit zaokrąglony w dół stoi poniżej ruchu, pod który był liczony. Projekt bez wydatku dostaje kwotę symboliczną.
Czwarta jest o kolejności. Listę robimy od najmniejszych środowisk, bo tam pomyłka kosztuje najmniej, a projektów bez historii jest najwięcej. Duże środowiska z realnym ruchem na AI dostają limit dopiero po rozmowie o kwocie. Źle dobrany limit zatrzyma produkcję klienta równie skutecznie jak atak.
I reguła, której nie wolno złamać: to, co potwierdziło API, i to, co człowiek oznaczył ręcznie w konsoli, mają na mapie osobne kolory i nigdy nie sumują się w jeden procent. Deklaracja jest cenna, bo niesie nazwisko i datę. Dowodem jest tylko odczyt.
Miesiąc produkcji: między „odstaje" a „warto obudzić człowieka"
Detektor porównuje każde konto wyłącznie z jego własną historią, więc w każdym przebiegu kilkanaście kont odstaje od normy, i tak ma być. Cała wartość systemu siedzi w tym, jak z tych obserwacji wybiera kilkanaście w miesiącu, przy których ma prawo komuś przerwać dzień.
Konkret z 3 września. Konto, które zwykle wydaje kilkanaście euro dziennie, w jednej dobie wydało 500. Mnożnik ×23, wzrost o 2200 procent, praktycznie całość na jednej usłudze map. Detektor zobaczył to o 3:00 w nocy i przez kolejne 21 godzin potwierdził 42 razy. Nie obudził nikogo, bo 500 euro nie przebija progu kwotowego, przy którym wolno komuś przerwać dzień.
Alert wyszedł następnego dnia rano, ale z innego detektora. Prognoza na koniec miesiąca sięgnęła 6000 euro wobec 900 w poprzednich miesiącach. Dzień był za mały, miesiąc już nie.
To nie był atak. U klienta przestała działać część mapowa, ruch przepiął się na zapasowy projekt i zaczął generować koszt tam, gdzie nikt go nie pilnował. Awaria, nie włamanie, a rachunek rósłby tak samo długo, jak długo nikt by nie zajrzał.
Alert ma wskazać palcem
Dwa z szesnastu alertów skończyły się wspólną sesją z klientem. W obu przypadkach wyglądało to tak samo: karta mówiła, że konto wydaje wielokrotnie więcej niż zwykle, a po drugiej stronie nikt nie potrafił wskazać, z którego projektu to leci ani który klucz za tym stoi. Konto rozliczeniowe to za gruby adres, żeby cokolwiek z nim zrobić.
Detekcja zeszła więc niżej, na pojedynczy projekt i pojedynczy SKU, czyli najdrobniejszą pozycję, jaką Google wypisuje na fakturze. Usługi na karcie sortujemy po tym, o ile realnie urosły w pieniądzach, nie po procentach. Usługa, która skoczyła z centa na siedem euro, urosła o siedemset procent i jest bez znaczenia. Usługa, która urosła o siedem tysięcy euro, jest całym zdarzeniem.
Rozbicie liczy się w tym samym przebiegu co reszta karty i to nie jest szczegół implementacyjny. Eksport billingowy dopełnia okno jeszcze wiele godzin po alercie, więc usługi policzone dopiero przy otwieraniu karty pochodziłyby z późniejszego stanu danych niż kwota w nagłówku. Karta ma być zdjęciem jednej chwili, nawet jeśli ta chwila jest niekompletna.
Baseline odporny na to, co mierzy
Najpierw bez matematyki. Detektor odpowiada codziennie na jedno pytanie: czy dzisiejszy koszt jest normalny dla tego konta? Potrzebuje do tego dwóch liczb: co jest normą i o ile dzień zwykle od niej odbiega. Kłopot zaczyna się wtedy, gdy w ostatnim tygodniu zdarzył się już jeden zły dzień.
Przykład. Konto wydaje około 20 euro dziennie. W poniedziałek ktoś uruchamia inferencję za 900, we wtorek za 640. Poniedziałek złapie każda metoda, bo 900 wobec 20 to inny świat. Ciekawy jest wtorek.
Ze średnią. Średnia z ostatnich siedmiu dni, w tym z poniedziałku za 900, wynosi 146. Zwykły rozrzut, liczony z tych samych dni, urósł z 2 do ponad 300, bo poniedziałek rozciągnął go w górę. Wtorek za 640 jest od tej nowej normy oddalony o niecałe dwa takie rozrzuty. Dla statystyki to zwykły dzień. Alarm gaśnie w środku incydentu.
Z medianą. Mediana to środkowa wartość po posortowaniu. Siedem dni to 17, 19, 20, 21, 22, 23 i 900, środkowa to 21. Poniedziałek stoi na końcu listy i nie ma nic do powiedzenia. Rozrzut liczymy tą samą sztuczką: bierzemy odległość każdego dnia od 21 i znowu środkową z nich, wychodzi 2. To jest MAD, mediana odchyleń. Wtorek za 640 jest oddalony od normy o kilkaset takich rozrzutów. Alarm trwa, bo powinien.
| Średnia | Mediana | |
|---|---|---|
| Norma po poniedziałku | 146 | 21 |
| Zwykły rozrzut | ponad 300 | 2 |
| Wtorek za 640 | prawie normalny dzień | alarm |
Rozrzut ma minimum, bo konto wydające równo 20, 20, 20 miałoby rozrzut zero i każdy cent wyglądałby jak katastrofa. A dzień bez wiersza w eksporcie liczy się jako koszt zero, żeby tydzień ciszy nie zniknął z historii. Suwaki pod wykresem pokazują obie linie na tej samej serii.
Dwie pułapki obok. Dzień bieżący: o szóstej rano konto ma za sobą sześć godzin, więc porównane z pełnymi dobami zawsze wygląda na spadek. Porównujemy więc dzisiejsze sześć godzin z tymi samymi sześcioma godzinami poprzednich dni. Detekcja godzinowa: jeśli badana godzina siedzi w tej samej próbce, z której liczysz normę, to sama tę normę podnosi i nigdy nie odstanie od niej na tyle, żeby przebić próg. Godzina za pół miliona wygląda wtedy na lekko podwyższoną. Badaną godzinę trzeba z próbki wyłączyć.
System musi wiedzieć, czego nie widzi
Najgroźniejszy stan detektora anomalii to cisza, która wygląda jak spokój.
25 sierpnia eksport billingowy przestał pisać. Nie jedno źródło, wszystkie, jedno po drugim w odstępie kilkudziesięciu minut. Detektor chodził dalej co pół godziny, skanował tabele, które od rana się nie zmieniały, i za każdym razem raportował, że nie ma anomalii. Przez sześć godzin nikt nie patrzył na flotę, a jedynym śladem tego stanu był pasek na dashboardzie, na który ktoś musiał sam spojrzeć.
Naprawiliśmy to jeszcze tego samego dnia i od razu przesadziliśmy: martwe źródło zaczęło budzić dyżurnego. Tej nocy, tuż po północy, on-call dostał telefon o zamrożonej tabeli eksportu, z którą i tak nie mógł nic zrobić do rana. Następnego dnia wycofaliśmy tę ścieżkę. Pager jest dziś zarezerwowany dla kosztu, a awaria źródła ma własny kanał i próg liczony w godzinach milczenia, bo źródło migające przez kwadrans nie jest incydentem, a takie, które milczy pół doby, jest.
Cztery stany, które w naiwnym kodzie wyglądają identycznie jak „brak anomalii":
Eksport nie pisze od godzin
Detektor skanuje zamrożone tabele i raportuje sukces. Potrzebna jest osobna metryka: jak dawno źródło cokolwiek zapisało, z progiem liczonym w godzinach milczenia.
Zapytanie padło
Pusta lista, bo zapytanie padło, i pusta lista, bo nic nie znaleziono, to dwa różne fakty i kod musi je rozróżniać. Przebieg, który nie widział floty, kończy się błędem zamiast raportem.
Konto bez pełnego miesiąca historii
Prognoza nie powstaje i słusznie, bo nie ma z czego. Ale konto jest liczone i widoczne jako „nieocenione", z datą, od której zacznie być oceniane.
Zero kont zamiast setek
Pusty wynik oznacza awarię przebiegu. Pusta flota zdarza się tylko przy pierwszym wdrożeniu i wtedy trzeba to zadeklarować wprost.
Brak danych to nie zero. Każda ścieżka, która nie potrafi udowodnić, że patrzyła na dane, kończy przebieg błędem widocznym w monitoringu. Alternatywą jest zielony dashboard nad flotą, której nikt nie ogląda.
Jak sprawdzić to u siebie
Trzy komendy odpowiadają na pytanie z tego tekstu: czy pod Twoim kontem rozliczeniowym może pojawić się projekt, o którym nikt nie wie. Pierwsza listuje projekty podpięte do konta z datą utworzenia, najnowsze na górze. Druga pokazuje, kto w organizacji może tworzyć projekty. Trzecia, kto może podpinać je pod billing.
$ gcloud billing projects list --billing-account=0A1B2C-3D4E5F-6A7B8C --format="value(projectId)" \ | xargs -I{} gcloud projects describe {} --format="csv[no-heading](projectId,createTime.date('%Y-%m-%d'))" \ | sort -t, -k2 -rgen-ai-tmp-4471,2026-09-10 ← utworzony wczoraj, zero historii kosztówshop-prod,2023-04-12shop-staging,2023-04-12data-warehouse,2022-11-03mobile-backend,2021-06-30 $ gcloud organizations get-iam-policy 123456789012 --flatten="bindings[].members" \ --filter="bindings.role:roles/resourcemanager.projectCreator" --format="value(bindings.members)"domain:example.com ← cała domena może tworzyć projekty (domyślne)group:cloud-admins@example.com $ gcloud billing accounts get-iam-policy 0A1B2C-3D4E5F-6A7B8C --flatten="bindings[].members" \ --filter="bindings.role:roles/billing.user" --format="value(bindings.members)"group:cloud-admins@example.comuser:dev-2019-contractor@example.com ← klucz sprzed lat, nikt nie pamięta po coserviceAccount:ci-legacy@shop-prod.iam.gserviceaccount.com
domain: przy Project Creator oznacza domyślną konfigurację Google Cloud: każdy w firmie może założyć projekt.Te same trzy komendy do skopiowania w całości. Uzupełniasz dwie zmienne na górze i wklejasz resztę bez zmian. Identyfikator konta znajdziesz w gcloud billing accounts list, numer organizacji w gcloud organizations list.
export BILLING_ACCOUNT_ID="0X0X0X-0X0X0X-0X0X0X" # gcloud billing accounts list
export ORG_ID="123456789012" # gcloud organizations list
echo "== 1. Projekty podpięte do konta $BILLING_ACCOUNT_ID, najnowsze na górze =="
gcloud billing projects list --billing-account="$BILLING_ACCOUNT_ID" --format="value(projectId)" \
| xargs -I{} gcloud projects describe {} --format="csv[no-heading](projectId,createTime.date('%Y-%m-%d'))" \
| sort -t, -k2 -r
echo; echo "== 2. Kto może tworzyć projekty w organizacji $ORG_ID =="
gcloud organizations get-iam-policy "$ORG_ID" --flatten="bindings[].members" \
--filter="bindings.role:roles/resourcemanager.projectCreator" --format="value(bindings.members)"
echo; echo "== 3. Kto może podpinać projekty pod konto $BILLING_ACCOUNT_ID =="
gcloud billing accounts get-iam-policy "$BILLING_ACCOUNT_ID" --flatten="bindings[].members" \
--filter="bindings.role:roles/billing.user" --format="value(bindings.members)"
Przejrzyj listę projektów
Każdy projekt, którego nie rozpoznajesz, dostaje właściciela albo znika. Powtarzaj co tydzień, najlepiej z harmonogramu i mailem.
Zawęź Project Creator i Billing Account User
Odbierz domenie domyślną rolę, zostaw grupę administratorów. Lista z prawem do podpinania billingu ma mieścić się na jednej dłoni.
Limit na każdej parze projekt × usługa AI
Także tam, gdzie AI nie jest używane. Kwota symboliczna, zaokrąglona w górę od historii tam, gdzie ruch jest realny.
Budżet na całe konto
Z progiem dobranym do realnych wydatków, nie do okrągłej liczby. Obejmie także wydatki nowych projektów podpiętych do tego konta.
Te cztery kroki zajmują popołudnie i nie wymagają żadnego narzędzia poza konsolą. Zamykają scenariusz z tego tekstu w małym środowisku i mocno go utrudniają w dużym.
Podsumowanie
Spend Caps w Google Cloud automatycznie egzekwują ustaloną kwotę dla objętych nimi usług. Zakładaj je wszędzie, gdzie się da, ze szczególnym uwzględnieniem projektów, które AI nie używają. Cloud Anomaly Detector dokłada drugą warstwę: porównuje wydatki z historią konta, pokazuje, co się zmieniło, i budzi kogoś, kto może zareagować. Nietypowy wydatek może wymagać uwagi także wtedy, gdy mieści się w miesięcznym limicie.
Spend Caps pilnują ustalonej kwoty. Cloud Anomaly Detector pomaga rozpoznać nietypowy koszt i ustalić, co z nim zrobić.
Cztery kroki wyżej wystarczą, żeby zacząć. Gdy środowisko rośnie, sprawdzaj, czy limity nadal obejmują to, co powinny. Granica jest tam, gdzie zaczyna się pytanie „czy to atak, czy nowy feature" przy kilkudziesięciu projektach i kluczach rozdanych latami. W FOTC robimy to jako Cloud Anomaly Detector: monitoring konta rozliczeniowego co pół godziny z alertami do Twojego zespołu i do naszego, a gdy alert już przyszedł i nie wiesz, co z nim zrobić, także jako godzinowe wsparcie inżyniera bez długiej umowy. Jeśli wolisz zrobić to sam, wszystko powyżej jest wystarczające, żeby zacząć.
FAQ
Czy limit wydatków uchroni mnie przed LLMjackingiem?
Ograniczy rachunek w projektach, które nim objąłeś. Nie zatrzyma ataku: egzekucja nie jest natychmiastowa, żądania w locie zostaną zafakturowane, a atakujący z prawem do tworzenia projektów założy nowy. Limit, detekcja na poziomie konta i przegląd ról Project Creator oraz Billing Account User zamykają trzy różne luki. Żaden z nich nie zastąpi pozostałych.
Po co Cloud Anomaly Detector, jeśli mam Spend Caps?
Spend Caps wstrzymują użycie wskazanej usługi po przekroczeniu ustalonej kwoty. Detektor szuka odchyleń od normalnych wydatków konta i pomaga wskazać projekt oraz usługę odpowiedzialne za zmianę. Może zgłosić anomalię mieszczącą się w limicie, o ile spełnia ona warunki alertowania. Korzysta z eksportu billingowego, więc czas detekcji zależy od dostępności danych. Nie ma gwarancji, że alert pojawi się przed zadziałaniem Spend Caps.
Jaką kwotę ustawić w projekcie, który nie używa AI?
Symboliczną, rzędu stu euro miesięcznie. Tyle, żeby nikt nie zauważył jej przy legalnym teście, i na tyle mało, żeby zatrzymała nadużycie, zanim urośnie. Gdy projekt zaczyna AI używać naprawdę, limit podnosisz świadomie.
Czy limit może zatrzymać mi produkcję?
Tak, i to jest jego zadanie. Źle dobrana kwota na projekcie z realnym ruchem zatrzyma legalną inferencję, a zdjęcie limitu wymaga człowieka i trwa do godziny. Dlatego na projektach produkcyjnych kwota wynika z historii i zaokrągla się w górę, a ktoś z dostępem do budżetu musi być osiągalny także w weekend.
Co jeśli eksport billingowy do BigQuery przestanie działać?
To jedyny stan, którego detektor kosztowy sam nie zauważy, bo brak danych wygląda jak brak wydatków. Świeżość źródła musi być osobną metryką z osobnym alarmem, a dashboard ma mówić „nie widzę" innym kolorem niż „nic się nie dzieje".
Opis limitów wydatków pochodzi z publicznej dokumentacji Google Cloud, sprawdzonej 14 września 2026. Dokumentacja nadal oznacza Spend Caps w Cloud Billing jako Preview i zapowiada rozszerzenie listy usług. Liczby o pracy detektora są rzeczywiste i pochodzą z jego logów. Mapa pokrycia i wykres baseline'u są ilustracjami mechanizmu, nie zrzutami z produkcji. Artykuł opisuje system w wersji 6.x (2026).