Média · E-commerce · Interní
Recommender systémy ve škále Seznamu
Řazení a doporučení napříč 50M+ požadavky denně: vyvážený recommender podle historie, klasifikátory clickbaitu a kvality, agentní content crawlery a framework pro experimenty, který každou změnu ověřil.
Stack
- Python
- recommender models
- LLM classifiers (DSPy)
- A/B experimentation
- SQL analytics
Dřívější interní práce: omezeno na můj podíl.
Výsledky
- 50M+požadavků denně ve škále Seznamu
- +5.5%kliky z vyváženého recommenderu≈ 35–40M Kč/rok, A/B testováno
- +18%CTR z agentních content crawlerůkliky +12%
- −40%expozice clickbaitu, quality klasifikátornízká kvalita −50%, kliky −2%
Kontext
Seznam provozuje newsfeed v národním měřítku a recommender za ním zvládá řazení a doporučení napříč víc než 50 miliony požadavků denně. Feed míchá zprávy, zábavu a zájmový obsah a byznys stojí na klikách a reklamních příjmech, které nesou. Na každého uživatele jsme měli dlouhou behaviorální historii, ale řazení ji většinou ignorovalo a skórovalo položky podle poslední hrstky kliků.
Byl jsem senior product manager pro recommender systémy přibližně deset let. Tahle case je omezená na část, kterou jsem vlastnil přímo: logiku řazení, klasifikátory kvality obsahu, crawlery, které krmily feed, a experimenty, které rozhodovaly, co se dostane do produkce.
Problém
Tři problémy, rozložené do let. Za prvé, feed byl jednotvárný: řazení vidělo jen nedávné interakce, takže série kliků na jedno téma vytlačila všechno ostatní, zatímco dlouhá historie ležela ladem. Za druhé, kvalita obsahu ostře klesla, jakmile editorial přestal ručně kontrolovat každý článek: vydavatelé toho využili a zaplavili feed clickbaitem a tenkým obsahem. Za třetí, kvalitní nichový obsah, který by feed rozšířil, se nevyplatilo zadávat ručně.
Každý z nich ohrožoval stejné číslo: kliky a tržby, které na nich visí.
Přístup
Spojnice byla měřit dřív, než se něco nasadí, a nesahat po drahém nástroji jako po prvním. Pro jednotvárný feed vyvážený recommender vážený stářím interakce: váhová funkce, ne větší model. Pro klasifikaci obsahu optimalizované LLM prompty s DSPy místo trénování a údržby samostatného klasifikátoru na každou vlastnost. Pro crawlery levný regex předfiltr před LLM, aby model viděl jen slibný text. A když byznys chtěl rovnou složit RPM do řazení, A/B test, který to rozhodne, místo hádky na meetingu.
Co jsem postavil
Omezeno na můj podíl. Váhovou funkci pro recommender podle historie jsem napsal sám; penalizuje stáří kliku a typ obsahu, aby feed zůstal smíšený. Specifikoval jsem klasifikátory kvality obsahu a clickbaitu (95% precision na clickbait) a asynchronní pipeline, která je spouští při uložení článku, ne při zpracování požadavku. Napsal jsem DSPy optimalizační skripty za klasifikátory typu obsahu, zájmu a adult obsahu. Napsal jsem pravidla pro filtrování zdrojů a skórování kvality agentních crawlerů. Navrhl jsem join přes URL decoration a sledování session, který propojil reklamní tržby s jednotlivými zónami recommenderu, a vyjednal ho s reklamním týmem, který se bál sahat do svých skriptů. A vlastnil jsem experimentální větev, která vážila RPM v řazení a přinesla evidenci k jejímu zamítnutí.
Výsledky
Každé číslo tady je měřené proti výchozímu stavu před změnou nebo A/B splitu. Vyvážený recommender zvedl kliky o +5,5 % (zhruba 35–40M Kč ročně navíc, při nákladech kolem pěti serverů) v A/B testu na živém provozu. Quality klasifikátor srazil expozici clickbaitu o −40 % a nízkou kvalitu o −50 % za cenu −2 % celkových kliků; to −2 % byl záměrný kompromis, měřený na A/B splitu, s 95% precision z označené sady clickbaitu. Agentní crawlery zvedly CTR o +18 % a kliky o +12 % proti výchozímu stavu před nasazením a přidaly tisíce ověřených zájmových článků denně bez růstu newsroomu. Tři DSPy klasifikátory šly od rozhodnutí do produkce za 1 týden. Odděleně, při kontrole denních statistik zhlédnutí, jsem zachytil JavaScript chybu, která zavírala celou video platformu ve feedu místo jednoho pořadu; škodu jsem spočítal v SQL a předal vývojářům přesný postup opravy: vyřešeno a databáze vyčištěna za 1 člověkodne.
Co bych vám řekl, pokud to řešíte
Tři věci se přenášejí.
Dejte levný filtr před drahý model. Regex předfiltr na crawlerech a asynchronní pipeline klasifikátorů nebyly chytré, ale byly důvod, proč LLM ekonomika na tomhle objemu fungovala. Nejdřív navrhněte cestu nákladů.
Když byznys chce změnu, která směňuje relevanci pro uživatele za výnos, pusťte A/B test místo hádky. Návrh řadit podle RPM zněl uvěřitelně a nepřekecal bych nikoho; dva týdny dat na zhruba 1 % provozu ukázaly, že to ublížilo CTR i relevanci, a tím to čistě skončilo.
Většina „nasazeno a důvěryhodné“ je neokázalá. Spočítat škodu v SQL, vyčistit poškozené preference, postavit whitelist, aby rychle nasazený klasifikátor netrestal zavedené autory: nic z toho se dobře nedemuje, ale vynechat to je způsob, jak dobrý systém ztratí důvěru uživatelů.
Vybraná rozhodnutí
Sedm rozhodnutí z práce na recommenderu a obsahové platformě: co jsem rozhodl, výsledek a kompromis.
+18% CTR
Agentní crawlery pro nichový zájmový obsah
Problém Nichový zájmový obsah se nevyplatí vyrábět ručně. Obsahové platformě chyběly kvalitní, úzce tematické články, což stropovalo CTR a engagement.
Rozhodnutí Rozhodl jsem, že newsroom nerozšiřovat: automatický sběr tu expanzi nahradí. Pravidla pro filtrování zdrojů a skórování jejich kvality jsem napsal sám.
Řešení Agentní crawlery, které na webu najdou, stáhnou a zařadí kvalitní nichové články a nasypou je do platformy.
Výsledek Tisíce kvalitních zájmových článků denně. CTR stouplo o +18 % a celkové kliky o +12 %. Měřeno: Online, proti výchozímu stavu před nasazením.
Kompromis Provozní náklady LLM a API byly ze začátku vysoké. Přidal jsem regex předfiltr, aby k drahému modelu došel jen slibný text.
+5.5% kliků
Vyvážený recommender, který používá dlouhodobou historii
Problém Recommender Seznamu vážil jen nejnovější interakce uživatele. Feed byl jednotvárný, i když jsme na každého drželi dlouhou historii.
Rozhodnutí Navrhl jsem algoritmus, který bere v úvahu celou historii, a váhovou funkci jsem napsal sám: penalizuje stáří kliku a typ obsahu.
Řešení Algoritmus, který v rovnováze míchá zprávy, zábavu a zájmový obsah, vážený stářím interakce.
Výsledek +5,5 % kliků: zhruba 35–40M Kč ročně navíc, při nákladech kolem pěti serverů. Měřeno: A/B test na reálném provozu.
Kompromis Přidal trochu latence při skládání feedu. Pro méně aktivní uživatele jsme výsledky cachovali, aby odpověď zůstala pod 100 ms.
1 týden nasazení klasifikátorů
Rychlé LLM klasifikátory s DSPy
Problém Obsahové platformy potřebují rozpoznávat spoustu vlastností obsahu: typ, zájem, adult obsah. Trénovat klasický ML klasifikátor na každou z nich bylo pomalé a výpočetně drahé.
Rozhodnutí Rozhodl jsem přejít od klasických modelů k optimalizovaným LLM promptům s DSPy a optimalizační skripty jsem napsal sám.
Řešení Stanfordské DSPy na automatickou optimalizaci LLM promptů a rychlou stavbu spolehlivých klasifikátorů.
Výsledek Klasifikátory typu obsahu, zájmu a adult obsahu plně nasazené za 1 týden. Měřeno: Na označené evaluační sadě u každého klasifikátoru.
Kompromis Volání LLM je dražší a pomalejší než lokální BERT. Klasifikaci jsme přesunuli do asynchronního zpracování na pozadí při uložení článku.
−40% expozice clickbaitu
Detekce clickbaitu a kvality, pod tlakem
Problém Editoři přestali ručně kontrolovat každý článek v newsfeedu. Vydavatelé toho využili a zaplavili feed clickbaitem a nízkou kvalitou.
Rozhodnutí Na nejhůř zasažené weby jsem dal dočasnou ruční opravu a souběžně řídil stavbu a okamžité nasazení automatického klasifikátoru.
Řešení Klasifikátor kvality obsahu a clickbaitu s 95% precision na clickbait.
Výsledek Expozice clickbaitu −40 %, nízká kvalita −50 %, celkové kliky −2 %. Měřeno: A/B, plus precision na označené sadě clickbaitu.
Kompromis Rychle nasazený model produkoval falešné pozitivy. Přidali jsme rychlou zpětnou vazbu a whitelist pro zavedené autory.
Propojení reklamních a recommender dat
Problém Lepší byznysová rozhodnutí a optimalizace feedu potřebovaly tržby po zóně a typu uživatele. Reklamní a recommender systémy byly v oddělených datech.
Rozhodnutí Navrhl jsem řešení kolem URL decoration a sledování session a vyjednal implementaci s reklamním týmem, který se bál sahat do svých skriptů.
Řešení Parametry recommenderu nesené do reklamních skriptů přes URL decoration a sdílenou reklamní session.
Výsledek Kompletní pohled na tržby per session v reálném čase pro každou zónu a typ uživatele. Měřeno: Odsouhlaseno proti vlastnímu revenue reportingu reklamního systému.
Kompromis URL decoration mohla ovlivnit analytické filtry partnerů. Parametry sledování jsme z URL stáhli přes History API hned po načtení.
Zamítnutí řazení podle RPM kvůli relevanci
Problém Byznys chtěl dát RPM (výnos) rovnou do recommenderu, s předpokladem, že weby s vyšším RPM jsou kvalitnější. Hrozilo to zhoršit relevanci feedu pro uživatele.
Rozhodnutí Odmítl jsem plošné nasazení bez evidence. Prosadil a navrhl jsem A/B test, který byznysovou hypotézu ověří na reálném provozu.
Řešení Experimentální větev vážící RPM v recommenderu, vyhodnocená podle dopadu.
Výsledek A/B test ukázal pokles CTR i celkové relevance feedu, a tím zastavil změnu, která by ublížila uživatelské zkušenosti. Měřeno: A/B test na reálném provozu.
Kompromis Dočasný výkonnostní pokles u testovací skupiny (asi 1 % uživatelů na dva týdny) byl nutná cena za tvrdá data k zamítnutí špatného rozhodnutí.
1 den oprava a úklid
Oprava chyby, která ve feedu zavírala video platformu Seznam.cz
Problém Uživatelé měli jít skrýt pořady, o které nestáli. Chyba v JS zavřela celou video platformu ve feedu místo jednoho pořadu, klesla zhlédnutí a ztratil se provoz.
Rozhodnutí Chybu jsem zachytil sám při kontrole denních statistik zhlédnutí. Spustil jsem SQL analýzu poškození dat, lokalizoval problém a předal vývojářům přesný postup opravy.
Řešení Analýza databáze, pak koordinace vývojářů při nasazení opravy a vyčištění poškozených preferencí.
Výsledek Vadná logika plně opravena a databáze vyčištěna za 1 člověkodne. Měřeno: Denní statistiky zhlédnutí, před a po.
Kompromis Museli jsme smazat posledních 48 hodin uživatelských preferencí, takže někteří uživatelé museli znovu skrýt nechtěné pořady: malá cena za obnovení video sekce.