Jest taka wersja tej historii, która mieści się w jednym tweecie. Zeskrap ogłoszenia o pracę, niech AI je poukłada, wyślij maile do zwycięzców. Generowanie leadów rozwiązane. Trochę w to wierzyłem na starcie. Potem zbudowałem to coś i okazało się, że cała ciekawa robota jest wszędzie tam, gdzie AI akurat nie ma.
Więc tu jest wersja długa. Jak naprawdę powstaje agent do outbound prospectingu, od początku do końca, razem z tym co się sypało i co kosztowało pieniądze. Jeśli sam próbujesz zautomatyzować prospecting B2B, to jest dokładnie to, co chciałbym przeczytać, zanim zacząłem.
Większość narzędzi do „generowania leadów” optymalizuje pod wolumen. Więcej kontaktów, więcej wierszy, większa baza. To jest dokładnie odwrotność tego, czego handlowiec potrzebuje w poniedziałek rano.
On potrzebuje krótkiej listy. Właściwe firmy, z realnym powodem do rozmowy w tym tygodniu, i konkretna osoba z mailem, najlepiej z telefonem. Dwadzieścia dobrych wierszy bije dwa tysiące zimnych, bo nikt nie przerobi dwóch tysięcy wierszy. Zostają zignorowane i cały system po cichu umiera.
Więc każda decyzja niżej służy jednemu - zrobić listę krótszą i bardziej trafną, nie dłuższą. Brzmi oczywiście. I prawie nikt tego nie robi, bo dorzucanie wierszy jest łatwe, a usuwanie tych złych jest trudne.
Wyzwalaczem całości jest rekrutacja. Firma, która nagle wrzuca więcej ogłoszeń, zwykle buduje zespół, reorganizuje się albo jest pod jakąś presją. Każdy z tych powodów to powód, żeby się odezwać. To publiczny, darmowy, tygodniowy sygnał i większość ludzi go ignoruje.
Dwa portale z ofertami pracy - Pracuj.pl i OLX - są skrapowane w każdą niedzielę wieczorem. Każdy przebieg ląduje w jednej tabeli w BigQuery z datą skrapu wbitą w wiersz. Tyle - bez wymyślnego magazynu, jedna tabela, jedna kolumna z datą. Ta data to cały trik, bo sygnałem nie jest „ta firma ma 40 otwartych rekrutacji”. Sygnałem jest „miała 12 tydzień temu, a teraz ma 40″.
Obok skrapera chodzi drugie, ręczne źródło. Wrzucam screeny postów z LinkedIna i newsów do folderu na Google Drive - runda finansowania, nowy zakład, post „zatrudniamy 50 osób”. Scenariusz w Make pilnuje tego folderu, wysyła każdy obrazek do Claude i dostaje z powrotem dwa pola: nazwę firmy i typ sygnału, rekrutacja albo news. To leci do osobnej tabeli, deduplikowane po nazwie pliku, żeby ten sam screen nie wszedł dwa razy.
I to jedyne miejsce, gdzie AI robi w całym tym pipelinie realną robotę - czyta obrazki. Zapamiętaj to.
Jak masz dwa tygodniowe snapshoty, to je porównujesz. Dla każdej firmy liczysz trzy rzeczy: wzrost otwartych ról w liczbach, wzrost procentowy i to, czy firma jest nowa w tym tygodniu - jest teraz, nie było tydzień temu.
Lista procentowa dostaje próg. Firma musi mieć minimum pięć aktualnych ogłoszeń, żeby się załapać. Inaczej skok z jednego ogłoszenia do trzech pokazuje się jako „+200% wzrostu” i zaśmieca górę listy szumem. Mały bezpiecznik, duża różnica.
Z dziesiątek tysięcy zeskrapowanych wierszy zostaje kilkaset firm, które faktycznie się ruszyły. Z tego tnę trzy listy - największy wzrost w liczbach, największy wzrost procentowy i te zupełnie nowe - i biorę górne dwadzieścia parę z każdej. Sygnały ze screenów są czwartą listą i tej już nie przycinam, bo to są moje świadome wybory, nie wolumen do obcięcia.
Cztery krótkie listy. Teraz trudna część.
I tu jest to, czego nie pokazują na demie. W momencie, w którym próbujesz tej listy użyć, okazuje się, że połowa jest dla Twojego działu sprzedaży bezużyteczna. Aktualni klienci. Byli klienci. Firmy, do których ktoś pisał w marcu. Marka, która okazuje się należeć do konta podpisanego rok temu.
Jak wyślesz taką listę jak leci, to robisz gorzej, niż było. Masz handlowców zaczepiających na zimno własne konta. Więc zanim cokolwiek trafi na listę, każdy kandydat jest zderzany z CRM-em.
Biorę pełny eksport firm z CRM-u - jakieś dwa tysiące kont, z NIP-em, datą ostatniej aktywności, statusem klienta i, co najważniejsze, z zadaniami zaplanowanymi na danej firmie. Potem wyrzucam każdego, kto jest aktualnym albo byłym klientem, był aktywny w ostatnich dziewięćdziesięciu dniach, albo ma na sobie zaplanowane zadanie. Ten sygnał z zadaniem jest ważniejszy, niż się wydaje. Jeśli handlowiec ma na firmę umówiony telefon na przyszły tydzień, to ta firma jest w robocie i nie ma prawa wyskoczyć jako zimny lead. Koniec tematu.
Jeden niuans, z którego jestem zadowolony - szansa, która jest otwarta, ale nikt jej nie tknął od ponad dziewięćdziesięciu dni, wraca do gry. Zamrożony deal, którego nikt nie ruszył od trzech miesięcy, jest dobrym celem na nowy kąt. Blokowanie go na zawsze tylko dlatego, że kiedyś był w CRM-ie, to sposób, w jaki dobre leady idą do piachu.
Mała dygresja, czemu eksportuję listę firm ręcznie, zamiast ciągnąć ją przez API. Endpoint „wylistuj wszystkie firmy” timeoutuje na 40-sekundowym limicie platformy automatyzacji. Endpoint do odczytu zadań zwraca „brak uprawnień” dla użytkownika API. Zamiast walczyć tydzień z uprawnieniami i timeoutami, eksportuję listę z UI i ją wgrywam. Nudne, niezawodne, zrobione. Czasem właściwa decyzja inżynierska to ta najmniej efektowna.
Tu straciłem najwięcej czasu i tu po cichu wykłada się większość domowych systemów do prospectingu.
Ogłoszenia mówią „Orlen Paczka”. CRM trzyma pełną nazwę prawną ze „sp. z o.o.” na końcu. Ta sama firma. Dopasowanie po dokładnej nazwie nie łapie z tego nic.
Więc budujesz normalizator. Ścina formy prawne - sp. z o.o., S.A., rozpisane w całości „spółka z ograniczoną odpowiedzialnością”, wszystkie literówki, które ludzie wklepują. Składa polskie znaki do czystego ASCII, więc ł robi się l, a ą robi się a, bo te dwie bazy nigdy nie zgadzają się co do ogonków. Potem dopasowuje po prefiksach, więc „otto work force” trafia w „otto work force europe”. Jest nawet reguła na prefiksy grup typu „grupa” i „gk”, żeby „Grupa LUX MED” rozwiązało się do spółki-matki.
A potem są przypadki, których żaden algorytm nie złapie. Biedronka należy do Jeronimo Martins. Hebe też. Żadne czyszczenie stringów nie sprawi, że „Biedronka” będzie wyglądać jak „Jeronimo Martins”. Na to trzymasz ręcznie pisaną tabelę aliasów i dokładasz do niej, kiedy wyłapiesz przeciek. Jest ręczna, trochę wstydliwa i jest jedyną rzeczą, która działa, dopóki nie masz twardego klucza, jak NIP, po obu stronach.
Całe to dobro żyje jako pliki SQL i CSV w repo gita. Nie wyklikane w UI narzędzia. Ta decyzja waży więcej, niż brzmi. Jak klient zapyta, czemu jakaś firma została zaczepiona dwa razy, to czytam diffa i mówię mu dokładnie, która reguła ją przepuściła i kiedy się zmieniła. Z logiką zakopaną w no-codowym canvasie tego nie zrobisz.
Nazwa firmy to nie lead. Nie napiszesz maila do „Orlen Paczki”. Więc krok wzbogacania zamienia nazwy w ludzi.
Najpierw nazwa na domenę. Wyszukiwarka firm w Apollo bierze oczyszczoną nazwę i zwraca stronę. Tam, gdzie dostaję domenę - a to jest duże „tam”, za chwilę o tym - ciągnę kontakty z HR i zarządu na tej domenie, z capem trzy osoby na firmę, zdeduplikowane, żeby ta sama osoba nie pojawiła się dwa razy. Potem dobijam maile, jeden po drugim.
Telefony to osobny problem. Apollo znajduje maile bez problemu. Polskie komórki - praktycznie zero. Więc zweryfikowane numery biorę z drugiego narzędzia, Prospeo, odpytując je po linku LinkedIn danej osoby, ustawione tak, żeby zwracało tylko zweryfikowane numery komórkowe. Dobra strona tego ustawienia jest taka, że obciąża konto tylko wtedy, kiedy faktycznie znajdzie numer. Nie ma numeru, nie ma opłaty.
Teraz niewygodna prawda. Apollo zwraca używalną domenę dla może jednej firmy na trzy. Czyli dwie trzecie czystej, dobrze przefiltrowanej listy nigdy nie dochodzi do etapu kontaktów - czysto dlatego, że krok nazwa-na-domenę spudłował. To jest aktualny sufit całego systemu. Nie skraping, nie AI, tylko nudna luka w dopasowaniu. To następna rzecz, którą naprawiam, i jeszcze jej nie rozgryzłem.
Wzbogacanie to jedyna część, która kosztuje realne pieniądze, więc to jedyna część, w której musisz być bezwzględny.
Darmowe zapytania - szukanie firmy, szukanie ludzi na domenie - nie kosztują nic. Drogie są dopasowanie maila i odpytanie o telefon, płatne od wyniku. Więc capujesz osoby na firmę do trzech, deduplikujesz ostro po domenie i odpalasz całość raz w tygodniu, nie przy każdej zmianie. Ta matma to różnica między kilkuset kredytami na miesiąc a wypaleniem płatnego planu w tydzień.
Drogi sposób, żeby się tego nauczyć, to ten, w jaki ja się nauczyłem. Wcześniejsze ustawienie wpuszczało nazwy do wzbogacania, zanim przejechał filtr CRM. Efekt był taki, że Apollo radośnie wzbogacało naszych własnych klientów, w kółko, plus stertę duplikatów. Lekiem nie był większy plan. Lekiem było przesunięcie filtra przed wydatek. Najpierw filtr, potem enrichment, zawsze.
Nudne podsumowanie. Skrapery odpalają w niedzielę wieczorem, żeby dane były świeże. Loadery wpychają oba portale do BigQuery kilka godzin później. W poniedziałek rano leci reszta - porównanie, filtr, trzy listy plus lista ze screenów, wzbogacanie, telefony - i wszystko ląduje w jednym arkuszu Google, ułożonym dokładnie w formacie importu do CRM-u. Firma, osoba, stanowisko, mail, telefon, LinkedIn, źródło, właściciel i powód, dla którego ten wiersz został wybrany.
Handlowiec otwiera ten arkusz, zanim wystygnie mu kawa, i zaczyna pisać. Bez researchu. Bez czyszczenia. I o to chodzi.
Skraping i AI to łatwe dziesięć procent. Działają od pierwszego dnia i robią świetny screen. Jeśli zbudujesz tylko to, zbudowałeś zabawkę.
Prawdziwa robota to trzy mało efektowne rzeczy. Filtr, który nie pozwala Ci pitchować własnych klientów. Dopasowanie nazw, które sprawia, że ten filtr w ogóle działa między dwiema bazami, które nigdy się nie zgadzają. I dyscyplina kredytowa, która nie pozwala wzbogacaniu po cichu wydrenować budżetu. Zrób te trzy dobrze, a część z AI prawie przestaje mieć znaczenie - moje czyta screeny i tyle.
Zbuduj ten rdzeń w kontroli wersji, nie w SaaS-owym UI, którego nie zdiffujesz. W dniu, w którym ktoś zapyta, czemu lead został zaczepiony dwa razy, będziesz chciał tę odpowiedź przeczytać, a nie zgadywać.
Zajęło dłużej, niż chciałbym przyznać. I teraz robi się samo, co tydzień, kiedy ja robię coś innego. Ten deal był wart swojej ceny.