Automatyzacja AI · Picvelo · 2026 · 3 miesiące (rozwijany)
Google Ads sterowany kodem, nie klikaniem
Kampania powstaje z pliku ze specyfikacją i trafia na konto jako wstrzymana - żaden skrypt nie może przypadkiem zacząć wydawać pieniędzy.
- Node.js
- Google Ads API
- Anthropic API
- SQLite
- Express
- React
- Python
Wyzwanie
Konto reklamowe małego SaaS-a to za mało pracy na agencję i za dużo, żeby zaglądać do niego raz na tydzień. Kampania Performance Max zjadała budżet na ruchu z sieci reklamowej przy kilkunastu groszach za kliknięcie i zerze rejestracji, a rekomendacje systemu sprowadzały się do podniesienia stawek. Do tego dochodzi pytanie, na które panel reklamowy nie odpowiada: która rejestracja w aplikacji naprawdę przyszła z reklamy.
Nasze rozwiązanie
Konto prowadzi się kodem. Definicja kampanii siedzi w pliku ze specyfikacją, skrypt tworzy ją przez API jako wstrzymaną, a każdy zapis idzie najpierw jako walidacja bez zapisu. Do tego worker w cyklu: pobiera dane kampanii i wyszukiwanych fraz, prosi model o listę akcji, przepuszcza je przez warstwę twardych limitów i dopiero potem dotyka konta. Atrybucja nie opiera się na tagu w przeglądarce, tylko na identyfikatorze kliknięcia zapisywanym przy rejestracji po stronie serwera.
Co zbudowaliśmy
- 01 Kampania opisana w pliku i tworzona przez API jako wstrzymana
- 02 Walidacja bez zapisu przed każdą zmianą na koncie
- 03 Worker w cyklu: pobranie danych, propozycje modelu, limity, zapis
- 04 Guard: limit budżetu dziennego, maksymalna zmiana 20%, trzy mutacje na kampanię dziennie
- 05 Whitelist akcji: negatywy, pauza, wznowienie, budżet, flaga do przeglądu
- 06 Blokada podniesienia budżetu przy zerze konwersji przez siedem dni
- 07 Tryby PAUSED i EMERGENCY_STOP - stop dla wszystkich zmian
- 08 Kampania z ręczną flagą, której automat nie dotyka
- 09 Panel React: kampanie, decyzje, akcje ręczne, ustawienia
- 10 Powiadomienia na Telegram, log decyzji i snapshoty w SQLite
Spis treści +
- Punkt wyjścia
- Decyzje, które ukształtowały projekt
- Kampania jako plik, nie jako formularz
- Walidacja przed zapisem, zawsze
- Guard, a nie zaufanie do modelu
- Kampania, której automat nie dotyka
- Log decyzji zamiast czarnej skrzynki
- Prawda o konwersjach po stronie serwera
- Praktyka: przebudowa konta
- Dwa mniejsze narzędzia obok
- Co z tego wyszło
- Technicznie
Punkt wyjścia
Picvelo - nasza platforma dla fotografów - sprzedaje abonament za 30 i 65 zł miesięcznie. Przy takiej cenie budżet reklamowy jest mały, a każda przepalona setka to realny procent kosztów miesiąca. Zostawić konta samego się nie da: wyszukiwane frazy zbierają śmieci, Performance Max rozchodzi się po sieci reklamowej, a system sam z siebie podpowiada głównie zwiększanie budżetu.
Agencja przy tej skali nie ma sensu ekonomicznego. Klikanie w panelu raz na tydzień oznacza tydzień palenia pieniędzy, zanim ktokolwiek zauważy problem.
Decyzje, które ukształtowały projekt
Kampania jako plik, nie jako formularz
Struktura kampanii - grupy, frazy, teksty reklam, stawki - jest opisana w pliku ze specyfikacją i tworzona przez API. Dzięki temu widać w jednym miejscu, co poszło na konto, a zmiana jest edycją pliku, a nie serią kliknięć, których po tygodniu nikt nie odtworzy.
Kampania trafia na konto jako wstrzymana. Nawet udany zapis nie kosztuje ani grosza, dopóki ktoś świadomie jej nie włączy.
Walidacja przed zapisem, zawsze
Google Ads API pozwala wysłać zmianę w trybie samej walidacji: przechodzi pełne sprawdzenie po stronie systemu, łącznie z limitami znaków w tekstach reklam, ale nic nie zmienia. Każda operacja idzie najpierw tak, a zapis jest drugim, świadomym krokiem.
Guard, a nie zaufanie do modelu
Worker pobiera dane, model dostaje je i zwraca propozycje akcji, ale nie ma dostępu do konta. Między nim a API stoi warstwa reguł: maksymalny budżet dzienny, maksymalna jednorazowa zmiana budżetu o 20 procent, najwyżej trzy zmiany na kampanię dziennie, lista dozwolonych typów akcji. Wszystko poza listą zostaje odrzucone i zapisane z powodem odrzucenia.
Osobna reguła blokuje podnoszenie budżetu kampanii, która od siedmiu dni nie ma konwersji. To dokładnie ten ruch, który podpowiada automatyka systemu reklamowego i który przy małym koncie boli najbardziej.
Model nie musi być nieomylny. Musi być ograniczony.
Kampania, której automat nie dotyka
Każda kampania ma flagę ręcznego sterowania. Jeśli człowiek grzebał w niej z panelu, worker ją omija. Bez tego każda ręczna korekta żyje do najbliższego cyklu, a narzędzie, które cofa decyzje właściciela, ląduje w koszu po tygodniu.
Log decyzji zamiast czarnej skrzynki
Do bazy trafia każda propozycja razem z werdyktem i uzasadnieniem. Panel pokazuje to jako listę: co miało być zrobione, co zostało wykonane, co odrzucone i dlaczego. Automat, po którym nie widać, co zrobił, jest gorszy od braku automatu, bo trzeba mu wierzyć na słowo.
Prawda o konwersjach po stronie serwera
Rejestracja jest przypisywana do reklamy na podstawie identyfikatora kliknięcia zapisanego przy zakładaniu konta, a nie na podstawie tego, czy tag w przeglądarce zdążył wystrzelić. Panel właściciela pokazuje więc rejestracje z reklam niezależnie od blokerów, zgód na ciasteczka i błędów po stronie przeglądarki. To liczba, na której podejmuje się decyzje o budżecie.
Praktyka: przebudowa konta
Narzędzia powstały po to, żeby ich użyć. Performance Max zostało wstrzymane, a na jego miejsce weszła kampania w sieci wyszukiwania zbudowana ze specyfikacji: aktywna jedna grupa zamiast trzech, stawki na maksymalizację kliknięć z sufitem 5 zł, budżet 15 zł dziennie. Kampania kieruje na zwykłą stronę produktową, nie na dedykowany landing - o tym, kiedy taki landing page pod Google Ads w ogóle się opłaca, piszemy osobno; tu ruch jest na razie za mały, żeby ten koszt się zwrócił. Do tego reguła wyjścia ustalona z góry: przy określonej kwocie wydanej bez ani jednej rejestracji kampania idzie do wyłączenia.
Ustawiony z góry warunek stopu jest tu równie ważny jak sama kampania. Bez niego test „czy reklama działa” nigdy się nie kończy.
Dwa mniejsze narzędzia obok
reklamypic to warstwa CLI do Google Ads i Meta Marketing API - weryfikacja połączenia i podgląd kampanii z terminala, bez klikania w dwa panele. markit to kalendarz publikacji i pipeline newsletterów w Pythonie na samej bibliotece standardowej, z panelem pokazującym kliknięcia, CTR i pozycje z Search Console w oknach 7, 28 i 90 dni; dostęp do Search Console jest tylko do odczytu.
Żadne z nich nie jest produktem. To narzędzia pod jedną firmę, w rozmiarze, w którym da się je utrzymać.
Co z tego wyszło
Narzędzie działa na jednym koncie - własnym, Picvelo - więc nie ma tu przed-po z cudzej kampanii do pokazania, a konto nie jest publiczne, żeby dało się to zweryfikować z zewnątrz. To, co widać w kodzie i logu decyzji, to dyscyplina: żaden zapis nie omija walidacji, żadna zmiana budżetu nie przekracza 20%, a kampania bez konwersji przez siedem dni nie dostaje podwyżki.
Czego nie wiemy: czy przebudowana kampania w sieci wyszukiwania faktycznie przynosi rejestracje taniej niż wcześniejszy Performance Max. Reguła wyjścia - określona kwota wydana bez konwersji kończy kampanię - jest ustawiona, ale działa od niedawna i nie mamy jeszcze wyniku, który dałoby się tu uczciwie podać. Te narzędzia mierzą i ograniczają ryzyko, nie gwarantują wyniku kampanii - a to jeden z projektów automatyzacji AI dla firm, które budujemy, tym razem dla własnego produktu, nie dla klienta zewnętrznego.
Technicznie
Node.js 20 w ESM, google-ads-api do odczytu i zmian na koncie, @anthropic-ai/sdk z tool use do proponowania akcji, SQLite na snapshoty i decyzje. API na Expressie z logowaniem sesyjnym, panel w React i Vite, całość za nginxem na VPS, cykl workera odpalany timerem systemd. Powiadomienia idą na Telegram. Konfiguracja kont i limitów siedzi w plikach JSON, po jednym na projekt.
Zrzuty ekranu
Podobny problem do rozwiązania?
Napisz krótko, o co chodzi — wycena wraca w 24 godziny.
Zapytaj o wycenę →