Alles wat u wilt weten voordat u installeert.
Een gedetailleerde blik op hoe DataFirefly Semantische Interne Links met AI: Vectorembeddings, Cosinussimilariteit en Halfautomatische Invoeging met Slimme Ankers voor PrestaShop 8 & 9 (Mistral, OpenAI) werkt, waarom we het zo gebouwd hebben en de gedachte achter de bovenstaande functies.
Waarom semantische interne links beter werken dan links op zoekwoorden
Klassieke modules voor interne links werken met regels van zoekwoord naar URL. U typt berbertapijt in en koppelt daar de URL van de categorie berbertapijt aan. De motor doet daarna een zoek-en-vervang in de HTML van uw artikelen, producten of pagina's. Die aanpak kent twee grote beperkingen. Hij is star: er ontstaat alleen een link wanneer het exacte zoekwoord voorkomt, waardoor alle pagina's afvallen waar het onderwerp anders is verwoord (Marokkaans tapijt, kelim, traditioneel tapijt). En hij is blind voor de context: de motor weet niet of de doelpagina werkelijk relevant is voor de bronpagina, hij vergelijkt alleen tekenreeksen. Semantisch linken werkt anders: elke inhoud wordt weergegeven als een vector met honderden dimensies die de betekenis vastlegt, of het nu om een product, een categorie, een CMS-pagina of een blogartikel gaat. Twee stukken inhoud worden gekoppeld als ze in die vectorruimte dicht bij elkaar liggen, ongeacht de gebruikte woorden. Zo vindt de module kansen die een zoekwoordmotor nooit zou zien, en vermijdt hij valse treffers waarbij een zoekwoord in een irrelevante context opduikt.
AI-embeddings: hoe dat in de praktijk werkt
Bij de eerste indexering loopt de module alle actieve entiteiten van uw winkel af voor de ingeschakelde typen (producten, categorieën, CMS-pagina's). Per entiteit wordt de tekst opgehaald en opgeschoond: titel, meta_title, meta_description, korte beschrijving en lange beschrijving, waarbij de HTML netjes wordt verwijderd. De opgeschoonde tekst gaat daarna in blokken naar de ingestelde AI-aanbieder (Mistral of OpenAI), die per item een vectorembedding teruggeeft: een reeks kommagetallen die de betekenis van de tekst weergeeft. Die vector wordt in de database bewaard als gepakte float32-BLOB in little-endian, met een vooraf berekende L2-norm om latere gelijkenisberekeningen te versnellen. De gelijkenis tussen twee stukken inhoud wordt daarna in PHP berekend via een genormaliseerd inwendig product (cosinusgelijkenis), een bijzonder snelle bewerking zodra de normen vooraf zijn berekend. Bij een catalogus van 5.000 entiteiten duurt het volledig doorrekenen van alle paren in één taal maar enkele seconden.
Waarom twee aanbieders en niet één
Elke aanbieder heeft zijn sterke kant. mistral-embed van Mistral is de aanbevolen standaard: 1024 dimensies, zeer lage latentie, hosting in Europa (relevant voor winkels die op Europese dataopslag letten) en kosten van ongeveer 10 cent per miljoen tokens, dus minder dan een euro om een meertalige catalogus van enkele duizenden entiteiten te indexeren. text-embedding-3-small van OpenAI is het alternatief: 1536 dimensies (een rijkere vectorruimte), sterk op niet-Europese talen, en kosten van ongeveer 2 dollarcent per miljoen tokens, dus vijf keer goedkoper dan Mistral. De module brengt beide aanbieders achter dezelfde interface samen: hetzelfde antwoordformaat, hetzelfde blokmechanisme en dezelfde foutafhandeling via PrestaShopLogger. U wisselt van aanbieder via de keuzelijst in de configuratie, waarna de module merkt dat het aantal dimensies is veranderd en voorstelt opnieuw te indexeren (één klik op Alles opnieuw indexeren).
De ankergenerator, het echte kernstuk van de module
Dit is het punt waarop de module zich onderscheidt van een gereedschap dat alleen ruwe suggesties doet. Voor elk paar van bron en doel boven de gelijkenisdrempel werkt de ankergenerator als volgt: hij neemt de titel van het doel, hakt die in n-grammen van 2 tot 6 woorden, haalt de stopwoorden eruit (Frans en Engels) en zoekt elk van die n-grammen letterlijk terug in de brontekst. De gevonden n-grammen worden op aflopende lengte gerangschikt (de langste zijn onderscheidender en SEO-sterker) en in de keuzelijst in de backoffice getoond. Het standaard gekozen anker is het langste dat is gevonden, wat doorgaans een anker van 3 of 4 woorden oplevert met de belangrijkste zoekwoorden van de doeltitel erin. Komt geen enkel n-gram van de doeltitel in de bron voor, dan stelt de module de ruwe doeltitel voor. U houdt uiteraard de regie: een bewerkbare keuzelijst en een optie om zelf een willekeurige ankertekst in te typen. Bij het invoegen kiest de module de eerste plek in de brontekst waar de ankertekst voorkomt en die nog niet in een a-, code- of pre-tag zit, zodat er geen bestaande link sneuvelt en geen al gelinkte tekst opnieuw wordt gelinkt.
Chirurgisch terugdraaien via een uniek merkteken
Dit is de functie die verkopers geruststelt die voorzichtig zijn met hun beschrijvingen. Elke ingevoegde link krijgt een HTML-attribuut data-dfasl met een unieke identificator van 36 tekens, die bij het invoegen willekeurig wordt aangemaakt. Die identificator staat ook in de database, in de tabel dfasl_inserted_link, samen met de bronentiteit, het doel, het anker, de datum van invoegen en de medewerker die het heeft goedgekeurd. Om een link te verwijderen gaat u naar het tabblad Ingevoegde links en klikt u op Verwijderen naast de betreffende regel: de module past een reguliere expressie toe die precies het patroon van de a-tag met dat unieke kenmerk herkent, verwijdert de a-tag maar laat de ankertekst intact, en markeert de link in de database als verwijderd. Geen enkele andere tag in de beschrijving wordt aangeraakt en geen enkele handmatige link loopt gevaar. Van 500 links die de module in 200 productpagina's heeft ingevoegd, verwijdert u er met één klik precies één, zonder de 499 andere aan te raken.
CLI-worker en aanpak voor grote catalogi
Bij een catalogus van enkele tientallen producten kan alles vanuit de backoffice: alles opnieuw indexeren en daarna een blok verwerken volstaat. Vanaf enkele duizenden entiteiten wordt de interface traag en wil niemand zijn browser urenlang openhouden. De module levert daarom een CLI-worker (bin/analyze.php) die u op de PHP-commandoregel start, met vier opties. Met --shop kiest u een specifieke winkel in een multishop-omgeving. Met --enqueue-all zet u alle actieve entiteiten opnieuw in de wachtrij voordat er wordt verwerkt, handig voor een volledige herindexering na een wissel van aanbieder of model. Met --loop blijft de worker doorgaan zolang er items zijn. Met --max-batches begrenst u het aantal blokken per run, als beveiliging tegen een op hol geslagen proces. Met --sleep last u een pauze tussen blokken in, handig om onder de rate limits van de API te blijven. De gebruikelijke opdracht voor een cron om de 15 minuten is: php modules/dfaisemanticlinks/bin/analyze.php --loop --max-batches=50 --sleep=1. De worker zet items die langer dan 30 minuten op de status Bezig blijven staan automatisch terug (voor het geval een eerdere worker is vastgelopen), markeert bij API-fouten de betrokken items met de status Fout en het foutbericht, en verwerkt de gezonde items in het blok gewoon verder.
Automatisch opnieuw indexeren en een actuele index
Een index die niet meer met de catalogus overeenkomt heeft geen enkele waarde. De module houdt de index actueel met de native PrestaShop-hooks. Bij elke wijziging van een product, categorie of CMS-pagina (de hooks actionObjectProductUpdateAfter, actionObjectCategoryUpdateAfter en actionObjectCmsUpdateAfter) komt de betreffende entiteit terug in de wachtrij met de status In afwachting, in alle actieve talen, waarna de eerstvolgende worker die automatisch verwerkt. Bij verwijdering (de hooks actionObjectProductDeleteAfter, actionObjectCategoryDeleteAfter en actionObjectCmsDeleteAfter) worden de bijbehorende embeddings en suggesties in cascade opgeruimd. De module gebruikt daarnaast een hash van de inhoud (SHA-256 van de opgeschoonde tekst): komt een entiteit in de wachtrij terwijl de inhoud niet werkelijk is veranderd (bijvoorbeeld omdat een medewerker alleen de voorraad heeft aangepast), dan merkt het indexeringsblok de ongewijzigde hash op en slaat het de API-aanroep over, wat tokens bespaart. Het automatisch opnieuw indexeren zet u aan of uit bij de instellingen (optie DFASL_AUTO_INDEX), handig om het tijdens een grote CSV-import stil te leggen en na afloop met een volledige herindexering te hervatten.
Native multishop en meertalig
De module is van huis uit geschikt voor multishop en meerdere talen. De embeddings worden afgebakend per combinatie van entiteit, taal en winkel: hetzelfde product in twee winkels krijgt twee onafhankelijke embeddings als de beschrijvingen verschillen, en hetzelfde product in het Nederlands en in het Engels krijgt twee verschillende embeddings, ook al gaat het om dezelfde productpagina. Suggesties gaan nooit over taalgrenzen heen: bij een Nederlands product wordt nooit een link naar een Engels product voorgesteld, wat voor SEO ook nergens op zou slaan. Voor winkelgrenzen geldt hetzelfde. De configuratie kan per winkel verschillen (API-sleutel, gelijkenisdrempel, geïndexeerde typen, weergavehook), wat handig is als u binnen dezelfde infrastructuur een zakelijke winkel met technische inhoud en een consumentenwinkel met publieksgerichte inhoud draait.
Typische gebruikssituaties
Een meertalige modewinkel met 2.000 producten: de semantische aanpak vindt productparen die visueel of qua stijl dicht bij elkaar liggen (bijvoorbeeld twee varianten van dezelfde jurkpasvorm), die zoekwoordregels stelselmatig zouden missen. Een technische zakelijke winkel met dichte beschrijvingen: de semantische aanpak verbindt producten die eenzelfde industriële toepassing delen zonder dat het vocabulaire gelijk is. Een webshopblog: elk artikel kan automatisch verwijzen naar de producten, categorieën en andere artikelen die inhoudelijk het dichtst in de buurt komen, met ankers die letterlijk uit de tekst van het artikel komen, precies het tegenovergestelde van een werktuiglijke zoek-en-vervang. Een catalogusherziening: na een grote import of een reorganisatie bouwt één volledige herindexering het netwerk in enkele minuten opnieuw op, waar een handmatige aanpak weken redactiewerk zou kosten. En een catalogus met sterk eigen vocabulaire (biologische cosmetica, medische apparatuur, technische producten): de module merkt inhoudelijke verwantschappen op die een niet-specialist niet zou zien, waarmee het SEO-team kansen ontdekt die niet voor de hand liggen.
Interne architectuur en compatibiliteit met PrestaShop 8 en 9
De module is gebouwd in PHP 8.1+ met strikte typering, readonly klassen en moderne taalfuncties (match, enums). De autoload is PSR-4 onder de namespace DataFirefly/AiSemanticLinks/, gekoppeld aan src/. De admincontrollers gebruiken de legacy ModuleAdminController en geen Symfony-grid, een bewuste keuze om stabiele compatibiliteit tussen PrestaShop 8.0 en 9.x te garanderen zonder twee varianten van de code te moeten onderhouden. Een eigen kleine servicecontainer koppelt de repositories en de zakelijke services aan elkaar, wat de module afschermt van de verschillen tussen de Symfony-containers van beide PrestaShop-versies en een afhankelijkheid vermijdt die bij elke grote update zou breken. Er zijn vijf SQL-tabellen met het voorvoegsel dfasl_: embedding (vectoren en hashes), queue (de werkwachtrij), suggestion (voorgestelde paren), inserted_link (actieve links) en job (bulkbewerkingen). Het verwijderen wist de 5 tabellen netjes en ruimt alle configuratievariabelen op. De broncode wordt niet versleuteld geleverd en is PSR-conform, dus u kunt hem overschrijven, controleren of naar eigen inzicht uitbreiden.
Er zijn nog geen beoordelingen.