Przejdź do treści
megapromotingPorozmawiajmy

Ekspertyza · Treści automatyczne

Przepływ, który sam wyszukuje tematy dnia, pisze artykuł, tłumaczy go na dziewiętnaście języków i publikuje — ale dopiero po przejściu przez bramkę weryfikacyjną, która, gdy nie może zweryfikować, niczego nie publikuje.

Silnik jest napisany w całości i znajduje się w samym repozytorium tej strony: osiem etapów, 1.706 linii, systemowy timer uruchamiany codziennie o 00:30 UTC. Część, która ma znaczenie, to nie generowanie, lecz bramka: pięć lokalnych weryfikacji, dziesięć zakazanych wyrażeń i dodatkowa kontrola, która szuka nazw klientek i klientów bez zgody, zmyślonych liczb i nagród, których nie mamy. Jeśli bramka nie może się uruchomić, nic nie jest publikowane.

Już zbudowane„delivered”, pentru că lucrarea există ca fișiere pe care le puteți deschide, nu ca descriere: `scripts/content-engine/` din depozitul megapromoting.com, 17 fișiere, 1.706 linii de TypeScript, unitate systemd cu cronometru, opt etape legate cap la cap și jurnale ale rulărilor. Cu o rezervă pe care o spunem noi, nu o aflați voi: **singura rulare completă din jurnale nu a publicat niciun articol.** Poarta le-a oprit pe toate trei — două pentru că verificarea nu a putut rula deloc, a treia pentru un câmp lipsă din antet. `publish` a rămas gol, IndexNow a primit zero adrese. Rularea a fost locală, pe stația de lucru, și a durat două ore și jumătate, adică peste limita de 60 de minute pusă în unitatea systemd — deci pe server ar fi fost oprită. Nu putem confirma din exterior că motorul rulează azi pe server, și nu o pretindem.

Automatyzacja, która sama pisze i publikuje, to miejsce, gdzie najłatwiej obiecać to, czego nie da się zrobić. Model pisze tysiąc przekonujących słów o wszystkim, także o rzeczach, które się nie wydarzyły, i robi to równie płynnie. Jeśli między modelem a przyciskiem publikacji nic nie stoi, zbudowałeś maszynę do wrzucania błędów do internetu, w dwudziestu językach, każdej nocy. Cała praca polega na tym, co stoi pośrodku.

Nasz przepływ ma osiem etapów. Zbiera tematy z otwartych źródeł, nadaje im ocenę od 0 do 100 za dopasowanie, odrzuca wszystko poniżej 50, wybiera pierwsze N według zasady różnorodności, żeby nie powstało dziesięć artykułów o tym samym, pisze artykuł po rumuńsku, tłumaczy go na dziewiętnaście języków, przepuszcza przez bramkę, i dopiero potem publikuje. Każdy etap zapisuje swój koszt i wynik w dzienniku, aby można było odtworzyć przebieg uruchomienia później.

Brama ma dwie warstwy. Pierwsza jest lokalna i nic nie kosztuje: nagłówek musi istnieć i mieć tytuł, opis oraz słowa kluczowe; tekst musi przekraczać 1.200 słów; musi mieć co najmniej trzy podtytuły, co najmniej trzy wewnętrzne linki i sekcję pytań z minimum trzema parami; i nie może zawierać żadnego z dziesięciu wyrażeń marketingowych, które umieściliśmy na czarnej liście. Druga warstwa to model, który szuka czegoś innego: nazwy klienta bez dowodu zgody, wymyślone statystyki, błędne twierdzenia o tym, co możemy zrobić, oraz nagrody, których nie mamy — lista tych prawdziwych jest zapisana w weryfikacji, a wszystko inne jest sygnalizowane.

Istnieje ludzka akceptacja w łańcuchu i mówimy o tym jako o argumencie, nie jako o wymówce. Artykuły, które nie przechodzą surowych kontroli, są odrzucane, nie publikowane. Te, które przechodzą surowo, ale dostają sygnały z drugiej weryfikacji, są zachowywane z oznaczeniem, aby człowiek mógł je sprawdzić. A jeśli weryfikacja nie może się uruchomić — na przykład dlatego, że usługa modeli nie odpowiada — artykuł jest traktowany jak odrzucony. Fail-closed, nie fail-open. Tak właśnie stało się przy jedynym pełnym uruchomieniu w logach i dlatego nic nie zostało opublikowane.

Co obejmuje

Praca, komponent po komponencie

Zbiera tematy z otwartych źródeł równolegle, bez upadku, gdy jedno milczy

Osiem zbieraczy startuje jednocześnie: Hacker News, Reddit, Product Hunt, GitHub trending w trzech przekrojach, zestaw czternastu kanałów RSS i Indie Hackers. Każdy ma własne przechwytywanie błędów, więc źródło, które padło, zwraca pustą listę i nie zatrzymuje uruchomienia. Wyniki są scalane, duplikaty usuwane po identyfikatorze, a potem stosowany jest limit ośmiu tematów na źródło, sortowanych według szybkości obiegu — tak, aby głośne źródło nie zalało kolejnego etapu.

Zapisuje i odrzuca, zanim wyda na pisanie

Każdy temat dostaje ocenę od 0 do 100 za to, jak dobrze pasuje do tego, co robimy, plus proponowany kąt, docelową branżę i docelową usługę. Wszystko poniżej 50 jest odrzucane. Etap działa na tanim modelu, z czterema wątkami równolegle, właśnie dlatego, że to etap decydujący o tym, na co wydać dalej. Z finalnego wyboru wyciąga się jeszcze jedną warstwę: pierwsze przejście bierze po jednym temacie na branżę, aby nie wyszło dziesięć wariantów na ten sam wątek.

Pisze artykuł z wymuszoną strukturą, nie swobodną

Generator dostaje ścisłą strukturę: 1.500–2.200 słów po rumuńsku, nagłówek YAML z tytułem o długości maksymalnie 60 znaków i opisem 155, jeden H1 i od czterech do sześciu H2, od trzech do pięciu wewnętrznych linków wybranych z listy adresów, które istnieją na stronie, wyróżniony cytat, sekcję pytań zgodną ze schematem FAQPage oraz końcowe wezwanie do działania. Działa z trzema wątkami równolegle, z budżetem pięciu minut na artykuł i limitem 5.000 tokenów na wyjściu.

Tłumaczy na dziewiętnaście języków, ze słownikiem, którego się nie tłumaczy

Źródłem jest rumuński; cele to dziewiętnaście języków, od angielskiego, rosyjskiego i ukraińskiego po arabski, hebrajski, hindi, japoński i uproszczony chiński — w tym dwa pisma od prawej do lewej. Zasady są jasno opisane w promptcie: nagłówek zachowuje swoją strukturę, adresy linków wewnętrznych nie są przepisywane ani lokalizowane, liczby, jednostki i daty są zachowywane, a terminy markowe ze słownika pozostają nietknięte. Tłumaczenie działa tylko na dwóch wątkach równolegle, celowo — brama modeli ogranicza przepustowość przy większym obciążeniu.

Surowa brama: pięć warunków i dziesięć zakazanych wyrażeń

Lokalnie, bez żadnego płatnego wywołania: nagłówek musi istnieć i mieć tytuł, opis oraz słowa kluczowe; tekst musi przekraczać 1.200 słów, liczonych po usunięciu bloków kodu i tagów; minimum trzy podtytuły poziomu drugiego; minimum trzy wewnętrzne linki do sekcji, które istnieją na stronie; sekcja pytań z co najmniej trzema parami. Plus czarna lista: „game-changing”, „cutting-edge”, „world-class”, „revolutionize”, „synergy” i jeszcze pięć. Jedno wystąpienie odrzuca artykuł.

Druga brama szuka dokładnie tego, czego nie widzi licznik

Drugi model, z niską temperaturą i odpowiedzią w JSON, dostaje artykuł i szuka pięciu rzeczy: nazwy klienta bez dowodu, że wyraził zgodę, halucynowanych statystyk typu procentowa dostępność bez pomiaru, niedokładnych twierdzeń o tym, co my możemy zrobić, języka broszury oraz twierdzeń o narzędziach zewnętrznych, które mogłyby sprawiać wrażenie, że je posiadamy, podczas gdy my tylko je integrujemy. Ma też listę nagród, które naprawdę mamy — każda nagroda spoza listy jest sygnalizowana.

Gdy weryfikacja nie może się uruchomić, artykuł jest traktowany jak odrzucony

Druga weryfikacja ma budżet 90 sekund, wyraźnie po to, aby nie blokować uruchomienia. Jeśli czas minie albo jeśli usługa modeli nie odpowie, błąd jest przechwycony i zamieniony w negatywny werdykt, a nie ignorowany. Konsekwencja jest ważna i to właśnie ta, którą lubimy najbardziej: artykuł nie trafia do publikacji, bo nie było strażnika. Tak już się stało, przy jedynym pełnym uruchomieniu w logach — dwa w pełni napisane artykuły nie zostały opublikowane, bo weryfikacja nie mogła zostać wykonana.

Publikacja ma jeden warunek i trzy kroki

Publikacja nawet się nie uruchamia, jeśli zero artykułów przeszło bramkę. Gdy się uruchamia: dodaje tylko katalog treści, zatrzymuje się, jeśli nie ma czego commitować, wykonuje commit z datą, liczbą artykułów i liczbą języków oraz próbuje wypchnięcia. Jeśli wypchnięcie się nie powiedzie, commit pozostaje lokalny, a uruchomienie trwa dalej — praca się nie traci i nie twierdzi się, że coś opublikowano. Powiadomienie wyszukiwarek wykonuje się tylko wtedy, gdy wypchnięcie się powiodło.

Każde uruchomienie zostawia swój rachunek

Na końcu zapisuje się raport dzienny: ile tematów zebrano, ile przeszło ocenę, ile wybrano, ile napisano, ile tłumaczeń powstało, ile przeszło bramkę, co zostało zcommitowane i co wypchnięto, co odpowiedziały wyszukiwarki, ile to trwało oraz koszt rozbity na model, z liczbą wywołań i tokenów wejściowych oraz wyjściowych. Raport jest plikiem, nie panelem — można go czytać, archiwizować i porównywać.

Jak to wygląda

Trasa, krok po kroku.

01

Ustalamy, co wolno pisać, a czego nie

Przed jakimkolwiek kodem: lista tematów, które obejmujemy, lista tych, których nie dotykamy, ton oraz lista zakazanych wyrażeń. Tutaj zapisuje się też lista stwierdzeń, których silnik nie może o was mówić — klientach, liczbach, nagrodach, porównaniach. Dostarczamy: zapisane zasady, w formie, która trafia bezpośrednio do weryfikacji, a nie jako osobny dokument, który się gubi.

02

Uruchamiamy tylko zbieranie i notowanie, bez pisania czegokolwiek

Uruchamia się w trybie suchym: zbiera się tematy, notuje się je, wybiera pierwsze, zapisuje raport i wychodzi przed generowaniem. To tanie — przy takim uruchomieniu z naszych dzienników było 24 wywołania, wszystkie na małym modelu, z mierzalnym kosztem około jednego centa łącznie. Widać dokładnie, co silnik wybrałby dzień po dniu, bez powstania jakiegokolwiek tekstu. Dostarczamy: raporty z uruchomień suchych i uzgodnienie tego, co wybiera.

03

Pisujemy i sprawdzamy, ale nie publikujemy

Uruchamia się generowanie i bramka, z wyłączoną publikacją. Tutaj kalibruje się progi: jeśli wszystkie artykuły odpadają na długości, trzeba innej regulacji niż wtedy, gdy odpadają na linkach wewnętrznych. Tutaj widać też, co sygnalizuje druga weryfikacja, która jest najbardziej pouczającą częścią. Dostarczamy: wygenerowane artykuły, pełne werdykty z powodem każdego odrzucenia oraz dostosowane progi.

04

Otwieramy publikację, z bramką na miejscu

Uruchamia się systemowy timer i publikacja. Godzinę wybiera się poza szczytem, z losowym opóźnieniem, aby uruchomienia nie wchodziły sobie w drogę; u nas 00:30 UTC z opóźnieniem do 30 minut, oraz z odzyskiwaniem, jeśli serwer był wyłączony o tej porze. Ustawia się limit czasu na uruchomienie. Dostarczamy: jednostkę usługi i timer, logi oraz procedurę zatrzymania.

05

Dodajemy języki, jeden po drugim

Tłumaczenie to etap o największym zużyciu i najłatwiejszy do wymknięcia się spod kontroli. Języki dodaje się na pasach priorytetu, nie wszystkie naraz, i sprawdza się, co wychodzi w każdym — zwłaszcza w pismach nielacińskich, gdzie reguła jest taka, że terminy marki mają pozostać w alfabecie łacińskim. Dostarczamy: glosariusz, uruchomione języki oraz koszt zmierzony na język z dziennika uruchomienia.

Opt etape1adunare din optculegători paraleli,fiecare cu prindereproprie de eroare2notare 0–100, aruncăsub 503alegere cudiversitate peindustrie4scriere în română,1.500–2.200 decuvinte5traducere în 19 limbicu glosar neatins6poarta dură, cincicondiții și zeceexpresii interzise7poarta a doua, carecaută clienți, cifreși premii inventate8publicare, doar dacăa trecut măcar unulCând poarta nu poate rula, nu se publică.
Opt etape

Dane

Czego dotykamy, gdzie to leży i jak długo zostaje

Pytania, które zadaje każdy, kto ma inspektora ochrony danych — postawione tutaj, zanim on je zada.

Co wchodzi
Tytuły, adresy i krótkie fragmenty z publicznych źródeł — otwarte API i kanały RSS. Nie zbiera się danych osobowych, nie czyta się prywatnych kont i nie wchodzi się po uwierzytelnieniu. Każdy temat zachowuje źródło, kanał i moment odkrycia, aby dało się śledzić, skąd wyszedł artykuł.
Gdzie stoją teksty
Jako pliki MDX w repozytorium kodu strony, pod `content/daily/{język}/{data}/{slug}.mdx`. Nie w osobnej bazie danych. Konsekwencją jest to, że pełna historia to historia git: widać, kto co napisał i kiedy, i można wrócić jednym poleceniem. Każdy artykuł ma własny nagłówek, z którego strona publiczna składa dane strukturalne.
Gdzie są klucze
W pliku środowiskowym odczytywanym przez jednostkę systemd przy uruchomieniu, poza repozytorium kodu. Ładowarka środowiska nie nadpisuje zmiennej już zdefiniowanej w procesie, więc konfigurację uruchomieniową można podmienić bez dotykania pliku. Wywołania do modeli przechodzą przez naszą wewnętrzną bramę, adresowaną lokalnie na serwerze.
Dzienniki i jak długo są przechowywane
Jeden plik JSON na dzień w katalogu dzienników silnika, plus wyjście standardowe i standardowy błąd zapisywane oddzielnie w `/var/log`, przez jednostkę systemd. Dzienny dziennik zawiera werdykty bramy dla każdego artykułu, z dokładnym powodem odrzucenia i liczbą zliczonych słów. Nie zawiera tekstu artykułów — te są w repozytorium.
Czego nie dotyka
Nie dotyka waszych kont w mediach społecznościowych, nie wysyła e-maili, nie zapisuje do CRM. Publikacja oznacza commit w repozytorium strony i powiadomienie do dwóch wyszukiwarek. Jeśli chcecie publikację w innych kanałach, omawia się to osobno, z tą samą zasadą: brama przed, nie po.

Przykład

Noc, w której silnik napisał trzy artykuły i nie opublikował żadnego

Sytuacja

Pełne uruchomienie, ze wszystkimi etapami włączonymi: zbieranie z otwartych źródeł, punktowanie, wybór, pisanie w języku rumuńskim, tłumaczenie, bramka, publikacja. Cel był celowo mały, trzy artykuły, żeby było widać cały łańcuch bez dużych kosztów.

Co zbudowaliśmy

Zbieranie przyniosło 24 unikalne tematy po usunięciu duplikatów i ograniczeniu per źródło. Ocenianie zachowało 18 i odrzuciło 6 poniżej progu 50. Reguła różnorodności wybrała 3, z różnych branż. Generator napisał 3 artykuły po rumuńsku. Tłumacz wygenerował 57 plików. Potem weszła brama.

Co z tego wyszło

Żaden artykuł nie przeszedł. Dwa odpadły, ponieważ drugiej weryfikacji nie dało się w ogóle wykonać — usługa modeli nie odpowiedziała w budżecie 90 sekund, a błąd potraktowano jako werdykt negatywny, nie zignorowano go. Trzeci odpadł z jednego powodu: brakowało mu pola słów kluczowych w nagłówku, mimo że miał 2.478 słów, czyli dwa razy więcej niż minimalny próg. Ponieważ żaden artykuł nie przeszedł, publikacji nawet nie wywołano: commit pozostał pusty, wypchnięcia nie wykonano, wyszukiwarki dostały zero adresów. 57 tłumaczeń pozostało na dysku, nieużytych.

Czego nie mówi ten przypadek

Uruchomienie było na stacji roboczej, nie na serwerze — widać to po ścieżkach w dzienniku — i trwało dwie i pół godziny, ponad limit 60 minut ustawiony w jednostce systemd. Czyli pokazuje dwie rzeczy naraz: że brama działa, i że dzienny pakiet jest za duży dla skonfigurowanego limitu czasu. Obie są prawdziwe i obie warto powiedzieć.

Pytania

O co pytają ludzie, zanim zadzwonią

Czy publikuje się bez tego, by ktoś widział tekst?

Tak, jeśli tak wybierzecie — i nie, jeśli nie. Silnik może działać całkowicie automatycznie, a w tym trybie artykuł, który przejdzie oba poziomy bramy, trafia do publikacji bez tego, by ktoś go przeczytał. Ale brama nie jest dekoracyjna: odrzuci artykuł za brak pola nagłówka, za 1.199 słów zamiast 1.200, albo za jedną jedyną frazę z czarnej listy. A jeśli wolicie, by każdy artykuł przechodził przez parę oczu, automatyczna publikacja zostaje wyłączona i wszystko zatrzymuje się do etapu weryfikacji, z sygnałami widocznymi od razu. Nasza rekomendacja na początek to druga opcja, aż sygnały staną się nudne.

Co się dzieje, gdy model pomyli fakt?

To zależy od rodzaju faktu i warto uczciwie powiedzieć, że nie wszystkie błędy są wychwytywane. Wychwytywane są: nazwa klienta podana bez dowodu zgody, zmyślona statystyka w rodzaju procentu dostępności bez pomiaru, stwierdzenie, które mogłoby sugerować, że posiadamy narzędzie, które tylko integrujemy, nagroda, której nie ma na liście rzeczywistych. Nie są wychwytywane: błędna data kalendarzowa z zewnętrznej wiadomości albo techniczne stwierdzenie o produkcie strony trzeciej, które brzmi wiarygodnie. Dla takich rzeczy nie ma innego strażnika niż człowiek, dlatego każdy artykuł zachowuje w nagłówku źródła, z których wyszedł — weryfikacja pozostaje możliwa po publikacji, a korekta jest commitem.

Jak zatrzymuje się przepływ?

Na trzy sposoby, w kolejności szybkości. Zatrzymanie timera systemowego — jutro nic już nie startuje. Wyczyszczenie zmiennej trzymającej klucz publikacji — silnik pisze i weryfikuje, ale powiadomienie wyszukiwarek jest pomijane z ostrzeżeniem w dzienniku. I uruchomienie w trybie suchym, które zatrzymuje się po wyborze tematów i niczego nie generuje. Dodatkowo pojedyncze uruchomienie ma limit czasu w jednostce usługi, najpierw z łagodnym sygnałem, a potem z wymuszonym zatrzymaniem.

Czy silnik działa teraz, na serwerze?

Nie możemy potwierdzić tego z zewnątrz i nie będziemy tego twierdzić. To, co możemy pokazać, to kod, jednostka usługi, timer, procedura instalacji i dzienniki uruchomień, które mamy. Jedyny pełny przebieg w dziennikach był na stacji roboczej, nie na serwerze — widać to po ścieżkach plików — i trwał dwie i pół godziny, czyli ponad limit 60 minut w jednostce systemd. Jeśli interesuje was dzisiejszy stan naszej instalacji, zapytajcie, a sprawdzimy razem. Wolimy takie pytanie niż „tak”, które okazuje się fałszywe.

Ile artykułów zostało dotąd opublikowanych?

Z naszych dzienników: zero. Pełne uruchomienie zebrało 24 tematy, zachowało 18 po ocenie, wybrało 3, napisało 3 artykuły i 57 tłumaczeń — a bramka zatrzymała wszystkie trzy. Dwa dlatego, że druga weryfikacja w ogóle nie mogła się uruchomić, jeden z powodu brakującego pola w nagłówku, mimo że miał 2.478 słów, więc z dużym zapasem przekroczył próg długości. Publikacja nie została wywołana, wyszukiwarki nie dostały żadnego adresu. Moglibyśmy wam tego nie mówić. Mówimy, bo to dokładnie demonstracja, której potrzebuje usługa: bramka naprawdę zatrzymuje.

To nie „treść AI”, która psuje pozycjonowanie w wyszukiwarce?

Właściwe pytanie nie brzmi, kto napisał, tylko czy tekst odpowiada na coś, czego ktoś rzeczywiście szuka, i czy da się to zweryfikować. Dlatego progi w bramce są ustawione na rzeczy, które korelują z użytecznością, a nie ze stylem: minimalna długość, struktura z podtytułami, linki wewnętrzne do istniejących stron, sekcja pytań. I dlatego czarna lista zawiera dokładnie te wyrażenia, które sygnalizują tekst napisany po to, by wypełnić miejsce. Tego, czego nie obiecujemy, to konkretnej pozycji w wynikach — to zależy od wielu rzeczy, które nie zależą od nas.

Ile kosztuje jedno uruchomienie?

Koszt się mierzy, a nie szacuje: każde wywołanie modelu zlicza tokeny wejściowe i wyjściowe, a dzienny raport podaje sumę rozbitą według modelu, wraz z liczbą wywołań. Przy próbnym uruchomieniu z naszych dzienników: 24 wywołania na modelu tańszym. Przy pełnym uruchomieniu z trzema artykułami i 57 tłumaczeniami: 32 wywołania, z czego 3 na modelu droższym — to one odpowiadały za największą część kosztu. Model używany na każdym etapie jest zmienną środowiskową, więc można obniżyć etap do tańszego modelu bez ruszania kodu. Kwota w pieniądzach zależy od wybranych modeli i ich stawek w momencie uruchomienia.

W jakich językach pisze i co dzieje się z terminami marek?

Źródłem jest rumuński, a cele to dziewiętnaście języków — angielski, rosyjski, ukraiński, polski, niemiecki, włoski, francuski, hiszpański, niderlandzki, arabski, turecki, hebrajski, hindi, japoński, koreański, indonezyjski, chiński uproszczony, portugalski brazylijski i czeski. Przy każdym języku w konfiguracji jest zapisany powód, dla którego się tam znajduje. Terminy marek i techniczne są w glosariuszu i pozostają nieprzetłumaczone, także w arabskim, hebrajskim i pismach azjatyckich, gdzie reguła jest wyraźna: pozostają w alfabecie łacińskim. Adresów linków wewnętrznych nigdy się nie lokalizuje.

Co nie jest gotowe z tego, co opisaliście?

Trzy rzeczy, powiedziane teraz, żebyście nie odkrywali ich sami. Własna dokumentacja miejscami wyprzedziła kod — komentarz na początku etapu notowania wspomina model, który nie jest już tym wywoływanym, a rejestr źródeł opisuje większy zestaw kanałów RSS niż ten z listy. Po drugie: dwa ze źródeł wpisanych do rejestru są oznaczone jako aktywne, ale ich pobieracz nie jest wywoływany w funkcji, która zbiera wszystko, więc dziś nic nie wnoszą. Po trzecie: pełne uruchomienie z dzienników przekroczyło limit czasu w jednostce usługi, co oznacza, że na serwerze, przy obecnych ustawieniach, zostałoby przerwane w połowie — limit trzeba podnieść albo dzienny pakiet zmniejszyć przed automatycznym uruchomieniem.

Na czym opierają się powyższe stwierdzenia (26 źródeł)

26 z nich to kod i pliki z naszych repozytoriów. Nie publikujemy ich nazw ani numerów linii: razem, na jednej stronie, opisałoby to zbyt dokładnie, jak zbudowane są systemy, które nie należą tylko do nas. Przechodzimy je razem z Tobą, w repozytorium, na życzenie — weryfikacja pozostaje możliwa, tylko odbywa się w rozmowie.

Co chcesz, żeby działało lepiej?

Opowiedz nam o swoim procesie. Wspólnie ustalimy, co warto zbudować, co da się połączyć i jak sprawdzimy wynik.

Porozmawiajmy