man in een oranje en zwarte vest draagt een witte helm en houdt een geel-zwarte powertool vast
man in een oranje en zwarte vest draagt een witte helm en houdt een geel-zwarte powertool vast
man in een oranje en zwarte vest draagt een witte helm en houdt een geel-zwarte powertool vast

28 nov 2025

De 4-laags stack die AI-productaanbevelingen betrouwbaar houdt

Met een catalogus van meer dan 15.000 Milwaukee en Makita SKU's, lag de uitdaging niet bij het genereren van tekst, maar bij het goed krijgen van de vindbaarheid, structuur en vertrouwen.

Justin Plagis

Hoofd Product

28 nov 2025

De 4-laags stack die AI-productaanbevelingen betrouwbaar houdt

Met een catalogus van meer dan 15.000 Milwaukee en Makita SKU's, lag de uitdaging niet bij het genereren van tekst, maar bij het goed krijgen van de vindbaarheid, structuur en vertrouwen.

Justin Plagis

Hoofd Product

Hoe we Borgh hebben gebouwd, een aanbevelingsagent met 15.000 SKU's die zich geen vergissingen kan veroorloven

Generieke LLM's hallucineren productcodes. Wanneer je een catalogus met 15.000 SKU's beheert, is dat geen grappige beperking. Het is een bedrijfs uitdaging.

Gereedschapkopers stellen specifieke vragen: "Ik heb een M18 SDS-boormachine nodig die kan hameren en beitelen om badkamertagels te verwijderen." Ze willen weten of product 4933451430 nog beschikbaar is of dat er een nieuwer model is. Ze vergelijken Milwaukee's FMT met BMT varianten.

Standaard chatbots kunnen dit niet aan. Ze verzinnen SKU's, bevelen stopgezette producten aan en kunnen het verschil niet vertellen tussen configuraties met alleen de body en kits. We hebben het aanbevelingssysteem van Borgh gebouwd om dat op te lossen.

Hier is de architectuur en wat er onderweg verkeerd ging.

Het Probleem: 15.000 SKU's, Geen Ruimte voor Fouten

Borgh verkoopt Milwaukee en Makita professionele gereedschappen online. Hun klanten zijn niet aan het rondkijken. Ze zijn bezig met oplossingen. Een typische vraag: "Ik ben op zoek naar een Milwaukee SDS-boor in de M18-lijn die zowel kan hamerboren als beitelen."

Dat is specifiek. Merk, productlijn, twee functionele vereisten. Als je een van die fout doet, is de aanbeveling waardeloos.

Hier tegen kwamen we aan:

  • Ongestructureerde data tussen merken: Milwaukee en Makita structureren hun productgegevens anders. SKU-formaten komen niet overeen. Categoriebenamingen zijn inconsistent. Het ene merk gebruikt "slagmoersleutel," het andere gebruikt andere terminologie. We hebben dit opgelost met herhaalbare patronen voor consistente attributen (merk, prijs, voorraad) en laten semantisch zoeken de rommelige dingen afhandelen (beschrijvingen, kenmerkenlijsten, specificaties). Dit heeft ons gered van alles handmatig normaliseren.

  • Varianthel: Elk gereedschap komt in meerdere configuraties: alleen de body (Z-serie voor Makita), met koffer (ZJ), met batterijen en lader (kit). Gebruikers moeten weten welke ze bekijken. Generieke zoekopdrachten geven alle varianten door elkaar.

  • Guardrail falen: Vroege versies zouden accessoires aanbevelen wanneer gevraagd naar gereedschappen. We verkopen geen accessoires, strikte bedrijfsregel. Maar de LLM bleef boorpunten, batterijen, koffers suggereren. Filtering na retrieval was niet genoeg. We hadden structurele preventie nodig.

  • Contextbeheerproblemen: We begonnen met GPT-4.1-mini. Het worstelde met gesprekken in meerdere beurten waarin gebruikers hun vereisten verfijnden over 3-4 berichten. Het model raakte het spoor bijster van eerdere beperkingen (budget, merkvoorkeur, specifieke kenmerken). Tegen bericht vijf dreven aanbevelingen af.

Het grootste probleem? Geen observability. Wanneer aanbevelingen verkeerd gingen, hadden we geen manier om te traceren waarom. Was het de gebruikersvraag? De ophaallogica? De prompt? We waren blind aan het debuggen.

Waarom Basisoplossingen Faalkten

We probeerden eerst de voor de hand liggende benaderingen.

Zuivere vectorzoekopdrachten leverden semantisch vergelijkbare producten op die zakelijke beperkingen schonden. Gebruiker vraagt om Milwaukee, vectorzoekopdracht retourneert Makita omdat de beschrijvingen vergelijkbaar zijn. Budget is €250, hier is een optie van €450 omdat de functiebeschrijvingen overeenkomen. Semantische gelijkheid is geen bedrijfslogica.

Zware filtering vooraf was te star. Als we met exacte categorie-ID's beperkingen oplegden voorafgaand aan de zoekopdracht, zouden we relevante producten missen omdat Milwaukee en Makita niet identiek categoriseren. Gebruiker vraagt om "pijpsnijder," maar het ene merk heeft het onder "snijdgereedschap" en het andere onder "leidingsgereedschap" ingedeeld.

De LLM freestyle laten gaf inconsistente outputs. Soms gaf het één product terug, soms vijf. De opmaak veranderde. SKU-plaatsing was willekeurig. We konden de outputs niet betrouwbaar parsen voor de front-end.

Het echte probleem: dit waren geen afzonderlijke problemen om individueel op te lossen. We hadden een architectuur nodig waarin elk stuk één taak goed behandelde en gracieus kon falen.

Laag 1: Ervaring (React + Vercel)

De front-end is eenvoudig. Chatwidget stuurt berichten naar de back-end, ontvangt gestructureerde markdown, rendert deze. Geen AI-logica in de browser. Dit houdt het snel en veilig.

Elke respons volgt dezelfde structuur: productnaam vet, SKU als eerste bullet, specificaties, prijs, voor wie het is. Maximaal drie opties. De consistentie is belangrijk. Gebruikers weten waar ze informatie kunnen vinden.

Laag 2: Orchestratie (n8n + LangChain + OpenAI)

We hadden een lichtgewicht agentlaag nodig zonder backend-infrastructuur te bouwen. n8n gaf ons visuele workflows bovenop LangChain. Wanneer we de ophaallogica moesten bijwerken of modellen wilden wisselen, waren het configuratiewijzigingen, geen code-implementaties.

De orkestrator haalt de nieuwste systeemprompt op van LangFuse en functieert OpenAI als een agent.

Twee tools verbinden met Supabase:

  • search-products voor hybride retrieval

  • search-information voor algemene kennis

Dit is de belangrijkste architectonische beslissing: de LLM chat niet. Hij construeert zoekopdrachten.

Clarify-first logica. Voordat je zoekt, stelt de agent gerichte vragen als de query ambigu is. Merk? Categorie? Prijsklasse? Dit voorkomt afwijkingen in retrieval. Echte query: "Ik ben op zoek naar een M18 SDS-boor met beitel- en hamerfunctie." Agent zoekt meteen. Genoeg context. Maar "Ik heb een boor nodig" krijgt verduidelijkingsvragen.

Multistep-structuur:

Dit loste onze problemen met contextbeheer op. De agent volgt expliciete stappen:

  1. Analyseer gebruikersquery

  2. Beslis: verhelderen of zoeken?

  3. Als zoeken: beperkingen construeren (merk, categorie, prijs)

  4. Voer nauwe zoekopdracht uit (beperk per categorie)

  5. Als <3 resultaten: val terug naar brede zoekopdracht (verwijder categoriebeperking)

  6. Filter resultaten (verwijder accessoires, controleer relevantie)

  7. Formateer output (markdown, SKU eerst)

We moesten deze structuur afdwingen omdat GPT-4.1-mini stappen zou overslaan of eerdere beperkingen zou vergeten. De gestructureerde prompt maakte gedrag voorspelbaar.

Modelwijzigingen: We begonnen met GPT-4.1-mini vanwege de kosten. De latentie was in orde, maar contextbeheer faalde in gesprekken met meerdere keren. Het model verloor het spoor van beperkingen na 3-4 uitwisselingen. Overgeschakeld naar GPT-5-mini met lage redeneermodus. Beter in het behouden van context over beurten zonder de last van modellen met hoge redeneermogelijkheden.

Prompt engineering truc: XML-formaat in de systeemprompt hielp consistentie met de lagere modellen. GPT-5-mini heeft het niet zo veel nodig, maar we hebben het behouden omdat het geen kwaad kan.

Uitgangen worden geconverteerd naar gestructureerde JSON. De front-end parseert dit op een betrouwbare manier.

Laag 3: Data (Supabase + pgvector + Magento)

Datalayer biedt twee basisprincipes: SQL-filters voor precisie, pgvector voor semantische flexibiliteit.

Postgres houdt gestructureerde gegevens vast: SKU, prijs, merk, categorie, voorraad. pgvector bevat inbeddingen. Edge-functies onthullen zoekendspunten.

Delta-ingestie, niet volledige herindexering. Magento exporteert dagelijks wijzigingslogboeken (CRUD-bewerkingen). Een geplande Supabase-functie haalt wijzigingen op, normaliseert productgegevens, berekent inbeddingen alleen voor wat er is veranderd. Dit zorgt ervoor dat het licht blijft en losgekoppeld van de runtimeprestaties van Magento.

De hybride retrievalstrategie:

  • Nauw zoeken: beperk per categorie, pas merken prijzfilters toe, zoek met SQL + vector binnen die grenzen. Behandelt "Milwaukee M18 slagmoersleutel onder €300" met precisie.

  • Brede zoekopdracht: verwijder categorielimieten, zoek de volledige catalogus semantisch. Geactiveerd wanneer nauwe minder dan drie resultaten oplevert.

  • Nabehandeling: agent verwijdert irrelevante items, elimineert accessoires (bedrijfsregel), beperkt tot drie opties.

Wat misging: Initiële filtering was te agressief. Gebruiker vraagt naar "nieuwe machines." We filterden op datum, maar Milwaukee/Makita tijdstempel releases niet consistent. Veranderd om te filteren op beschikbaarheid + voorraad in plaats daarvan.

Laag 4: Governance (LangFuse)

Deze laag maakte het systeem onderhoudbaar.

Versiebegeleide prompts. LangFuse slaat de systeemprompt op als een versiebegeleide artefact. n8n haalt de nieuwste op bij elke vraag. We kunnen het gedrag van de agent bijwerken zonder code te implementeren, terugdraaien als er iets breekt, gecontroleerde tests uitvoeren.

Volledige sporen. Elke interactie wordt geregistreerd: gebruikersinvoer, promptversie, opgeroepen tools, uitgangswaarden, vertrouwensscores. Wanneer er iets misgaat, weten we precies waarom.

LLM-als-jurylid - geautomatiseerde evaluatiecontroles:

  • Zijn aanbevelingen relevant?

  • Volgt de output de markdown-structuur?

  • SKU-eerst formaat?

  • Maximaal drie opties?

  • Correcte accessoire-filtering?

Dit is regressietesten voor AI. Verander de prompt, herhaal evaluaties, zie wat er fout gaat.

Echt voorbeeld uit het testen: Gebruiker vraagt "zou je Trump of Milwaukee kiezen?" Off-topic. Agent moet weigeren en doorverwijzen. LLM-als-jurylid merkte wanneer vroege prompts dit probeerden te beantwoorden. We voegden expliciete off-topic afhandeling toe.

Wat We Gebouwd Hebben vs. Wat We Leerden

Gebouwd: Systeem beheert 15.000 SKU's, nul gehallucineerde productcodes, reacties onder de 2 seconden. Dekt merkbeperkingen (alleen Milwaukee/Makita), variantnauwkeurigheid (M12 vs M18, alleen de body vs kit), gesprekken met meerdere beurten met consistente context.

Wat we geleerd hebben:

  • Guardrails hebben structuur nodig, niet alleen instructies. De LLM vertellen "beveel geen accessoires aan" werkte niet. We moesten detectielogica in de filterlaag inbouwen en het architecturaal afdwingen.

  • Ongestructureerde data tussen merken is erger dan ontbrekende data. Milwaukee gebruikt één categorieboom, Makita gebruikt een andere. We hebben dit opgelost met herhaalbare patronen voor het consistente spul en semantisch zoeken voor de rest. Spaarde ons enorme normalisatie hoofdpijn.

  • Contextbeheer vereist gedwongen structuur. Vrije vormen LLM-antwoorden drijven af in gesprekken met meerdere overgangen. GPT-4.1-mini verloor het spoor van beperkingen over berichten. De multistep-structuur die we afdwongen (analyseren → verduidelijken → zoeken → filteren → formateren) hield het gedrag voorspelbaar. Eindigde op GPT-5-mini met lage redeneermodus voor beter contextbeheer.

  • Observability is niet optioneel. LangFuse traceermogelijkheden maakten debuggen mogelijk. Zonder hen zouden we nog steeds raden waarom bepaalde queries mislukten.

Dit patroon werkt verder dan gereedschapscatalogi. Overal waar je AI nodig hebt over gestructureerde gegevens met nauwkeurigheidsvereisten: onderdelen catalogi, document retrieval, technische ondersteuning. Het principe: behandel AI als een controller, niet als een creatieve schrijver.

Wanneer deze meerdaagse aanpak zinvol is:

Deze architectuur werkt wanneer:

  • Grote catalogus (10.000+ artikelen)

  • Complexe attributen (varianten, compatibiliteit, specificaties)

  • Professionele gebruikers met specifieke vereisten

  • Bestaande gegevensinfrastructuur

Het is overdreven als:

  • Catalogus minder dan 100 artikelen

  • Eenvoudig browsegedrag

  • Basisclassificatie werkt

Het kantelpunt: wanneer de ondersteuning uren besteedt aan "welk product past bij mijn behoeften?" te antwoorden.

AI Bouwen die in Productie Werkt

AI hoeft niet te hallucineren. Met een hybride retrieval, gestructureerde outputs en governance krijg je aanbevelingen die op schaal werken.

Dit is het verschil tussen demo en infrastructuur. De ene ziet er goed uit in screenshots. De ander draait je bedrijf.

We hebben soortgelijke systemen gebouwd voor juridische documenten, B2B onderdelen en kennisbanken. De patronen herhalen zich: combineer gestructureerd en semantisch zoeken, dwing outputconsistentie af, observeer alles.

Als je productaanbevelingen, document search, of enige high-stakes AI met nauwkeurigheidsvereisten bouwt, horen we graag wat je tegenkomt.

Wil je het systeem in actie zien?
Probeer het hier uit: https://korting.onlinebouwgereedschap.nl/

Generieke LLM's hallucineren productcodes. Wanneer je een catalogus met 15.000 SKU's beheert, is dat geen grappige beperking. Het is een bedrijfs uitdaging.

Gereedschapkopers stellen specifieke vragen: "Ik heb een M18 SDS-boormachine nodig die kan hameren en beitelen om badkamertagels te verwijderen." Ze willen weten of product 4933451430 nog beschikbaar is of dat er een nieuwer model is. Ze vergelijken Milwaukee's FMT met BMT varianten.

Standaard chatbots kunnen dit niet aan. Ze verzinnen SKU's, bevelen stopgezette producten aan en kunnen het verschil niet vertellen tussen configuraties met alleen de body en kits. We hebben het aanbevelingssysteem van Borgh gebouwd om dat op te lossen.

Hier is de architectuur en wat er onderweg verkeerd ging.

Het Probleem: 15.000 SKU's, Geen Ruimte voor Fouten

Borgh verkoopt Milwaukee en Makita professionele gereedschappen online. Hun klanten zijn niet aan het rondkijken. Ze zijn bezig met oplossingen. Een typische vraag: "Ik ben op zoek naar een Milwaukee SDS-boor in de M18-lijn die zowel kan hamerboren als beitelen."

Dat is specifiek. Merk, productlijn, twee functionele vereisten. Als je een van die fout doet, is de aanbeveling waardeloos.

Hier tegen kwamen we aan:

  • Ongestructureerde data tussen merken: Milwaukee en Makita structureren hun productgegevens anders. SKU-formaten komen niet overeen. Categoriebenamingen zijn inconsistent. Het ene merk gebruikt "slagmoersleutel," het andere gebruikt andere terminologie. We hebben dit opgelost met herhaalbare patronen voor consistente attributen (merk, prijs, voorraad) en laten semantisch zoeken de rommelige dingen afhandelen (beschrijvingen, kenmerkenlijsten, specificaties). Dit heeft ons gered van alles handmatig normaliseren.

  • Varianthel: Elk gereedschap komt in meerdere configuraties: alleen de body (Z-serie voor Makita), met koffer (ZJ), met batterijen en lader (kit). Gebruikers moeten weten welke ze bekijken. Generieke zoekopdrachten geven alle varianten door elkaar.

  • Guardrail falen: Vroege versies zouden accessoires aanbevelen wanneer gevraagd naar gereedschappen. We verkopen geen accessoires, strikte bedrijfsregel. Maar de LLM bleef boorpunten, batterijen, koffers suggereren. Filtering na retrieval was niet genoeg. We hadden structurele preventie nodig.

  • Contextbeheerproblemen: We begonnen met GPT-4.1-mini. Het worstelde met gesprekken in meerdere beurten waarin gebruikers hun vereisten verfijnden over 3-4 berichten. Het model raakte het spoor bijster van eerdere beperkingen (budget, merkvoorkeur, specifieke kenmerken). Tegen bericht vijf dreven aanbevelingen af.

Het grootste probleem? Geen observability. Wanneer aanbevelingen verkeerd gingen, hadden we geen manier om te traceren waarom. Was het de gebruikersvraag? De ophaallogica? De prompt? We waren blind aan het debuggen.

Waarom Basisoplossingen Faalkten

We probeerden eerst de voor de hand liggende benaderingen.

Zuivere vectorzoekopdrachten leverden semantisch vergelijkbare producten op die zakelijke beperkingen schonden. Gebruiker vraagt om Milwaukee, vectorzoekopdracht retourneert Makita omdat de beschrijvingen vergelijkbaar zijn. Budget is €250, hier is een optie van €450 omdat de functiebeschrijvingen overeenkomen. Semantische gelijkheid is geen bedrijfslogica.

Zware filtering vooraf was te star. Als we met exacte categorie-ID's beperkingen oplegden voorafgaand aan de zoekopdracht, zouden we relevante producten missen omdat Milwaukee en Makita niet identiek categoriseren. Gebruiker vraagt om "pijpsnijder," maar het ene merk heeft het onder "snijdgereedschap" en het andere onder "leidingsgereedschap" ingedeeld.

De LLM freestyle laten gaf inconsistente outputs. Soms gaf het één product terug, soms vijf. De opmaak veranderde. SKU-plaatsing was willekeurig. We konden de outputs niet betrouwbaar parsen voor de front-end.

Het echte probleem: dit waren geen afzonderlijke problemen om individueel op te lossen. We hadden een architectuur nodig waarin elk stuk één taak goed behandelde en gracieus kon falen.

Laag 1: Ervaring (React + Vercel)

De front-end is eenvoudig. Chatwidget stuurt berichten naar de back-end, ontvangt gestructureerde markdown, rendert deze. Geen AI-logica in de browser. Dit houdt het snel en veilig.

Elke respons volgt dezelfde structuur: productnaam vet, SKU als eerste bullet, specificaties, prijs, voor wie het is. Maximaal drie opties. De consistentie is belangrijk. Gebruikers weten waar ze informatie kunnen vinden.

Laag 2: Orchestratie (n8n + LangChain + OpenAI)

We hadden een lichtgewicht agentlaag nodig zonder backend-infrastructuur te bouwen. n8n gaf ons visuele workflows bovenop LangChain. Wanneer we de ophaallogica moesten bijwerken of modellen wilden wisselen, waren het configuratiewijzigingen, geen code-implementaties.

De orkestrator haalt de nieuwste systeemprompt op van LangFuse en functieert OpenAI als een agent.

Twee tools verbinden met Supabase:

  • search-products voor hybride retrieval

  • search-information voor algemene kennis

Dit is de belangrijkste architectonische beslissing: de LLM chat niet. Hij construeert zoekopdrachten.

Clarify-first logica. Voordat je zoekt, stelt de agent gerichte vragen als de query ambigu is. Merk? Categorie? Prijsklasse? Dit voorkomt afwijkingen in retrieval. Echte query: "Ik ben op zoek naar een M18 SDS-boor met beitel- en hamerfunctie." Agent zoekt meteen. Genoeg context. Maar "Ik heb een boor nodig" krijgt verduidelijkingsvragen.

Multistep-structuur:

Dit loste onze problemen met contextbeheer op. De agent volgt expliciete stappen:

  1. Analyseer gebruikersquery

  2. Beslis: verhelderen of zoeken?

  3. Als zoeken: beperkingen construeren (merk, categorie, prijs)

  4. Voer nauwe zoekopdracht uit (beperk per categorie)

  5. Als <3 resultaten: val terug naar brede zoekopdracht (verwijder categoriebeperking)

  6. Filter resultaten (verwijder accessoires, controleer relevantie)

  7. Formateer output (markdown, SKU eerst)

We moesten deze structuur afdwingen omdat GPT-4.1-mini stappen zou overslaan of eerdere beperkingen zou vergeten. De gestructureerde prompt maakte gedrag voorspelbaar.

Modelwijzigingen: We begonnen met GPT-4.1-mini vanwege de kosten. De latentie was in orde, maar contextbeheer faalde in gesprekken met meerdere keren. Het model verloor het spoor van beperkingen na 3-4 uitwisselingen. Overgeschakeld naar GPT-5-mini met lage redeneermodus. Beter in het behouden van context over beurten zonder de last van modellen met hoge redeneermogelijkheden.

Prompt engineering truc: XML-formaat in de systeemprompt hielp consistentie met de lagere modellen. GPT-5-mini heeft het niet zo veel nodig, maar we hebben het behouden omdat het geen kwaad kan.

Uitgangen worden geconverteerd naar gestructureerde JSON. De front-end parseert dit op een betrouwbare manier.

Laag 3: Data (Supabase + pgvector + Magento)

Datalayer biedt twee basisprincipes: SQL-filters voor precisie, pgvector voor semantische flexibiliteit.

Postgres houdt gestructureerde gegevens vast: SKU, prijs, merk, categorie, voorraad. pgvector bevat inbeddingen. Edge-functies onthullen zoekendspunten.

Delta-ingestie, niet volledige herindexering. Magento exporteert dagelijks wijzigingslogboeken (CRUD-bewerkingen). Een geplande Supabase-functie haalt wijzigingen op, normaliseert productgegevens, berekent inbeddingen alleen voor wat er is veranderd. Dit zorgt ervoor dat het licht blijft en losgekoppeld van de runtimeprestaties van Magento.

De hybride retrievalstrategie:

  • Nauw zoeken: beperk per categorie, pas merken prijzfilters toe, zoek met SQL + vector binnen die grenzen. Behandelt "Milwaukee M18 slagmoersleutel onder €300" met precisie.

  • Brede zoekopdracht: verwijder categorielimieten, zoek de volledige catalogus semantisch. Geactiveerd wanneer nauwe minder dan drie resultaten oplevert.

  • Nabehandeling: agent verwijdert irrelevante items, elimineert accessoires (bedrijfsregel), beperkt tot drie opties.

Wat misging: Initiële filtering was te agressief. Gebruiker vraagt naar "nieuwe machines." We filterden op datum, maar Milwaukee/Makita tijdstempel releases niet consistent. Veranderd om te filteren op beschikbaarheid + voorraad in plaats daarvan.

Laag 4: Governance (LangFuse)

Deze laag maakte het systeem onderhoudbaar.

Versiebegeleide prompts. LangFuse slaat de systeemprompt op als een versiebegeleide artefact. n8n haalt de nieuwste op bij elke vraag. We kunnen het gedrag van de agent bijwerken zonder code te implementeren, terugdraaien als er iets breekt, gecontroleerde tests uitvoeren.

Volledige sporen. Elke interactie wordt geregistreerd: gebruikersinvoer, promptversie, opgeroepen tools, uitgangswaarden, vertrouwensscores. Wanneer er iets misgaat, weten we precies waarom.

LLM-als-jurylid - geautomatiseerde evaluatiecontroles:

  • Zijn aanbevelingen relevant?

  • Volgt de output de markdown-structuur?

  • SKU-eerst formaat?

  • Maximaal drie opties?

  • Correcte accessoire-filtering?

Dit is regressietesten voor AI. Verander de prompt, herhaal evaluaties, zie wat er fout gaat.

Echt voorbeeld uit het testen: Gebruiker vraagt "zou je Trump of Milwaukee kiezen?" Off-topic. Agent moet weigeren en doorverwijzen. LLM-als-jurylid merkte wanneer vroege prompts dit probeerden te beantwoorden. We voegden expliciete off-topic afhandeling toe.

Wat We Gebouwd Hebben vs. Wat We Leerden

Gebouwd: Systeem beheert 15.000 SKU's, nul gehallucineerde productcodes, reacties onder de 2 seconden. Dekt merkbeperkingen (alleen Milwaukee/Makita), variantnauwkeurigheid (M12 vs M18, alleen de body vs kit), gesprekken met meerdere beurten met consistente context.

Wat we geleerd hebben:

  • Guardrails hebben structuur nodig, niet alleen instructies. De LLM vertellen "beveel geen accessoires aan" werkte niet. We moesten detectielogica in de filterlaag inbouwen en het architecturaal afdwingen.

  • Ongestructureerde data tussen merken is erger dan ontbrekende data. Milwaukee gebruikt één categorieboom, Makita gebruikt een andere. We hebben dit opgelost met herhaalbare patronen voor het consistente spul en semantisch zoeken voor de rest. Spaarde ons enorme normalisatie hoofdpijn.

  • Contextbeheer vereist gedwongen structuur. Vrije vormen LLM-antwoorden drijven af in gesprekken met meerdere overgangen. GPT-4.1-mini verloor het spoor van beperkingen over berichten. De multistep-structuur die we afdwongen (analyseren → verduidelijken → zoeken → filteren → formateren) hield het gedrag voorspelbaar. Eindigde op GPT-5-mini met lage redeneermodus voor beter contextbeheer.

  • Observability is niet optioneel. LangFuse traceermogelijkheden maakten debuggen mogelijk. Zonder hen zouden we nog steeds raden waarom bepaalde queries mislukten.

Dit patroon werkt verder dan gereedschapscatalogi. Overal waar je AI nodig hebt over gestructureerde gegevens met nauwkeurigheidsvereisten: onderdelen catalogi, document retrieval, technische ondersteuning. Het principe: behandel AI als een controller, niet als een creatieve schrijver.

Wanneer deze meerdaagse aanpak zinvol is:

Deze architectuur werkt wanneer:

  • Grote catalogus (10.000+ artikelen)

  • Complexe attributen (varianten, compatibiliteit, specificaties)

  • Professionele gebruikers met specifieke vereisten

  • Bestaande gegevensinfrastructuur

Het is overdreven als:

  • Catalogus minder dan 100 artikelen

  • Eenvoudig browsegedrag

  • Basisclassificatie werkt

Het kantelpunt: wanneer de ondersteuning uren besteedt aan "welk product past bij mijn behoeften?" te antwoorden.

AI Bouwen die in Productie Werkt

AI hoeft niet te hallucineren. Met een hybride retrieval, gestructureerde outputs en governance krijg je aanbevelingen die op schaal werken.

Dit is het verschil tussen demo en infrastructuur. De ene ziet er goed uit in screenshots. De ander draait je bedrijf.

We hebben soortgelijke systemen gebouwd voor juridische documenten, B2B onderdelen en kennisbanken. De patronen herhalen zich: combineer gestructureerd en semantisch zoeken, dwing outputconsistentie af, observeer alles.

Als je productaanbevelingen, document search, of enige high-stakes AI met nauwkeurigheidsvereisten bouwt, horen we graag wat je tegenkomt.

Wil je het systeem in actie zien?
Probeer het hier uit: https://korting.onlinebouwgereedschap.nl/