Benelux AI Job Scout
Een interne analysetool die twee uur handmatig zoeken naar vacatures in de Benelux verving door een gefilterd overzicht van 20 minuten — door het automatisch ophalen van 14 gratis bronnen en het classificeren van elke vacature op het ene signaal dat vacaturebanken nooit tonen: taaleisen
- Probleem — Zoeken naar ML/Data/AI-functies in de Benelux kostte ~2 uur/week; ~38% van relevante vacatures verbergt harde taaleisen die in de preview onzichtbaar zijn
- Inzicht — De woordenschat voor taaleisen is consistent en aanleernbaar, waardoor regelgebaseerde classifiers 5 van 7 dimensies aankunnen; een LLM is slechts nodig voor ~3% van de gevallen
- Oplossing — Ik bouwde de pipeline volledig solo: verzamelen uit 14 gratis bronnen, elke vacature classificeren op 6 dimensies + CV-match, in een filter-eerst React-dashboard
- Resultaat — Live op ai-job-hunter.ontwrpn.com; 282 vacatures geïndexeerd, 100% taalclassificatie; wekelijks zoeken van ~2 uur naar ~20 min (−83%), €0/maand
De blokkade was onzichtbaar — begraven in alinea drie
Zoeken naar ML/Data/AI-functies in België, Nederland en Luxemburg kostte elke maandag ongeveer twee uur. Het diepere probleem: ~38% van de vacatures die relevant leken, vereiste vloeiend Nederlands, Frans of Duits — een harde blokkade die nooit in de titel of vacaturepreview stond. Het verscheen drie alinea’s verder, aangegeven door een woord als vereist, requis of Voraussetzung. Een kandidaat zonder die taal besteedt tien minuten aan het lezen van een vacature waarvoor hij of zij nooit in aanmerking kon komen.
Drie samengestelde tekortkomingen: de zoektocht was versnipperd over vijf vacaturebanken zonder overlap; taaleisen waren systematisch verborgen; en zonder een relevantiesignaal leek elke vacature evenveel waard om te onderzoeken. Het resultaat was twee uur ongerichte zoektocht met een verouderde spreadsheet.
Het probleem was niet een gebrek aan vacatures. Het waren de kosten van het lezen van het juiste signaal uit de ruis
Acht weken zelfevaluatie vóór een regel code
De verkenningsfase liep door november 2025. Ik analyseerde mijn eigen zoeksessies over acht weken (gemiddeld: ~2 uur, waarvan ~40 minuten op taalgeblokkeerde vacatures), ondervroeg 12 actieve Benelux-bronnen op API-beschikbaarheid en ToS-beperkingen, en sampelde handmatig 50 ML/Data-vacatures van Adzuna BE en NL om de woordenschat van taaleisen te karakteriseren.
Belangrijkste bevindingen: Adzuna is de enige gratis bron die België en Nederland dekt met salarissignalen; VDAB vergrendelt API-toegang achter een ondertekende partnerovereenkomst; LinkedIn en Indeed zijn in de praktijk niet beschikbaar voor persoonlijke tools. Luxemburg heeft een structurele dekkingskloof — er bestaat geen lu-endpoint en ADEM publiceert geen live vacature-API. De woordenschat voor taalblokkades bleek consistent en aanleernbaar: vloeiend, vereist, courant, maîtrise, muttersprachlich, C1, B2 voor vereist; een plus, un atout, von Vorteil, nice to have voor optioneel.
~38% van de handmatig gesampelde vacatures bevatte een harde taaleis die onzichtbaar was in de vacaturepreview. De woordenschat was stabiel genoeg om regelgebaseerd te classificeren — met een LLM alleen nodig voor de ~3% ambigue gevallen waarbij formuleringen als “working language is French” de regex trotseerden.
Eerst regelgebaseerd; LLM alleen voor de ambigue 3%
De classificatiepipeline dekt zeven dimensies. Vijf bleken betrouwbaar regelgebaseerd: taal van de vacature (franc-min trigram-model), arbeidstype (meertalige regex), functiefamilie (titelpatroonmatching met fuzzy-fallback), senioriteit (titel-regex) en vaardigheidextractie (gazetteer van 50 termen met aliassen). Remote-type gebruikt een trefwoordclassifier. Alleen taaleisen escaleren naar een LLM — wanneer de modificator rond een taalvermelding onduidelijk is.
Het taalovereenkomstlabel heeft vier waarden: Goed (Engels OK), Misschien (lokale taal voorkeur), Risico (waarschijnlijk vereist, formulering ambigu), Blokkade (expliciet vereist). In de eerste productierun over 282 vacatures werd het LLM 8 keer aangeroepen — 8 van de 1.500 gratis dagelijkse Gemini-verzoeken. NLP-kosten: €0/maand. De regelgebaseerde logica is vier weken zonder een vals positief op de sterk-vereiste categorie gedraaid. Een fijnafgestemd model zou marginaal nauwkeuriger zijn op randgevallen; voor een woordenschatstabiel domein als HR-signaalwoorden is deterministische logica de juiste standaard.
Taalblokkades zichtbaar vóór het openen van een kaart — de classifier markeert harde eisen die vacaturebanken begraven in alinea drie
Filter-eerst-dashboard gebouwd rond het taalovereenkomstsignaal
14 gratis vacaturebronnen (Adzuna, EURES, Arbeitnow, Remotive, RemoteOK, Jobicy, The Muse, Greenhouse, Lever, Recruitee, SmartRecruiters, Ashby, Workable, HN Who’s-Hiring) voeden een dagelijkse verzamel→classificeer→embed-pipeline die in-process draait via node-cron. Elke vacature wordt geclassificeerd op zes dimensies en gescoord aan de hand van een geüpload CV via term-overlap matching. Het React-dashboard toont filters als URL-parameters — elke gefilterde weergave is deelbaar en overleeft een paginaverversing.
Een persistente taallegenda staat onder de filterbalk in elke weergave. De vacaturedetailpagina toont classificatielabels en een Solliciteer-knop boven de vouw — vóór de beschrijving. Zowel donker (standaard) als licht thema worden meegeleverd; de voorkeur wordt opgeslagen in localStorage via een enkel data-theme-attribuut op het rootelement. Een vijfstappige onboarding-tour begeleidt nieuwe gebruikers door de logica van de taallabels.

Live — 14 bronnen, 282+ vacatures geïndexeerd, filteren op taalovereenkomst, functiefamilie, senioriteit, remote-type
Donker thema (standaard)
Licht thema
Vacaturedetail — Solliciteer boven de vouw
Taallegenda — persistent in elke weergave
Wekelijks zoeken: 2 uur → 20 minuten. Infrastructuurkosten: €0
Live sinds mei 2026. Vier weken vroege productiedata (geschat op basis van bijgehouden sessies, geen rigoureuze studie): wekelijkse zoeksessie −83% (2 uur → 20 minuten); tijd op taalgeblokkeerde vacatures −95% (40 min → 2 min); tijd om Vandaag-Solliciteren-kandidaten te identificeren −92% (60 min → 5 min). 282 vacatures geïndexeerd in België (122), Nederland (145) en remote Benelux (15). 100% geclassificeerd met taalovereenkomst. Infrastructuurkosten: €0/maand — gedeelde Hetzner VPS met zelfgehoste Coolify en Postgres, LLM op de gratis tiers van Gemini/Groq.
Handmatige nauwkeurigheidsbeoordeling op 30 willekeurig gesampelde classificaties: taalovereenkomst 28/30 correct (twee valse positieven uit Nederlands in boilerplate juridische secties, een bekende fix in de wachtrij); arbeidstype 26/30; functiefamilie 29/30. Richtinggevend bemoedigend — geen rigoureuze studie. De dominante besparing zit in het filteren op taaleisen: de classifier toont de blokkade vóór het openen van de kaart, waardoor de tien-minuten-leesbeurten die nooit haalbare sollicitaties waren, worden geëlimineerd.
Het meest waardevolle signaal is vaak het signaal dat niemand toont. Elke vacaturebank weet van taaleisen. Geen enkele toont het als filter
Wat ik anders zou doen — en wat de €0-beperking me leerde
Drie eerlijke retrospectieve opmerkingen. Ten eerste: ik bouwde het dashboard vóór de fit-score. Tijdens de eerste vier weken in productie werden 282 vacatures alleen gesorteerd op plaatsingsdatum — niet wezenlijk anders dan een vacaturebank. Een fit-score vanaf dag één zou het product direct nuttig hebben gemaakt. Ten tweede: de taalblokkade-classifier werd gevalideerd aan de hand van een handmatige steekproef van 30 vacatures; de juiste validatie zou zijn geweest het loggen van sollicitatieresultaten vanaf het begin om echte recall/precisie te berekenen. Ten derde: VDAB — de rijkste bron voor Belgische vacatures — werd uitgesteld vanwege de vereiste partnerovereenkomst. Het had de eerste integratie moeten zijn.
De €0/maand-beperking dwong tot betere architectuur. Regelgebaseerde NLP vereist geen API en is voorspelbaar te debuggen bij fouten. De in-process node-cron-scheduler heeft geen betaalde cron-service nodig en draait op dezelfde machine als de data. De discipline van bouwen onder een harde kostengrens leverde meer draagbare, minder gekoppelde code op dan een open budget had kunnen doen.