# Semantische Interne Links met AI: volledige gids

> Overzicht DataFirefly Semantische Interne Links met AI (dfaisemanticlinks) bouwt de interne linkstructuur van uw PrestaShop-winkel op uit vectorembeddings. Elk product, elke categorie en elke CMS-pagina wordt door een AI-aanbieder (Mistral…

- Pagina: <https://www.datafirefly.com/nl/documentation/dfaisemanticlinks/>
- Taal: nl
- Bijgewerkt op: 2026-09-09
- Andere talen: [fr](https://www.datafirefly.com/documentation/dfaisemanticlinks/index.md), [en](https://www.datafirefly.com/en/documentation/dfaisemanticlinks/index.md), [es](https://www.datafirefly.com/es/documentation/dfaisemanticlinks/index.md), [de](https://www.datafirefly.com/de/documentation/dfaisemanticlinks/index.md), [it](https://www.datafirefly.com/it/documentation/dfaisemanticlinks/index.md), [pl](https://www.datafirefly.com/pl/documentation/dfaisemanticlinks/index.md), [pt](https://www.datafirefly.com/pt/documentation/dfaisemanticlinks/index.md)
- Index: <https://www.datafirefly.com/nl/documentation/llms.txt>

## Overzicht

DataFirefly Semantische Interne Links met AI (`dfaisemanticlinks`) bouwt de interne linkstructuur van uw PrestaShop-winkel op uit **vectorembeddings**. Elk product, elke categorie en elke CMS-pagina wordt door een AI-aanbieder (Mistral of OpenAI) in een vector omgezet, de vectoren worden met **cosinusgelijkenis** vergeleken, en de module stelt contextuele links voor met **ankerteksten die letterlijk uit de brontekst komen**. U keurt de voorstellen een voor een of in bulk goed, en elke ingevoegde link kan chirurgisch worden weggehaald dankzij een unieke markering `data-dfasl`.

De module doet aan de frontzijde geen enkele AI-aanroep: de gelijkenissen zijn vooraf berekend en de goedgekeurde links staan rechtstreeks in de beschrijvingen. De impact op de prestaties is nul.

## Vereisten

- PrestaShop 8.0 tot 9.x (PrestaShop 1.7 wordt niet ondersteund)
- PHP 8.1, 8.2 of 8.3
- MySQL 5.7+ of MariaDB 10.3+
- Een API-sleutel van **Mistral** (console.mistral.ai) of **OpenAI** (platform.openai.com)
- CLI-toegang is aan te raden bij catalogi van meer dan 1000 entiteiten (via cron)

## Installatie

1. Backoffice → **Modules → Modulebeheer → Een module installeren**.
2. Upload `dfaisemanticlinks.zip` en klik op **Installeren**.
3. De module maakt 5 tabellen aan met het voorvoegsel `dfasl_` (embedding, queue, suggestion, inserted_link en job) en een menu **AI-linkstructuur** met 4 tabbladen: Dashboard, Voorstellen, Ingevoegde links en Instellingen.

Bij het verwijderen verdwijnen de 5 tabellen en alle configuratievariabelen `DFASL_*` netjes. Exporteer uw gegevens vooraf als u ze wilt bewaren.

## Configuratie

### 1. Aanbieder van de embeddings

Tabblad **Instellingen**, eerste blok:

- **Aanbieder**: Mistral (mistral-embed, 1024 dimensies, de standaard, met hosting in de EU) of OpenAI (text-embedding-3-small, 1536 dimensies).
- **API-sleutel**: plak de sleutel van de gekozen aanbieder.
- **De verbinding testen**: die knop stuurt een testreeks door en toont hoeveel dimensies er terugkomen. Valideer uw sleutel hier altijd vóór u een indexering start.

Wisselt u na een indexering van aanbieder, dan wijzigen de vectordimensies (1024 tegenover 1536). De module nodigt u dan uit om **Alles opnieuw indexeren** te draaien: de oude vectoren worden overschreven, maar de al ingevoegde links blijven staan.

### 2. Indexering

- **Geïndexeerde types**: producten, categorieën en CMS-pagina's, elk apart in te schakelen.
- **Minimale lengte** (standaard 200 tekens): inhoud die na het opschonen van de HTML te kort is, wordt overgeslagen.
- **Batchgrootte** (standaard 20): het aantal items dat per API-verzoek vertrekt. Eén embeddingaanroep per batch.
- **Automatisch opnieuw indexeren** (standaard aan): elke wijziging aan een product, categorie of CMS-pagina zet de entiteit via hooks terug in de wachtrij. Zet dat tijdelijk uit tijdens een massale CSV-import.

### 3. Voorstellen en invoegen

- **Gelijkenisdrempel** (standaard 0,78): paren onder de drempel worden overgeslagen. Ga naar 0,72 voor meer voorstellen, of naar 0,82 voor meer striktheid.
- **Maximaal aantal links per pagina** (standaard 5): een bescherming tegen SEO-overoptimalisatie.
- **Ankerstrategie**: geoptimaliseerde n-grammen (de standaard) of de ruwe titel van het doel.

## De eerste indexering

1. Tabblad **Dashboard** → de knop **Alles opnieuw indexeren**: alle actieve entiteiten van de ingeschakelde types komen in de wachtrij, in alle actieve talen.
2. Klik zo vaak als nodig op **Een batch verwerken** (bij kleine catalogi), of start de CLI-worker (zie verderop).
3. Elke batch: het extraheren en opschonen van de tekst, de embeddingaanroep in batch, het bewaren van de vector, en daarna het berekenen van de voorstellen met cosinusgelijkenis.

Het dashboard toont doorlopend: het totale aantal entiteiten, de actieve embeddings, de wachtende voorstellen, de actieve links en de statussen van de wachtrij (In afwachting, Bezig, Klaar en Fout).

Indicatieve kosten: 1000 producten in 3 talen komt op ongeveer 1,5 miljoen tokens, dus ongeveer 0,15 € (Mistral) of 0,03 $ (OpenAI). Dankzij de detectie met een SHA-256-hash betaalt u bij volgende indexeringen alleen voor de inhoud die werkelijk is gewijzigd.

## De voorstellen goedkeuren

Tabblad **Voorstellen**: een gepagineerde tabel met per regel de bron, het doel, de gelijkenisscore, het voorgestelde anker, een fragment met de context, en de knoppen **Invoegen** en **Weigeren**.

### Het anker kiezen

De ankergenerator haalt de n-grammen (2 tot 6 woorden) uit de doeltitel die letterlijk in de brontekst voorkomen, gerangschikt van het langste naar het kortste. De keuzelijst toont alle kandidaten; met de optie **Aanpassen** opent een vrij veld. Het standaardanker is het langste gevonden n-gram, doorgaans 3 of 4 woorden met de belangrijkste zoekwoorden van het doel.

### Invoegen

Bij het invoegen linkt de module het eerste voorkomen van het anker dat niet al in een `a`-, `code`- of `pre`-tag zit (met de PCRE-patronen SKIP en FAIL). Is er geen vrij voorkomen, dan komt er onder aan de beschrijving een terugvalparagraaf met de klasse `dfasl-related`. Elke link krijgt een attribuut `data-dfasl` met een unieke identificatie van 36 tekens.

### Bulkacties

Vink meerdere regels aan (met het vakje in de kolomkop selecteert u alles) en klik daarna op **De selectie invoegen** of **De selectie weigeren**. De paginering toont 50 regels.

## Een link weghalen (rollback)

Tabblad **Ingevoegde links**: een gepagineerde lijst met de actieve links, met de bron, het doel, het anker, de datum en de medewerker. De knop **Weghalen** wist alleen de `a data-dfasl`-tag met die identificatie: de ankertekst blijft intact, geen enkel ander HTML-element wordt geraakt, en de link wordt in de database als weggehaald gemarkeerd.

## CLI-worker en cron

Gebruik bij grote catalogi de worker op de opdrachtregel:

```
php modules/dfaisemanticlinks/bin/analyze.php [opties]
```

- `--shop=N`: richt zich op één bepaalde winkel (multistore).
- `--enqueue-all`: zet alle actieve entiteiten opnieuw in de wachtrij vóór het verwerken.
- `--loop`: blijft lopen zolang er items wachten.
- `--max-batches=N`: begrenst het aantal batches per run (een beveiliging tegen ontsporen).
- `--sleep=N`: een pauze in seconden tussen de batches (voor de rate limits van de API).

Een aanbevolen cron om het kwartier:

```
*/15 * * * * php /pad/naar/prestashop/modules/dfaisemanticlinks/bin/analyze.php --loop --max-batches=50 --sleep=1
```

De worker zet vermeldingen die al meer dan 30 minuten op « Bezig » blijven staan automatisch terug (na een vastgelopen vorige run), markeert de mislukte items met de foutmelding van de API, en verwerkt de rest van de batch gewoon verder.

## Automatisch opnieuw indexeren

De hooks `actionObjectProductUpdateAfter`, `actionObjectCategoryUpdateAfter` en `actionObjectCmsUpdateAfter` zetten de gewijzigde entiteit in alle actieve talen terug in de wachtrij. De verwijderhooks wissen de embeddings en de voorstellen in cascade. De SHA-256-inhoudshash voorkomt elke API-aanroep als de werkelijke tekst niet is veranderd (bijvoorbeeld bij een eenvoudige voorraadwijziging).

## Multistore en meertaligheid

De embeddings worden per drietal (entiteit, taal, winkel) afgebakend. De voorstellen overschrijden nooit de taal- of winkelgrenzen. De configuratie (API-sleutel, drempel, geïndexeerde types) kan per winkel verschillen, via de gewone multistore-contextkiezer van PrestaShop.

## Problemen oplossen

### « API-sleutel niet ingesteld » of een fout bij de verbindingstest

Controleer of de sleutel wel bij de aanbieder in de keuzelijst hoort (een Mistral-sleutel werkt niet met de OpenAI-provider en omgekeerd) en of er nog krediet is. De gedetailleerde API-fouten komen via PrestaShopLogger in **Geavanceerde parameters → Logboeken** terecht.

### Er blijven items op de status « Bezig » staan

Waarschijnlijk is een worker onderbroken. Wacht 30 minuten (dan volgt de automatische reset) of klik op **De wachtrij legen** en start daarna **Alles opnieuw indexeren**.

### Weinig of geen voorstellen

Er zijn drie veelvoorkomende oorzaken: een te hoge gelijkenisdrempel (probeer 0,72), te korte inhoud (onder de minimale lengte), of een catalogus die te homogeen of te heterogeen is. Controleer ook of de gewenste soorten entiteiten in de Instellingen aanstaan.

### Het voorgestelde anker is de ruwe titel van het doel

Dat is de terugvalmodus: geen enkel n-gram uit de doeltitel komt letterlijk in de brontekst voor. Kies een eigen anker of verrijk de bronbeschrijving.

## Technische architectuur

- PHP 8.1+ met strikte types, PSR-4 onder de namespace DataFirefly/AiSemanticLinks/ die naar `src/` wijst
- Legacy beheercontrollers `ModuleAdminController` (voor stabiele compatibiliteit met PS8 en PS9)
- Een eigen minicontainer voor de services (los van de Symfony-container)
- Vectoren als BLOB met float32 in little-endian, plus een vooraf berekende L2-norm
- 5 tabellen: `dfasl_embedding`, `dfasl_queue`, `dfasl_suggestion`, `dfasl_inserted_link` en `dfasl_job`
- Onversleutelde broncode, klaar om te overschrijven
