# Jakub Ćwirlej — Journalist die met AI bouwt

> Journalist (ongeveer twintig jaar bij de Poolse publieke omroep) die met AI bouwt — apps en zijn eigen kleine taalmodel voor code.
>
> Een samenvatting van de portfoliosite van Jakub Ćwirlej, gegenereerd uit de inhoud, om te gebruiken met een AI-assistent. Alle teksten staan hieronder volledig.

https://jakubcwirlej.com/nl/ · Gegenereerd uit de inhoud van de site: 2026-10-14

## Kernfeiten

- **Naam:** Jakub Ćwirlej
- **Rollen:** journalist (ongeveer twintig jaar bij de Poolse publieke omroep, TVP) die met AI bouwt: apps en zijn eigen kleine taalmodel voor code; onafhankelijk onderzoek (preprints)
- **Televisie:** ongeveer twintig jaar verslaggever voor de Poolse publieke omroep (TVP): reportages en documentaire items voor de actualiteitenprogramma's Magazyn Ekspresu Reporterów, Alarm, Telekurier en Reporterzy, van research en camerawerk tot de eindmontage; 48 van zijn reportages staan op de site met links naar TVP VOD
- **Woonplaats:** België, vlak bij Gent; hij woonde het grootste deel van zijn leven in Polen
- **Taalversies van de site:** Pools, Engels, Frans, Nederlands
- **Apps:**
  - **OrsonAI** — zijn eerste app, AI-tools voor journalisten: live transcriptie van interviews in een editor, een chatbot raadplegen over gekozen passages, certificaten van menselijk auteurschap op het ledger van Hedera Hashgraph (https://app.orsonai.com)
  - **Orson Rec** — getoond als live demo naast OrsonAI in het hoofdstuk Apps
  - **ViaSanto** — een gebedsapp: de rozenkrans kraal voor kraal, de heilige van de dag, gebedsdoelen zoals de noveen van Pompeï, de lezing van de dag, intenties van de gemeenschap met live tellers; live demo in het hoofdstuk Apps (https://viasanto.com)
- **Werken met AI:** hij schrijft geen code met de hand: hij ontwerpt de taken, leidt teams van AI-agents (één orchestrator per team; research, uitvoering gecontroleerd door twee onafhankelijke controleurs, verificatie) en controleert de resultaten met tests en metingen; zijn belangrijkste omgeving is Claude Code, met Gemini via de API als tweede mening; hij heeft gewerkt met Google Cloud (Vertex AI, Cloud Run, BigQuery, Firestore, Cloud Build, Secret Manager) en Firebase
- **EUGEN 160M:** zijn eigen kleine taalmodel voor code, vanaf nul getraind en nog in een vroeg stadium van de training; het vult code aan terwijl je typt en stelt de volgende regel voor, is ook getraind op fill-in-the-middle en vertaalt Python naar C++ en Rust (gecontroleerd door een compiler en tests); te proberen in de terminal op de AI-pagina (https://jakubcwirlej.com/nl/ai-dev/#terminal) of via de API (POST /agent/complete, POST /agent/translate)

Samenvattingen, kernpunten, kernfeiten en de FAQ zijn redactioneel (voor dit bestand geschreven op basis van de teksten van de site); de volledige teksten zijn de woorden van de auteur.

## Inhoud

1. Over
2. Hoofdstukken
   - [Media](#chapter-media)
   - [Apps](#chapter-apps)
   - [AI](#chapter-ai-dev)
3. Artikelen
4. Reportages op TVP VOD
5. EUGEN 160M proberen
6. Voor AI-agents
7. Volledige teksten
   - [Media — reportage en werken met beeld](#media)
   - [Over mij](#about-me)
   - [Mijn manier van werken](#approach)
   - [AI in de journalistiek](#ai-journalism)
   - [Hoe ik begon](#how-i-started)
   - [Wat ik heb geleerd door mijn eigen model te trainen](#training-lessons)
   - [Trainingsdata](#training-data)
   - [Een paar gedachten over AI-veiligheid](#ai-safety)
   - [De HDK-technologie](#hdk-tech)
8. Publicaties
9. CV
10. Contact
11. Hoe deze site is gebouwd — technische briefing
12. FAQ

## Over

Jakub Ćwirlej is een journalist die met AI bouwt. Ongeveer twintig jaar lang was hij verslaggever voor de Poolse publieke omroep (TVP) en maakte hij reportages en documentaire items voor actualiteitenprogramma's als Magazyn Ekspresu Reporterów, Alarm, Telekurier en Reporterzy — van research en camerawerk tot de eindmontage. Hij bouwt apps (onder meer OrsonAI en ViaSanto) en zijn eigen kleine taalmodel voor code, EUGEN 160M, dat nog in training is; daarnaast publiceert hij onafhankelijk onderzoek (preprints). Hij woont in België, vlak bij Gent.

## Hoofdstukken

- [Media](https://jakubcwirlej.com/nl/) — reportage en werken met beeld: zijn televisiewerk, zijn manier van werken, AI in de journalistiek
- [Apps](https://jakubcwirlej.com/nl/apps/) — de apps die hij bouwde — OrsonAI, Orson Rec en ViaSanto — met live demo's op de pagina
- [AI](https://jakubcwirlej.com/nl/ai-dev/) — zijn eigen taalmodellen trainen: hoe hij begon, de lessen, AI-veiligheid, en een terminal om EUGEN 160M te proberen

Alle teksten van de drie hoofdstukken in leesvolgorde: koppen, alinea’s, lijsten en de knoppen onder de alinea’s (met wat ze openen). De teksten van de vensters staan volledig onder „Volledige teksten”.

### Media {#chapter-media}

https://jakubcwirlej.com/nl/ — reportage en werken met beeld: zijn televisiewerk, zijn manier van werken, AI in de journalistiek

Hallo! Ik ben Kuba. Ik vertel graag verhalen die ertoe doen.

Knoppen:

- [Over mij](#about-me) — tekstvenster: Over mij · Markdown: https://jakubcwirlej.com/nl/articles/about-me.md

Waarom ik het werken met beeld zo waardeer? Heel eenvoudig. Beelden spreken een universele taal: ze roepen emoties op en vertellen verhalen op een manier die met woorden alleen niet over te brengen is. Mijn plek achter de lens gaf me een unieke vrijheid om me uit te drukken en verhalen vorm te geven.

Bijna twintig jaar lang maakte ik honderden reportages en documentaire bijdragen voor landelijke actualiteitenprogramma's zoals Magazyn Ekspresu Reporterów, Alarm, Telekurier en Reporterzy. Mijn journalistieke loopbaan begon weliswaar op een nieuwsredactie, maar al snel begreep ik dat ik een veelzijdige maker moest worden, iemand die elk aspect van het televisievak doorgrondt, als ik materiaal wilde maken dat de kijker echt vasthoudt. Daarom beperk ik me in mijn werk niet tot één rol. Ik ben verantwoordelijk voor het hele productieproces: van nauwgezette research, via het camerawerk, de interviews en het schrijven van de tekst, tot de uiteindelijke montage en postproductie.

Knoppen:

- Reportages op TVP VOD — lijst: [Reportages op TVP VOD](#reportages)

Mijn aanpak verweeft liefde voor de visuele kunsten met de koppige wil om verhalen te vertellen die in de werkelijkheid echt iets teweegbrengen. Het gaat niet alleen om de camera vasthouden, een vlotte montage of lastige vragen stellen – het gaat erom met beelden een band te smeden, mensen te betrekken en hen tot nadenken te dwingen.

In mijn reportages probeerde ik een stem te geven aan mensen die daar in het dagelijks leven volledig van verstoken zijn. Ombudsjournalistiek draait voor een groot deel om ontmoetingen met mensen in crisis – mensen die machteloos staan tegenover een harteloze bureaucratische machine, of die worstelen met de dramatische gevolgen van milieuaantasting. Een goed voorbeeld is de reeks reportages die ik maakte over het probleem van de zinkgaten en over de enorme maatschappelijke kosten die na de sluiting van de mijn Olkusz-Pomorzany van de ene dag op de andere op de plaatselijke gemeenschap neerkwamen.

Het werk in de meedogenloze wereld van de ombudsjournalistiek bracht me echter niet alleen empathie bij, maar ook het vermogen om bliksemsnel problemen op te lossen, en een keihard pragmatisme. Werken op locatie, niet zelden onder enorme tijdsdruk en in onvoorspelbare omstandigheden, dwong me tot volledige zelfstandigheid. Anderzijds is het juist die onafhankelijkheid die me de grootste vrijheid geeft: ze laat me verhalen van A tot Z vertellen.

Knoppen:

- [Mijn manier van werken](#approach) — tekstvenster: Mijn manier van werken · Markdown: https://jakubcwirlej.com/nl/articles/approach.md

Wat me altijd heeft gedreven, is pure nieuwsgierigheid naar de wereld. We leven in waanzinnig interessante tijden, en dat betekent dat je niet kunt blijven stilstaan: je moet je voortdurend ontwikkelen, je aannames toetsen en alles steeds opnieuw leren. Ik zie dat als een uitdaging waarin nieuwe technologieën een krachtige bondgenoot zijn. Precies door die honger naar kennis begon mijn werkwijze als reporter vanzelf op te schuiven richting oplossingen op basis van kunstmatige intelligentie. Vandaag zoek ik nieuwe uitdagingen op het snijvlak van media en technologie – daar waar de ervaring van een reporter en praktische kennis van AI samen meer opleveren dan elk afzonderlijk.

Knoppen:

- [AI in de journalistiek](#ai-journalism) — tekstvenster: AI in de journalistiek · Markdown: https://jakubcwirlej.com/nl/articles/ai-journalism.md

### Apps {#chapter-apps}

https://jakubcwirlej.com/nl/apps/ — de apps die hij bouwde — OrsonAI, Orson Rec en ViaSanto — met live demo's op de pagina

#### ViaSanto

ViaSanto is een gebedsapp die voortkwam uit een eenvoudige observatie uit het dagelijks leven: smartphones trekken ons tegenwoordig voortdurend weg van wat belangrijk is. In plaats van daartegen te vechten, besloot ik van de telefoon een bondgenoot van het gebed te maken. Veel mensen willen regelmatig bidden, maar verliezen het van de haast: een rozenkrans die in de tram begint, raakt snel onderbroken en kwijt, en een noveen van negen dagen wordt na één gemiste dag opgegeven. Velen bidden – door ziekte, leeftijd, emigratie of werk – alleen en hebben niemand om hun intenties mee te delen. ViaSanto laat je onderweg discreet bidden, houdt je voortgang en elke dag van een noveen bij, en brengt mensen die alleen bidden samen in een gemeenschap die voor hun intenties bidt.

Knoppen:

- [ViaSanto](https://viasanto.com)

De app draait om een virtuele, interactieve rozenkrans op het scherm van de telefoon. ViaSanto leidt je stap voor stap door de gekozen devoties, houdt je voortgang bij en herinnert je aan je intenties. Lichte gamificatie ondersteunt de gewoonte: volharding ontgrendelt nieuwe, zorgvuldig ontworpen kralenpatronen. De gemeenschapsruimte is net zo belangrijk – groepen waarin je intenties kunt delen en elkaar in gebed kunt steunen.

#### Bekijk hoe het werkt

In de telefoon naast deze tekst draait de echte app. Klik op het scherm om de besturing over te nemen.

- Zoek de eerste kraal die nog niet gebeden is (net boven de kralen met een gouden gloed) – druk erop en houd vast: in het vak bovenaan het scherm loopt de tekst van het gebed, en een balk toont de voortgang.
- Het uiterlijk van de rozenkrans verander je in de collectie (het boekpictogram in de onderste balk): kies ‘Różańce’ (Rozenkransen) en een ander patroon – de app neemt de kleuren ervan over, net als het kader rond deze tekst.
- Klik in het vak op ‘Czytanie na dziś’ (Lezing van vandaag) om de lezingen van de dag te openen.

De app is geschreven in Flutter: één codebase draait native op iOS en Android en in de browser. De logica, de data en hun beveiliging lopen via een zelf gehoste Supabase-backend (PostgreSQL) op Europese servers. Ik heb het geheel ontworpen op betrouwbaarheid: ViaSanto werkt ook offline – het slaat de voortgang op het toestel op en synchroniseert die met de server zodra er weer verbinding is.

#### OrsonAI

OrsonAI is een redactionele teksteditor met een ingebouwde AI-assistent, die ik heb gebouwd voor journalisten – zowel freelancers als redacties, die hij volledige ondersteuning moet bieden. Hij is gegroeid uit mijn eigen werk: schrijven, research en verificatie gebeuren tegenwoordig tegelijk, en in de praktijk betekent dat voortdurend heen en weer springen tussen documenten, de browser en notities. Hier gebeurt alles in één venster. Een geselecteerd fragment kun je aan de chat voorleggen zonder de hele context te kopiëren, transcripties van opgenomen interviews komen in de editor terecht, en aparte modi helpen je schrijven op basis van notities, informatie opzoeken, een tekst vóór publicatie controleren – van de feiten tot de juridische risico's – en documenten en opnames analyseren. Voordat een vraag naar een AI-model op externe servers gaat, kan de tekst worden geanonimiseerd, zodat namen van geïnterviewden en andere persoonsgegevens de redactie niet verlaten. De assistent helpt de journalist, maar neemt het werk niet over. De app is momenteel niet te koop, maar hij werkt en je kunt hem uitproberen in de gastmodus. Als redacties belangstelling tonen, sluit ik niet uit dat ik er verder aan werk.

Knoppen:

- [OrsonAI](https://app.orsonai.com)

Het meeste werk heb ik gestoken in de vertrouwenslaag. Elke interactie met de AI wordt gehasht – het hele pad van het project, via het document en het gesprek, tot de vraag en het antwoord – en een achtergrondproces controleert de verzamelde hashes elke minuut en verankert ze om de 1.000 gebeurtenissen in de Hedera Consensus Service. Op basis daarvan kan het systeem een tekst een certificaat van menselijk auteurschap toekennen: het beoordeelt het menselijke aandeel en de kwaliteit van de tekst, en als de tekst de drempels haalt, schrijft het de hash ervan in het openbare register van Hedera Hashgraph. Elke latere bewerking maakt het certificaat ongeldig, en de echtheid controleer je door de SHA-256-hash van het document te vergelijken met de vermelding in het register. Het auditmechanisme heb ik afgesplitst als een aparte, open bibliotheek, HDK, vanaf versie 0.1.3 onder de CC BY-NC 4.0-licentie (een gratis bibliotheek, alfa, met optionele verankering in Hedera; eerdere versies Apache 2.0). De backend is Python en FastAPI op Google Cloud in een Europese regio; de tekst wordt vooral door Gemini-modellen verwerkt, Mistral is de reserveleverancier en modellen van OpenAI werken aan de transcriptie.

Knoppen:

- [De HDK-technologie](#hdk-tech) — tekstvenster: De HDK-technologie · Markdown: https://jakubcwirlej.com/nl/articles/hdk-tech.md
- [Gratis HDK-bibliotheek](https://jakubcwirlej.com/files/hdk/hdk-audit-0.1.3.zip) — bestandsvenster
- [HDK op Hugging Face](https://huggingface.co/JakCwi/hdk-audit) (JakCwi/hdk-audit, licentie CC BY-NC 4.0)

#### Orson Rec

Orson Rec is een webapp om interviews op te nemen die je op het startscherm van je telefoon kunt installeren. Ik heb hem gemaakt voor verslaggevers in het veld, om hun uren terugluisteren en uittypen te besparen. Op een belangrijk moment in het gesprek druk je op CUT – het opgenomen fragment gaat meteen naar spraak-naar-tekst, zodat de transcriptie met tijdcodes fragment voor fragment op het scherm verschijnt terwijl het interview nog loopt. Belangrijke momenten markeer je met IN- en OUT-markeringen, en je voorbereide vragen heb je bij de hand in de prompter. Met de VO-modus neem je een voice-over op vanuit een tekst die in de OrsonAI-editor is voorbereid, en met de ingebouwde audio-editor knip je de opname bij. Het bestand exporteer je naar WAV, MP3 of AAC, en de transcriptie gaat met één klik naar de editor. De opname zelf gebeurt op de telefoon, maar voor de transcriptie is een internetverbinding nodig.

Knoppen:

- [Orson Rec](https://rec.orsonai.com)

### AI {#chapter-ai-dev}

https://jakubcwirlej.com/nl/ai-dev/ — zijn eigen taalmodellen trainen: hoe hij begon, de lessen, AI-veiligheid, en een terminal om EUGEN 160M te proberen

Eerste scherm: een terminal om EUGEN 160M te proberen: https://jakubcwirlej.com/nl/ai-dev/#terminal

#### EUGEN 160M

EUGEN 160M is een klein taalmodel dat helpt bij het schrijven van code: het vult code aan terwijl je typt (autocomplete) en stelt de volgende regel voor. Het is ook getraind om code midden in een bestand aan te vullen (fill-in-the-middle) en is gespecialiseerd in het vertalen van Python naar C++. Het heeft 164,5 miljoen parameters en wordt vanaf nul getraind op één NVIDIA RTX PRO 6000-kaart (96 GB). Door het kleine formaat genereert het ook op een gewone processor snel, tot ongeveer 270 tokens per seconde. Het model is te proberen in de terminal: klik op de knop hieronder.

Knoppen:

- [Goed om te weten…](#how-i-started) — tekstvenster: Hoe ik begon · Markdown: https://jakubcwirlej.com/nl/articles/how-i-started.md

#### Eerste resultaten

De training staat nog aan het begin, en de resultaten geven nu al reden tot optimisme. Op HumanEval, waarin het model een Python-functie schrijft op basis van een beschrijving, zijn de best gemeten resultaten van EUGEN 18,9% van de taken bij één poging en 32,9% bij tien. Bij geverifieerde vertaling van Python naar C++ – compiler en tests kiezen een werkende versie uit meerdere voorstellen van het model – compileren 77 van de 100 programma's en slagen er 53 voor alle tests. De stack van het model zorgt ervoor dat alleen vertaalvoorstellen die deze controles doorstaan de gebruiker bereiken. De grafiek zet de resultaten van EUGEN af tegen modellen tot 0,5 miljard parameters.

Knoppen:

- [Wat ik heb geleerd door mijn eigen model te trainen](#training-lessons) — tekstvenster: Wat ik heb geleerd door mijn eigen model te trainen · Markdown: https://jakubcwirlej.com/nl/articles/training-lessons.md

#### Modelarchitectuur

EUGEN is een decoder-only transformer met 36 lagen, getraind met MuonH, een variant van Muon die de norm van de gewichtsmatrices constant houdt. Het model zit in de basistraining. Ongeveer 0,35% van de data is eigen data: STaR-oplossingen die EUGEN zelf genereerde en die de tests doorstonden, en vertaalparen tussen Python en C++, Java, Go en Rust, gecontroleerd met compilatie en tests.

Knoppen:

- [Trainingsdata](#training-data) — tekstvenster: Trainingsdata · Markdown: https://jakubcwirlej.com/nl/articles/training-data.md

#### Sparse FFN, Triton-kernel

Ik werk ook aan het optimaliseren en versnellen van de training met een sparse FFN en heb daarvoor een eigen GPU-kernel ontwikkeld, geschreven in Triton. In een model van 306 miljoen parameters (FFN 4.096) haalde de geoptimaliseerde kernel een 36% hogere doorvoer dan zijn eerste versie. Onze eerste tests laten zien dat met een groter model en een FFN van 8.192 de sparse kernel uit het EUGEN-project een versnelling van meer dan 40% ten opzichte van een dense model kan opleveren. Of een sparse getraind en aan het eind verdicht model gelijk komt met een dense model, is nog open, maar de eerste resultaten brengen me ertoe het volgende, grotere model zo te trainen.

Knoppen:

- [Kernel op Hugging Face](https://huggingface.co/JakCwi/eugen-sparse) (JakCwi/eugen-sparse, licentie CC BY-NC 4.0)

#### TetherGate: geleerde gates stabiliseren

TetherGate is een mechanisme dat voorkomt dat geleerde gates dichtgaan. Een gate die een residuele tak schaalt – een expert, een adapter of een nieuw toegevoegde laag – wordt door de optimizer vaak geleidelijk naar nul gedrukt, waarna de tak niets meer aan het model bijdraagt. TetherGate combineert een ondergrens die afhangt van de trainingsstap met een veer die de drempel van de gate naar een bewegend anker trekt, berekend uit het actuele stuursignaal. Dat signaal kan elke statistiek zijn. Ik heb het mechanisme experimenteel getest in mijn eigen modellen.

Knoppen:

- [TetherGate downloaden (.zip)](https://jakubcwirlej.com/files/tethergate.zip) — downloadt het bestand (tethergate.zip (code, README, tests), licentie CC BY-NC 4.0)
- [TetherGate op Hugging Face](https://huggingface.co/JakCwi/tethergate) (JakCwi/tethergate, licentie CC BY-NC 4.0)

#### Eigen onderzoek

Ik doe voortdurend eigen onderzoek naar AI. Dat gaat onder meer over signalen uit het netwerk zelf: de activaties van de gates in FFN-lagen en de daarop gebaseerde Gate Sparseness Index (GSI), die volgens voorlopige resultaten kan helpen om nog vóór het antwoord vragen waarop het model het antwoord weet te onderscheiden van vragen waarbij het begint te confabuleren. Latere analyse liet zien dat een deel van het effect voortkomt uit de lengte van de vragen – na correctie daarvoor blijft het signaal bij het Llama-model overeind, de andere resultaten moeten opnieuw worden gemeten. Ik heb geen formele opleiding in dit vakgebied, maar ik probeer zo professioneel mogelijk te werken: met openbaar gemaakte data, herhaalbare metingen en duidelijk benoemde beperkingen.

Knoppen:

- [Een paar gedachten over AI-veiligheid](#ai-safety) — tekstvenster: Een paar gedachten over AI-veiligheid · Markdown: https://jakubcwirlej.com/nl/articles/ai-safety.md

#### Hoe ik met AI werk

Ik schrijf geen code met de hand. Ik ontwerp de taken en leid teams van AI-agents, en elk resultaat controleer ik. Een team werkt in drie fasen: research, uitvoering en verificatie. Twee onafhankelijke controleurs houden toezicht op de uitvoering: de ene bewaakt de reikwijdte van de taak, de andere de technische kwaliteit.

Ik leid twee à drie van zulke teams tegelijk, dus als één taak mijn aandacht nodig heeft, gaan de andere gewoon door. Als een model vastloopt, leg ik het probleem voor aan een model van een ander bedrijf.

Ik besteed grote brokken werk uit, maar alleen tot de grens waarop ik ze nog grondig kan controleren, en daarna reserveer ik tijd voor correcties. Of iets klaar is, beslist een test of een meting, niet de bewering van het model.

#### Meer

Knoppen:

- [Gedachten over AI-veiligheid](#ai-safety) — tekstvenster: Een paar gedachten over AI-veiligheid · Markdown: https://jakubcwirlej.com/nl/articles/ai-safety.md
- [Coherence Over Truth](https://www.researchgate.net/publication/397730862) — Publicaties: [Coherence Over Truth: On Minds, Models and Reality](#coherence-over-truth)
- [HDK: AI-audittrails](https://www.researchgate.net/publication/400762996) — Publicaties: [HDK: Tamper-Evident LLM Audit Trails with Hierarchical Hash Genealogy and Distributed Ledger Anchoring](#hdk-tamper-evident-audit-trails)
- [Kwantumbarrières voor AGI](https://www.researchgate.net/publication/400670258) — Publicaties: [Self-Referential Quantum Barriers for AGI Containment: A Physics-Based Framework for Probabilistic Safety Engineering](#agi-quantum-containment)

## Artikelen

- [Media — reportage en werken met beeld](https://jakubcwirlej.com/nl/articles/media.md) (`media`) — Jakub Ćwirlej legt uit waarom hij zo hecht aan werken met beeld, dat volgens hem een universele taal spreekt. Hij beschrijft bijna twintig jaar reportages en documentaire items voor Poolse actualiteitenprogramma's, waarvoor hij de hele productie zelf verzorgde, en zijn streven om een stem te geven aan mensen die er geen hebben. Hij verbindt zijn nieuwsgierigheid naar de wereld met de manier waarop zijn reportagegereedschap opschoof naar tools op basis van AI.
- [Over mij](https://jakubcwirlej.com/nl/articles/about-me.md) (`about-me`) — Een persoonlijk portret waarin de auteur zichzelf beschrijft als iemand die vaste standpunten vermijdt, wat hij voor een journalist of onderzoeker een troef vindt. Hij schetst zijn weg van het atelier van zijn grootvader en een jeugdplan om docent filosofie te worden naar twintig jaar als verslaggever voor de Poolse publieke omroep, en zegt dat de journalistiek hem hielp zijn angst om beoordeeld te worden te overwinnen. Hij schrijft ook over zijn gezin, de boeken en muziek waarvan hij houdt en zijn recente verhuizing naar België, vlak bij Gent.
- [Mijn manier van werken](https://jakubcwirlej.com/nl/articles/approach.md) (`approach`) — Voor de auteur is journalistiek in de eerste plaats een manier om de wereld te leren kennen en voortdurend bij te leren, en ook een vorm van dienstbaarheid: ongeacht zijn stemming of het risico is het zijn taak het verhaal af te leveren, omdat mensen het recht hebben om te weten. Hij betoogt dat televisie nooit objectief is, omdat subjectiviteit al begint bij de keuze van de shots en doorloopt in de montage, en dat de echte ethische plicht is de tijd van de kijker niet te verspillen. Hij legt uit hoe zorgvuldig hij zich op locatie voorbereidt en waarom hij nooit naar prijzen heeft gestreefd.
- [AI in de journalistiek](https://jakubcwirlej.com/nl/articles/ai-journalism.md) (`ai-journalism`) — De auteur, die sinds de lancering van ChatGPT bijna dagelijks AI gebruikt, erkent de risico's ervan, vooral hallucinaties, maar betoogt dat pragmatisch gebruik van de technologie het vak versterkt: hij praat met een chatbot op de terugweg van opnames, automatiseert transcriptie en gebruikt OSINT-tools, al kan nog geen enkel model van ruwe interviews een televisie-‘stramien’ maken. Hij vindt het weinig zinvol teksten op hun klank te beoordelen, omdat AI-detectoren zich in beide richtingen vergissen, en merkt op dat de Europese AI Act vraagt wie voor een tekst verantwoordelijk is, maar de lezer geen middel geeft om na te gaan wie hem schreef. Hij verwacht dat journalisten die blijven onderzoeken en itereren het goed zullen doen, en dat vooral wie alleen schema's herhaalt zijn baan verliest.
- [Hoe ik begon](https://jakubcwirlej.com/nl/articles/how-i-started.md) (`how-i-started`) — De auteur vertelt hoe het bouwen van OrsonAI, een reeks AI-tools voor zijn eigen journalistieke werk, hem van vibecoding naar onderzoek naar hallucinaties van taalmodellen en naar het trainen van eigen modellen bracht. Hij beschrijft de koele ontvangst van de app in de branche, zijn onderzoek naar de activaties van SwiGLU-gates en het mislukken van zijn eerste model op een eigen architectuur. Vandaag traint hij EUGEN 160M, een klein model gespecialiseerd in code dat in een terminal op de site te proberen is.
- [Wat ik heb geleerd door mijn eigen model te trainen](https://jakubcwirlej.com/nl/articles/training-lessons.md) (`training-lessons`) — Tien praktische lessen uit de ervaring van de auteur met het zelf trainen van taalmodellen. Ze gaan over te optimistische rekenschattingen, klein beginnen, voortdurende monitoring, geïsoleerde wijzigingen en ablatietests, de keuze van data, realistische verwachtingen, geduld tijdens plateaus en de behoefte aan meer dan één GPU. Hij besluit dat kleine, gespecialiseerde modellen van individuele makers nog steeds zinvol zijn.
- [Trainingsdata](https://jakubcwirlej.com/nl/articles/training-data.md) (`training-data`) — De trainingsmix van EUGEN 160M per Hugging Face-repository: 14 rijen die 93,4% van de huidige tokenstroom dekken. Dolma 3 is het grootste deel (35,29%, inclusief Stack-Edu en Common Crawl per onderwerp), gevolgd door The Stack v3 (15,44%) en commitgeschiedenissen uit CommitPack en verwante datasets (10,46%). Eigen data – STaR-oplossingen die EUGEN genereerde en die met tests zijn geverifieerd, plus vertaalparen van code – vormen ongeveer 0,35% van de mix.
- [Een paar gedachten over AI-veiligheid](https://jakubcwirlej.com/nl/articles/ai-safety.md) (`ai-safety`) — Een essay over AI-veiligheid waarin de auteur een oppervlakkig publiek debat bekritiseert dat verdeeld is tussen technomaximalisten en doemprofeten. Hij betoogt dat het ergste waarschijnlijk al begonnen is, gezien autonome wapens, toenemende surveillance en de ideologie van het technomaximalisme, en dat de verantwoordelijkheid altijd bij mensen moet liggen, omdat machines geen eigen handelingsvermogen hebben. Hij stelt concrete regelgevende maatregelen voor en waarschuwt tegen de antropomorfisering van AI.
- [De HDK-technologie](https://jakubcwirlej.com/nl/articles/hdk-tech.md) (`hdk-tech`) — De auteur beschrijft HDK, een gratis Python-bibliotheek (CC BY-NC 4.0; eerdere versies Apache 2.0) uit OrsonAI die manipulatie van vastgelegde gesprekken met taalmodellen aantoonbaar maakt. Ze hasht elke gebeurtenis met al haar voorouders, voegt een aan een geheim gekoppelde kanarieteller toe en verankert Merkle-roots op de Hedera Consensus Service.

## Reportages op TVP VOD {#reportages}

De eigen reportages van de auteur voor de Poolse publieke omroep (TVP), met links naar TVP VOD, gegroepeerd per programma, nieuwste eerst. De data zijn uitzenddata (JJJJ-MM-DD); de titels zijn in het Pools, zoals op TVP VOD. Sommige afleveringen bevatten meerdere reportages: waar een starttijd (mm:ss) staat, begint zijn item daar.

### Reporterzy (40 afleveringen)

- 2026-08-14 — [Dom w pułapce](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-591,S02E591,3256128)
- 2026-07-17 — [Czeski złodziej](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-571,S02E571,3176812)
- 2026-07-13 — [Zamknięta droga do jeziora](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-567,S02E567,3164772)
- 2026-06-30 — [Droga przez pole](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-558,S02E558,3127029)
- 2026-05-18 — [Kłopoty spółdzielni](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-527,S02E527,2999531)
- 2026-05-11 — [Schronisko grozy](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-522,S02E522,2975164)
- 2026-04-27 — [Zbiorniki w Szczecinie](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-513,S02E513,2936795)
- 2026-04-20 — [Cofnięta zgoda na budowę](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-508,S02E508,2915241)
- 2026-04-07 — [Zawalony dach – co dalej?](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-499,S02E499,2879609)
- 2026-03-24 — [Osiedle Maltańskie sprzedane](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-490,S02E490,2839753)
- 2026-02-16 — [Łabędzie umierają w zatoce](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-464,S02E464,2740643)
- 2026-01-30 — [Zawalony dom](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-453,S02E453,2694986)
- 2026-01-02 — [Zalewane domy](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-434,S02E434,2623068)
- 2025-12-05 — [Domy nad jeziorem](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-408,S02E408,2552153)
- 2025-11-21 — [Odebrane mieszkanie](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-398,S02E398,2520281)
- 2025-11-17 — [Odbieranie zwierząt](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-394,S02E394,2511477)
- 2025-11-05 — [Polowanie na mandat?](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-387,S02E387,2484673)
- 2025-10-28 — [Szczury w Szczecinie](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-381,S02E381,2463194)
- 2025-10-22 — [Płot na drodze dojazdowej](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-377,S02E377,2453392)
- 2025-10-06 — [Co zatruwa Berlinek?](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-365,S02E365,2417050)
- 2025-08-20 — [Bloki do rozebrania](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-337,S02E337,2310978)
- 2025-08-12 — [Kolekcjonerka dworków](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-331,S02E331,2293557)
- 2025-08-05 — [Uzdrowisko widmo](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-327,S02E327,2277448)
- 2025-07-22 — [Oszukani „Na mieszkanie”](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-318,S02E318,2246122)
- 2025-06-20 — [Afera finansowa w Obornikach](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-296,S02E296,2175283)
- 2025-06-17 — [Śmierdząca wioska](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-293,S02E293,2168790)
- 2025-06-11 — [Droga przez salę](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-289,S02E289,2155669)
- 2025-06-02 — [To może być koniec rybackiego Helu](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-282,S02E282,2135757)
- 2025-05-23 — [Zawraca Wartę](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-276,S02E276,2113874)
- 2025-04-09 — [Ciechocinek](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-249,S02E249,2020351)
- 2025-03-21 — [Żubry (nie) pod ochroną](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-236,S02E236,1980171)
- 2025-03-13 — [Zapadliska finał](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-230,S02E230,1964013)
- 2025-02-12 — [Zapadliska II](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-209,S02E209,1903959)
- 2025-01-16 — [AI – zagrożenia](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-192,S02E192,1848618)
- 2025-01-10 — [Zapadliska](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-188,S02E188,1835997)
- 2024-11-14 — [Burmistrz biznesmen](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-149,S02E149,1715678)
- 2024-11-05 — [Biogazownia Ciechocinek](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-142,S02E142,1696658)
- 2024-10-17 — [Pył węglowy](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-130,S02E130,1658205)
- 2024-08-08 — [aflevering zonder titel](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-80,S02E80,1504121)
- 2024-05-09 — [aflevering zonder titel](https://vod.tvp.pl/informacje-i-publicystyka,205/reporterzy-odcinki,1162990/odcinek-46,S02E46,1302768)

### Magazyn Ekspresu Reporterów (8 afleveringen)

- 2021-09-28 — [Uwięzieni w smrodzie](https://vod.tvp.pl/informacje-i-publicystyka,205/magazyn-ekspresu-reporterow-odcinki,273697/odcinek-925,S01E925,380779)
- 2021-04-20 — [Śmierdząca sprawa](https://vod.tvp.pl/informacje-i-publicystyka,205/magazyn-ekspresu-reporterow-odcinki,273697/odcinek-914,S01E914,302568)
- 2021-01-26 — [Hotel na lata](https://vod.tvp.pl/informacje-i-publicystyka,205/magazyn-ekspresu-reporterow-odcinki,273697/odcinek-902,S01E902,300904)
- 2020-12-08 — [Chcemy godnie żyć](https://vod.tvp.pl/informacje-i-publicystyka,205/magazyn-ekspresu-reporterow-odcinki,273697/odcinek-895,S01E895,299253)
- 2020-11-03 — [Dożywocie](https://vod.tvp.pl/informacje-i-publicystyka,205/magazyn-ekspresu-reporterow-odcinki,273697/odcinek-890,S01E890,391108) — zijn item begint op 28:05
- 2020-10-13 — [Okno z widokiem](https://vod.tvp.pl/informacje-i-publicystyka,205/magazyn-ekspresu-reporterow-odcinki,273697/odcinek-887,S01E887,297265)
- 2020-09-22 — [Chcemy godnie żyć](https://vod.tvp.pl/informacje-i-publicystyka,205/magazyn-ekspresu-reporterow-odcinki,273697/odcinek-884,S01E884,391122)
- 2020-09-08 — [W cieniu kominów](https://vod.tvp.pl/informacje-i-publicystyka,205/magazyn-ekspresu-reporterow-odcinki,273697/odcinek-882,S01E882,297534) — zijn item begint op 21:38

## EUGEN 160M proberen

EUGEN 160M is Jakubs eigen kleine taalmodel voor code, vanaf nul getraind en nog in een vroeg stadium van de training. Het vult code aan terwijl je typt en stelt de volgende regel voor; het is ook getraind om code midden in een bestand aan te vullen (fill-in-the-middle) en vertaalt Python naar C++ en Rust. Probeer het in de terminal op de AI-pagina, of via de API voor AI-agents:

- https://jakubcwirlej.com/nl/ai-dev/#terminal
- `POST https://jakubcwirlej.com/api/agent/complete` — {"code", "suffix"?, "mode": "inline" | "next_line" | "block"} → {"completion", …}
- `POST https://jakubcwirlej.com/api/agent/translate` — {"code", "to": "cpp" | "java" | "rust"} → {"ok", "code", …}

```http
POST https://jakubcwirlej.com/api/agent/complete
Content-Type: application/json

{"code": "def is_prime(n):\n    ", "mode": "block"}
```

```http
POST https://jakubcwirlej.com/api/agent/translate
Content-Type: application/json

{"code": "def add(a, b):\n    return a + b\n", "to": "rust"}
```

## Voor AI-agents

Een AI-agent kan de teksten van de site doorzoeken, vragen stellen aan Jakubs chatagent en EUGEN testen via een kleine JSON-API. Volledige beschrijving en limieten: https://jakubcwirlej.com/api/agent

- `POST https://jakubcwirlej.com/api/agent/search` — {"query", "lang"?, "k"?} → passages of the site's texts (4 languages)
- `POST https://jakubcwirlej.com/api/agent/interview` — {"question", "lang"?, "session_id"?} → {"answer", "session_id", …}
- https://jakubcwirlej.com/llms.txt

## Volledige teksten

### Media — reportage en werken met beeld {#media}

id: `media` · taal van de tekst: NL · 484 woorden · Markdown: https://jakubcwirlej.com/nl/articles/media.md

**Samenvatting (redactioneel):** Jakub Ćwirlej legt uit waarom hij zo hecht aan werken met beeld, dat volgens hem een universele taal spreekt. Hij beschrijft bijna twintig jaar reportages en documentaire items voor Poolse actualiteitenprogramma's, waarvoor hij de hele productie zelf verzorgde, en zijn streven om een stem te geven aan mensen die er geen hebben. Hij verbindt zijn nieuwsgierigheid naar de wereld met de manier waarop zijn reportagegereedschap opschoof naar tools op basis van AI.

**Kernpunten (redactioneel):**

- Hij maakte honderden reportages en documentaire items voor programma's als Magazyn Ekspresu Reporterów, Alarm, Telekurier en Reporterzy.
- Hij begon als journalist op een nieuwsredactie en werd een allround maker die verantwoordelijk is voor research, camerawerk, interviews, tekst, montage en postproductie.
- Ombudsjournalistiek draait volgens hem om ontmoetingen met mensen in crisis; een voorbeeld is zijn reeks over de zinkgaten na de sluiting van de mijn Olkusz-Pomorzany.
- Het werk in het veld, onder tijdsdruk, leerde hem snel problemen op te lossen, pragmatisme en zelfstandigheid.
- Zijn nieuwsgierigheid bracht zijn reportagegereedschap naar tools op basis van AI.

**Volledige tekst (de woorden van de auteur):**

Hallo! Ik ben Kuba. Ik vertel graag verhalen die ertoe doen.

Waarom ik het werken met beeld zo waardeer? Heel eenvoudig. Beelden spreken een universele taal: ze roepen emoties op en vertellen verhalen op een manier die met woorden alleen niet over te brengen is. Mijn plek achter de lens gaf me een unieke vrijheid om me uit te drukken en verhalen vorm te geven.

Bijna twintig jaar lang maakte ik honderden reportages en documentaire bijdragen voor landelijke actualiteitenprogramma's zoals Magazyn Ekspresu Reporterów, Alarm, Telekurier en Reporterzy. Mijn journalistieke loopbaan begon weliswaar op een nieuwsredactie, maar al snel begreep ik dat ik een veelzijdige maker moest worden, iemand die elk aspect van het televisievak doorgrondt, als ik materiaal wilde maken dat de kijker echt vasthoudt. Daarom beperk ik me in mijn werk niet tot één rol. Ik ben verantwoordelijk voor het hele productieproces: van nauwgezette research, via het camerawerk, de interviews en het schrijven van de tekst, tot de uiteindelijke montage en postproductie.

Mijn aanpak verweeft liefde voor de visuele kunsten met de koppige wil om verhalen te vertellen die in de werkelijkheid echt iets teweegbrengen. Het gaat niet alleen om de camera vasthouden, een vlotte montage of lastige vragen stellen – het gaat erom met beelden een band te smeden, mensen te betrekken en hen tot nadenken te dwingen.

In mijn reportages probeerde ik een stem te geven aan mensen die daar in het dagelijks leven volledig van verstoken zijn. Ombudsjournalistiek draait voor een groot deel om ontmoetingen met mensen in crisis – mensen die machteloos staan tegenover een harteloze bureaucratische machine, of die worstelen met de dramatische gevolgen van milieuaantasting. Een goed voorbeeld is de reeks reportages die ik maakte over het probleem van de zinkgaten en over de enorme maatschappelijke kosten die na de sluiting van de mijn Olkusz-Pomorzany van de ene dag op de andere op de plaatselijke gemeenschap neerkwamen.

Het werk in de meedogenloze wereld van de ombudsjournalistiek bracht me echter niet alleen empathie bij, maar ook het vermogen om bliksemsnel problemen op te lossen, en een keihard pragmatisme. Werken op locatie, niet zelden onder enorme tijdsdruk en in onvoorspelbare omstandigheden, dwong me tot volledige zelfstandigheid. Anderzijds is het juist die onafhankelijkheid die me de grootste vrijheid geeft: ze laat me verhalen van A tot Z vertellen.

Wat me altijd heeft gedreven, is pure nieuwsgierigheid naar de wereld. We leven in waanzinnig interessante tijden, en dat betekent dat je niet kunt blijven stilstaan: je moet je voortdurend ontwikkelen, je aannames toetsen en alles steeds opnieuw leren. Ik zie dat als een uitdaging waarin nieuwe technologieën een krachtige bondgenoot zijn. Precies door die honger naar kennis begon mijn werkwijze als reporter vanzelf op te schuiven richting oplossingen op basis van kunstmatige intelligentie. Vandaag zoek ik nieuwe uitdagingen op het snijvlak van media en technologie – daar waar de ervaring van een reporter en praktische kennis van AI samen meer opleveren dan elk afzonderlijk.

#### Verwante teksten

- [Over mij](https://jakubcwirlej.com/nl/articles/about-me.md)
- [Mijn manier van werken](https://jakubcwirlej.com/nl/articles/approach.md)
- [AI in de journalistiek](https://jakubcwirlej.com/nl/articles/ai-journalism.md)

### Over mij {#about-me}

id: `about-me` · taal van de tekst: NL · 807 woorden · Markdown: https://jakubcwirlej.com/nl/articles/about-me.md

**Samenvatting (redactioneel):** Een persoonlijk portret waarin de auteur zichzelf beschrijft als iemand die vaste standpunten vermijdt, wat hij voor een journalist of onderzoeker een troef vindt. Hij schetst zijn weg van het atelier van zijn grootvader en een jeugdplan om docent filosofie te worden naar twintig jaar als verslaggever voor de Poolse publieke omroep, en zegt dat de journalistiek hem hielp zijn angst om beoordeeld te worden te overwinnen. Hij schrijft ook over zijn gezin, de boeken en muziek waarvan hij houdt en zijn recente verhuizing naar België, vlak bij Gent.

**Kernpunten (redactioneel):**

- Hij woonde het grootste deel van zijn leven in Polen; zijn loopbaan begon op een redactie, als journalist en videomonteur.
- Hij heeft zijn studie niet afgemaakt en zegt dat zijn eerste app, OrsonAI, een flop bleek; hij hecht aan het vermogen om van koers te veranderen.
- Creativiteit betekent voor hem iets helemaal van nul opbouwen.
- Als zijn grootste tekortkoming noemt hij een gebrek aan emotionele intelligentie.
- Hij noemt ‘De boeken van Jakob’ van Olga Tokarczuk, Marcel Proust, Arvo Pärt, L’Arpeggiata en Bach onder leiding van Philippe Herreweghe.

**Volledige tekst (de woorden van de auteur):**

Over mezelf praten is me nooit makkelijk afgegaan. Vooral omdat ik het gevoel heb dat ik nog altijd weinig over mezelf weet. Ik ben ruim veertig en heb over de meeste zaken die mensen ‘bepalend’ vinden nog steeds geen uitgesproken mening. Ik probeer altijd veel gezichtspunten toe te laten en me aan geen enkel ervan langer te hechten dan het de weerstand van de werkelijkheid kan doorstaan. Veel mensen zien zo'n gebrek aan harde, onwrikbare overtuigingen misschien als een tekortkoming; voor een journalist of researcher is het volgens mij de grootste troef.

Het grootste deel van mijn leven woonde ik in Polen. Het visuele vertellen begon voor mij in het atelier van mijn grootvader – een plek die me haast heilig was, en waar ik begreep hoeveel slagkracht één enkel beeld kan hebben. Mijn beroepsloopbaan begon echter in een newsroom, als journalist en videomonteur. Door die ervaring leerde ik elk aspect van het televisievak door en door kennen, en ze vormde me tot een veelzijdige maker. Twintig jaar lang werkte ik als reportagemaker voor Telewizja Polska. Dat is best ironisch, want als kind was ik van weinig dingen zo zeker als hiervan: ik zou geen journalist worden – zoals mijn vader. Ik wilde filosofie studeren en universiteitsdocent worden. Het leven en de noodzaak om aan de kost te komen gooiden die plannen om, maar juist mijn aanpassingsvermogen bleek mijn belangrijkste eigenschap. Ik belandde in de media en voelde me er best goed thuis.

De journalistiek heeft bepaald wie ik ben. Ze leerde me discipline en doorzettingsvermogen, maar werkte vooral als een jarenlange therapie: ze genas me van jeugdtrauma's. Jarenlang durfde ik geen woord te zeggen tegen mensen die ik slimmer vond dan mezelf; de angst om beoordeeld te worden verlamde me. Achteraf bekeken was dat soms ronduit komisch, maar het werk met camera en microfoon dwong me die angst onder ogen te zien. Ik waardeer het mediawerk nog altijd precies daarom: je beleeft de wereld er telkens opnieuw door. Het biedt de kans om jezelf en je plaats in de meest uiteenlopende contexten steeds opnieuw te definiëren. Het is een avontuur zonder einde.

Voor een buitenstaander kom ik misschien wispelturig over, misschien zelfs als iemand die niet in staat is resultaten af te leveren. Ik heb tenslotte mijn studie niet afgemaakt, en ook mijn eerste app – OrsonAI – bleek een flop. Toch ben ik er diep van overtuigd dat je in het leven voortdurend mogelijkheden moet verkennen en een pivot moet kunnen maken wanneer de omstandigheden daarom vragen. Anderzijds kan ik me met hart en ziel inzetten voor projecten waarin ik zin zie – dat ik twintig jaar in één uiterst veeleisende sector heb doorgebracht, bewijst wellicht het best dat ik serieus neem wat ik doe.

Ik hou van opdrachten die creativiteit vragen. Ik weet dat het afgezaagd klinkt, en creativiteit kan vandaag letterlijk alles betekenen. Daarom heeft dat woord voor mij een heel concrete inhoud: in het diepe springen en jezelf in een situatie brengen waarin je iets helemaal van nul moet opbouwen. Precies daarom heb ik het werk als reportagemaker zo gewaardeerd. Ook al kun je de indruk krijgen dat in reportages steeds dezelfde verhalen en menselijke motieven terugkeren, een goede documentairemaker slaagt erin er telkens op een volledig nieuwe, intrigerende manier over te vertellen.

Als ik mijn grootste zwakte moet noemen, dan is dat zonder twijfel een gebrek aan emotionele intelligentie. Ik kan een ruimte totaal niet ‘lezen’. Als iemand iets niet expliciet tegen me zegt, ontgaat het me hoogstwaarschijnlijk. Het klinkt misschien grappig, maar door die paradox lijk ik in dat opzicht soms verbazend veel op kunstmatige intelligentie.

En privé? Mijn gezin geeft me de grootste vreugde. Zien hoe mijn kinderen opgroeien is een fascinerende ervaring. Ik neem het mezelf wel kwalijk dat ik tot nu toe te weinig tijd aan hen heb besteed – dat is een van de belangrijkste dingen die ik nu in mijn leven probeer te veranderen.

Ik lees graag boeken die me een gevoel van continuïteit geven. Boeken die laten zien dat tijdperken en decors wel veranderen, maar dat we in wezen precies dezelfde vreugde en hetzelfde verdriet delen met de mensen die honderden jaren voor ons leefden. Vandaar mijn fascinatie voor ‘De boeken van Jakob’ van Olga Tokarczuk en het werk van Marcel Proust. Mijn grote droom is trouwens om Frans zo goed te leren dat ik eindelijk ‘Op zoek naar de verloren tijd’ in het origineel kan lezen.

Ik hou van klassieke muziek – Arvo Pärt, het ensemble L'Arpeggiata, maar vooral de cantates en missen van Bach in de uitvoering van Philippe Herreweghe. Sinds kort woon ik in België, niet ver van Gent, dus ik hoop vurig dat ik binnenkort de kans krijg om zijn interpretaties live te horen.

En verder? Ik luister gewoon graag naar de regen en kijk hoe het gras buigt in de wind. Meer heb ik niet nodig.

### Mijn manier van werken {#approach}

id: `approach` · taal van de tekst: NL · 849 woorden · Markdown: https://jakubcwirlej.com/nl/articles/approach.md

**Samenvatting (redactioneel):** Voor de auteur is journalistiek in de eerste plaats een manier om de wereld te leren kennen en voortdurend bij te leren, en ook een vorm van dienstbaarheid: ongeacht zijn stemming of het risico is het zijn taak het verhaal af te leveren, omdat mensen het recht hebben om te weten. Hij betoogt dat televisie nooit objectief is, omdat subjectiviteit al begint bij de keuze van de shots en doorloopt in de montage, en dat de echte ethische plicht is de tijd van de kijker niet te verspillen. Hij legt uit hoe zorgvuldig hij zich op locatie voorbereidt en waarom hij nooit naar prijzen heeft gestreefd.

**Kernpunten (redactioneel):**

- Hij volgt afwisselend de BBC en Radio France en waardeert hun ethische principes, maar vindt veel claims van absolute objectiviteit cynisch.
- Hij stelt voor dat redacties openlijk verklaren welk wereldbeeld zij als dominant beschouwen.
- De voorbereiding van een verhaal omvat een bezoek vooraf aan de locatie om de ruimte en het licht te controleren.
- Hij stuurde zijn reportages niet naar festivals: hij voelde zich niet gerechtigd de ‘auteur’ van andermans verhalen te zijn en koos ervoor een betrouwbare teamspeler te zijn.

**Volledige tekst (de woorden van de auteur):**

Journalistiek, en vooral televisiewerk, is voor mij in de eerste plaats een manier om de wereld te leren kennen, een toegangspas tot plekken en mensen die ik anders nooit zou hebben bereikt. Nieuwsgierigheid trok me naar de journalistiek, en die houdt me er nog altijd. Ook na 20 jaar leer ik nog steeds bij.

Dat leren is trouwens geen keuze, maar een voorwaarde van dit werk. Een journalist staat telkens weer voor een onderwerp waar hij gisteren nog weinig van wist, en in de meeste gevallen kom je zonder grondig onderzoek nergens. Wetten veranderen, omstandigheden veranderen, de mensen om wie het gaat veranderen. Daarom maak je in dit vak nooit twee keer hetzelfde onderwerp – ook niet als de problemen bedrieglijk op elkaar lijken. Twee gezinnen die door dezelfde tragedie zijn getroffen, zijn nog altijd twee verschillende verhalen, en wat drie jaar geleden waar was, is vandaag vaak niet meer dan een vertrekpunt.

Voor veel van mijn vrienden uit het vak is journalistiek een vorm van dienstbaarheid. Ook mij ligt die houding na aan het hart – en dat terwijl ze de geformaliseerde structuren van het leger of de politie mist, en ik zelf het grootste deel van mijn loopbaan hooguit op stukloon kon rekenen. Van privileges, een beschermende paraplu van de staat of institutionele zekerheid was niet eens sprake. Toch had ik altijd het gevoel dat wij een vergelijkbare plicht te dragen hadden. Of ik me die dag nu goed of minder goed voel, of het onderwerp me persoonlijk tegenstaat of zelfs fysiek gevaar oplevert – mijn taak is simpelweg dat onderwerp ‘af te leveren’. Mensen hebben het recht om te weten, en het is mijn rol hun die kennis te bezorgen.

Precies daarom erger ik me zo aan de hedendaagse pretentie van absolute objectiviteit. Niet dat ik de klassieke normen niet respecteer – ik luister elke dag afwisselend naar de BBC en Radio France, en ik heb diepe waardering voor hun ethische principes. Maar laten we eerlijk zijn: bij werkelijk elke zender begint en eindigt de grens tussen objectiviteit en subjectiviteit precies daar waar de redactionele lijn (editorial line) haar trekt. In veel andere gevallen is die pretentie ronduit cynisch: men heeft de mond vol van het journalistieke ethos, alleen maar om de eigen opvattingen binnen te smokkelen. Het zou veel eerlijker zijn als elke redactie officieel verklaarde welk wereldbeeld ze als dominant beschouwt. De waarheid is – en tot dat diepere inzicht kwam ik na jaren werken op de set – dat televisie per definitie nooit objectief is. Subjectiviteit begint al bij de technologie en de kadrering. Alleen al of de cameraman uit de hand filmt (wat een shot een nerveuze dynamiek geeft) of de camera op een statief zet, is een bewuste keuze die meteen het verhaal en de emotionele beleving beïnvloedt. En dan komen daar nog de montage, de selectie van informatie en het geluid bij. Het televisiebeeld is altijd iemands interpretatie van de werkelijkheid.

Voor mij komt echte journalistieke ethiek neer op een ongeschreven afspraak met de kijker: mijn belangrijkste plicht is zijn tijd niet te verspillen. Daarvoor moet je verhalen vertellen op een manier die boeit en intrigeert, ook al trekken al decennialang dezelfde universele motieven van menselijk drama en menselijke vreugde over het scherm. In de meedogenloze omgeving van de ombudsjournalistiek, onder enorme tijdsdruk, leerde ik een evenwicht te vinden tussen een eigen visie en keihard pragmatisme. Het gaat daarbij niet alleen om de camera vasthouden of lastige vragen stellen. Het gaat erom een stem te geven aan wie er geen heeft, en de beeldtaal zo in te zetten dat ze een band smeedt, de juiste snaar raakt en weerklank vindt bij de kijker.

Dat vraagt dan weer om ambachtelijke bescheidenheid en een rigoureuze voorbereiding. Een onderwerp voorbereiden betekent voor mij niet alleen een voorgesprek met de hoofdpersonen. Het betekent ook ruim op tijd ter plaatse zijn om de ruimte in kaart te brengen, in te schatten hoe het licht tijdens de opnames zal vallen en van welke kant de zon zal komen. Dankzij dat puur analytische, haast ingenieursmatige deel van het werk kan ik de opnames met een koel hoofd plannen, zodat ik me later, op het beslissende moment, alleen nog op de mens en zijn verhaal hoef te concentreren.

Ik ben nooit op vakprijzen uit geweest en heb mijn reportages nooit naar festivals gestuurd. Daar waren twee redenen voor. Ten eerste: wanneer ik vertelde over andermans leven, vaak over iemands persoonlijke tragedies, kon ik me nooit de ‘auteur’ van die verhalen voelen – ik vond simpelweg niet dat ik daar het morele recht toe had. Ten tweede heb ik jarenlang bewust de reputatie opgebouwd van iemand die geen grillige kunstenaar en individualist is, maar een betrouwbare teamspeler. Artistieke pretenties heb ik bewust opgegeven, zodat het werk vlot kon verlopen. Ik maakte reportages voor de eindredacteuren – efficiënt, op tijd, zonder overbodige discussies. Ik zorgde ervoor dat de raderen van die machine zonder haperen bleven draaien. Ik ben er diep van overtuigd dat je, om belangrijke verhalen te vertellen en echt invloed uit te oefenen op de werkelijkheid, geen monument hoeft op te richten voor wie ze maakt.

### AI in de journalistiek {#ai-journalism}

id: `ai-journalism` · taal van de tekst: NL · 1555 woorden · Markdown: https://jakubcwirlej.com/nl/articles/ai-journalism.md

**Samenvatting (redactioneel):** De auteur, die sinds de lancering van ChatGPT bijna dagelijks AI gebruikt, erkent de risico's ervan, vooral hallucinaties, maar betoogt dat pragmatisch gebruik van de technologie het vak versterkt: hij praat met een chatbot op de terugweg van opnames, automatiseert transcriptie en gebruikt OSINT-tools, al kan nog geen enkel model van ruwe interviews een televisie-‘stramien’ maken. Hij vindt het weinig zinvol teksten op hun klank te beoordelen, omdat AI-detectoren zich in beide richtingen vergissen, en merkt op dat de Europese AI Act vraagt wie voor een tekst verantwoordelijk is, maar de lezer geen middel geeft om na te gaan wie hem schreef. Hij verwacht dat journalisten die blijven onderzoeken en itereren het goed zullen doen, en dat vooral wie alleen schema's herhaalt zijn baan verliest.

**Kernpunten (redactioneel):**

- In een onderzoek van de EBU en de BBC uit oktober 2025 bevatte een op de vijf antwoorden van AI-assistenten op vragen over de actualiteit ernstige inhoudelijke fouten, zoals verzonnen of verouderde informatie.
- Zijn eerste app, OrsonAI, ontstond uit de behoefte om interviews in realtime te transcriberen en meteen in een editor te importeren.
- AI-detectoren vergissen zich in beide richtingen: ZeroGPT schreef een fragment van de Amerikaanse Onafhankelijkheidsverklaring voor bijna 98 procent toe aan een machine, terwijl twee detectoren een tekst die volgens Wired door AI verzonnen was, hoogstwaarschijnlijk door een mens geschreven achtten.
- Zijn idee van een op de blockchain verankerd certificaat van menselijk auteurschap stuitte bij kennissen uit de sector op een gebrek aan interesse.
- Vanaf 2 augustus 2026 verplicht de Europese AI Act om door AI gegenereerde teksten over zaken van algemeen belang te markeren, tenzij ze redactioneel zijn gecontroleerd en iemand er de verantwoordelijkheid voor draagt.

**Volledige tekst (de woorden van de auteur):**

Ik rijd terug van een opname. Handen aan het stuur, verse gedachten en indrukken van de set tollen door mijn hoofd, dus zet ik een chatbot aan en praat ik gewoon met hem. Ik vertel wat ik gezien heb, probeer hardop de eerste zinnen van de reportage uit, som op wat ik nog moet checken. De bot schrijft alles op, ordent het in notities en geeft gaandeweg commentaar op mijn ideeën. Soms levert zo'n gesprek een eerste kladversie van de tekst op, soms alleen een lijstje observaties dat me helpt bij het verdere werk aan de reportage. Vroeger, tegen de tijd dat ik op de redactie aankwam, waren veel vluchtige maar heel goede ideeën me gewoon ontglipt. En als ik een paar dagen later op een onderwerp moest terugkomen, moest ik veel dingen opnieuw ontdekken.

Omdat ik sinds de lancering van ChatGPT bijna elke dag kunstmatige intelligentie gebruik, kan ik me moeilijk vinden in het debat over AI in de media, waarin bijna altijd auteursrecht, ethiek en bronbescherming op de voorgrond staan. En terecht, want modellen confabuleren nog altijd: in een onderzoek van de EBU en de BBC uit oktober 2025 bevatte een op de vijf antwoorden van AI-assistenten op vragen over de actualiteit ernstige inhoudelijke fouten, zoals verzonnen of verouderde informatie. Vanuit het oogpunt van journalistieke betrouwbaarheid zijn hallucinaties een nachtmerrie. Toch denk ik dat deze technologie, ondanks dat risico, het journalistieke vak in de eerste plaats zal versterken, als je ze pragmatisch inzet. Zelf grijp ik graag naar AI, om te beginnen om de saaiste, meest repetitieve processen te automatiseren. Uit die behoefte ontstond mijn eerste app, OrsonAI, die helpt bij het realtime transcriberen van interviews en ze in een handomdraai in een editor importeert.

De echte revolutie voltrekt zich echter op het gebied van research. Tools voor de analyse van open bronnen (OSINT), tot voor kort peperduur en voorbehouden aan de grootste inlichtingendiensten of marktreuzen, zijn vandaag radicaal gedemocratiseerd. Iedereen kan voor eigen gebruik een agent bouwen die in enkele seconden de kerngegevens uit lijvige documenten haalt en structureert. De uiteindelijke factcheck blijft immers altijd bij de mens liggen, maar alleen al dat je bliksemsnel ziet waar in een document een bepaald gegeven staat, maakt het werk van een onderzoeksjournalist vele malen sneller.

Uiteraard duikt al snel de verleiding op om nog een stap verder te gaan: als de machine kan lezen, laat ze dan zelf de tekst schrijven. Daar heb ik gemengde gevoelens over, want kunstmatige intelligentie kan me op dit moment simpelweg niet uit handen nemen wat bij het maken van een reportage het belangrijkst is. Geen enkel model kan een handvol ruwe interviews nemen en er een zinnig televisie-‘stramien’ van maken – een precieze structuur waarin de uitspraken van de hoofdpersonen op een natuurlijke manier afwisselen met het commentaar van de maker en intelligent aansluiten bij de gedraaide beelden. Een agent de juiste context geven zodat hij een script genereert dat in de buurt komt van wat ik verwacht, zou op dit moment werk vergen dat niet in verhouding staat tot het eindresultaat. Misschien is het een kwestie van tijd en van de volgende iteraties van de modellen, maar tot nu toe heb ik geen tool gevonden die dat niveau van complexiteit kan vatten. AI redt zich aardig met korte nieuwsberichten en persteksten – mits iemand ze achteraf controleert – maar in langere vormen mis ik bijna altijd een eigen stijl en vloeiendheid.

Anderzijds ben ik geen dogmatische tegenstander van AI-ondersteuning bij creatief werk. Schrijven is, laten we eerlijk zijn, deels een puur mechanische vaardigheid. Wat echt telt, is het idee, de originele blik en wat de auteur ons te vertellen heeft. Een goed, onconventioneel idee en origineel denken breken vroeg of laat door de laag van de vorm heen. Ik ken veel te veel journalisten die ons al jaren niets nieuws meer te vertellen hebben en wier teksten bedrieglijk veel lijken op kant-en-klare producten van een algoritme – er zit geen enkel levend idee in. Ze missen die specifieke vonk, de eigenzinnige intelligentie en de menselijke flits die de wiskunde van taalmodellen nog altijd niet kan vatten.

Wanneer ik een artikel lees, weet ik meestal al na de eerste paar zinnen of de inhoud bij me aanslaat. Of een mens of een machine het schreef, is voor mij eerlijk gezegd bijzaak naast de vraag: voegt deze tekst iets nieuws en waardevols toe aan mijn leven? Kan hij mijn kijk op een probleem veranderen? Overigens is het, anders dan vaak wordt gedacht, vandaag erg moeilijk om puur op basis van de syntaxis een menselijke tekst met zekerheid te onderscheiden van een machinetekst. Toen ik detectoren voor AI-teksten testte, ontdekte ik al snel dat perfect gestructureerde, logische en ritmische columns van bekende opiniemakers, geschreven in 2013, door die programma's soms als honderd procent machinewerk worden aangemerkt. Het werkt trouwens in beide richtingen. De detector ZeroGPT schreef een fragment van de Amerikaanse Onafhankelijkheidsverklaring voor bijna 98 procent toe aan een machine, en toen Wired een tekst controleerde die – zoals de redactie later zelf vaststelde – door AI verzonnen was, oordeelden twee detectoren dat hij hoogstwaarschijnlijk door een mens was geschreven. Teksten brandmerken alleen op grond van hoe ze klinken, lijkt me dan ook weinig zinvol.

Als lezer beoordeel ik de waarde van een tekst, niet de auteur, maar het vertrouwen van het publiek berust op de vraag wie voor een tekst verantwoordelijk is. Daarom begrijp ik ook de andere, puristische benadering: het uitgangspunt dat journalistiek om ethische redenen een machinevrije zone moet blijven, als een domein van bijzonder maatschappelijk vertrouwen. Alleen zou zo'n oplossing een stevig sociaal contract vereisen, en mechanismen die onbetwistbaar een certificaat van menselijk auteurschap garanderen. Zulke mechanismen bestaan nog altijd niet: de bestaande certificaten van menselijk auteurschap zijn vrijwillig en zijn in de media geen standaard geworden. Ik heb daar zelf veel over nagedacht toen ik een certificaat van menselijk auteurschap ontwierp dat op de blockchain verankerd is – een onveranderlijk bewijs van wie een tekst geschreven heeft. Maar toen ik dat idee aftoetste bij kennissen uit de sector, stuitte ik op een volledig gebrek aan interesse en op onbegrip voor de noodzaak ervan.

Uiteindelijk denk ik, hoewel journalistiek vandaag hoog op de lijstjes staat van beroepen die het meest door AI bedreigd worden, dat echte journalisten het in het tijdperk van kunstmatige intelligentie best goed zullen redden. Ten eerste omdat er vroeg of laat een moment van systemische ontnuchtering komt: de waarde van menselijke controle over informatie zal zo serieus genomen worden dat ze in passende wetgeving wordt vastgelegd. De eerste regels zijn er al, al gaan ze een andere kant op: vanaf 2 augustus 2026 verplicht de Europese AI Act om door AI gegenereerde teksten over zaken van algemeen belang als zodanig te markeren, tenzij ze redactioneel zijn gecontroleerd en iemand er de verantwoordelijkheid voor draagt. De wet vraagt dus wie verantwoordelijk is, maar geeft de lezer geen middel om na te gaan wie de tekst echt geschreven heeft.

Ten tweede zijn onze vaardigheden perfect schaalbaar in een technologische wereld. Het werk aan mijn eigen app en het trainen van een model maakten me één cruciaal ding duidelijk: creëren, zowel in de technologie als in de media, is volgens mij voor 90 procent een proces dat wij journalisten al lang onder de knie hebben. Het is een repetitieve cyclus van twee dingen: research en iteratie. Je verzamelt informatie. Je verifieert. Je synthetiseert. Je verbetert. En je begint opnieuw. Voor mensen die willen leren en de werkelijkheid om hen heen willen begrijpen, opent kunstmatige intelligentie grote mogelijkheden. Eén bekwame journalist, ondersteund door agentische modellen, kan vandaag doen waarvoor gisteren nog een hele redactie nodig was. Dat is een reële kans om de maatschappelijke controle op wat er in de wereld gebeurt te vergroten.

Wie verliest dan zijn baan? In de eerste plaats zij voor wie journalistiek al lang geen missie meer is, maar het herhalen van vaste schema's. Mensen die elk jaar over hetzelfde onderwerp een bijna identieke tekst schrijven. Ik zie geen enkele reden waarom een redactie hen nog in dienst zou nemen als een algoritme hetzelfde sneller en gratis doet. Ik maak mezelf daarbij niet wijs dat de markt altijd wie niets eigens maakt eruit zeeft. Soms zeeft ze de goedkoopsten eruit, of wie toevallig het dichtst bij de deur stond. Op de lange termijn zal de concurrentie van machines echter vooral wie weigert zich te ontwikkelen en niet wil leren van het bord vegen. Natuurlijk is moeilijk te voorspellen welke kant een technologie die zich zo snel ontwikkelt op gaat. Toch denk ik dat kunstmatige intelligentie ons beroep uiteindelijk, paradoxaal genoeg, zal versterken als ze op een ethische manier in de journalistiek wordt ingezet – met het natuurlijke en hoogste recht van mensen op betrouwbare informatie voor ogen. Ze zal een instrument worden dat de mens niet vervangt, maar zijn handelingsvermogen vergroot.

Als ik terugkom van een opname, praat ik met de bot en dicteer ik hem de eerste zinnen. Hij schrijft ze op, verbetert de komma's, stelt misschien een betere woordvolgorde voor. Maar ik was degene die bij de opname was, en ik ben nog altijd degene die beslist wat er in de reportage komt en wat de kijker op het scherm ziet. De tijd die ik bespaar op saaie, repetitieve zinnen, die AI me helpt te automatiseren, kan ik besteden aan de mensen over wie mijn reportages gaan.

### Hoe ik begon {#how-i-started}

id: `how-i-started` · taal van de tekst: NL · 1584 woorden · Markdown: https://jakubcwirlej.com/nl/articles/how-i-started.md

**Samenvatting (redactioneel):** De auteur vertelt hoe het bouwen van OrsonAI, een reeks AI-tools voor zijn eigen journalistieke werk, hem van vibecoding naar onderzoek naar hallucinaties van taalmodellen en naar het trainen van eigen modellen bracht. Hij beschrijft de koele ontvangst van de app in de branche, zijn onderzoek naar de activaties van SwiGLU-gates en het mislukken van zijn eerste model op een eigen architectuur. Vandaag traint hij EUGEN 160M, een klein model gespecialiseerd in code dat in een terminal op de site te proberen is.

**Kernpunten (redactioneel):**

- OrsonAI bood live transcriptie van interviews, een bewerkingsmodus om een chatbot te raadplegen over gekozen passages en certificaten van menselijk auteurschap op het openbare ledger van Hedera Hashgraph.
- De GSI-signalen die hij vond, beschrijft hij nu eerder als proxysignalen voor kennis dan als ‘epistemisch bewustzijn’ van een model; hij zag dat confabulatie grotendeels een proces in twee fasen is.
- De vooruitgang van EUGEN 160M berust op nauwgezette monitoring, gerichte trainingsdata, synthetische data met STaR en LEMA en voorbeelden van vertalingen van Python naar C++, Java en Rust.
- Met hulp van een AI-codeeragent bouwde hij een eigen Triton-kernel voor het trainen van een sparse model: in een model van ~300 miljoen parameters trainde de sparse variant 1,23× sneller dan de dense, en latere optimalisaties van de kernel verhoogden de doorvoer met nog eens 36%.
- Hij schrijft het mislukken van zijn eerste model toe aan een filosofisch probleem en verwijst naar Tarski's definitie van waarheid en de stellingen van Gödel.

**Volledige tekst (de woorden van de auteur):**

…Ik heb geen formele opleiding in programmeren of in het trainen van LLM’s.

Dat ik apps ben gaan bouwen en AI ben gaan trainen, komt door een volkomen vreemde samenloop van toevalligheden, al lijkt die achteraf bekeken toch behoorlijk logisch. En ik denk dat het iets belangrijks zegt over onze tijd. Ik had het niet gepland; ik had nooit gedacht dat ik ooit meer met technologie te maken zou hebben dan een gemiddelde iPhone-gebruiker. Jarenlang was de podcast Hard Fork mijn enige venster op de wereld van Big Tech. De groeten aan Casey en Kevin :)

Het begon allemaal met vibecoding en de app OrsonAI. Al spelend met kunstmatige intelligentie ging ik tools maken die me konden helpen bij mijn dagelijkse journalistieke werk. Interviews al tijdens de opname omzetten in tekst en ze in een editor importeren, of een bewerkingsmodus waarin je geselecteerde tekstfragmenten met de chatbot kon bespreken zonder tussen vensters te moeten wisselen en de hele context opnieuw te moeten plakken: dat waren toen echt toffe tools, die mijn werk flink versnelden.

Gaandeweg begon ik het te zien als een project, als iets waar ook anderen iets aan zouden kunnen hebben. Het idee was simpel: de hulpmiddelen waarmee ik zelf tijd bespaar, ombouwen tot een product voor mensen die tegen dezelfde problemen aanlopen. Ik heb veel tijd gestoken in het ontwikkelen van een interface en mechanismen die veilige AI voor redacties konden garanderen – AI die de journalist helpt, maar hem het werk niet uit handen neemt. Ik ontwierp zelfs een systeem dat aan teksten certificaten van menselijk auteurschap toekent en die publiceert op het openbare ledger van Hedera Hashgraph. Een onveranderlijk bewijs met juridische bewijskracht, dat laat zien hoe een tekst tot stand kwam en hoe groot het aandeel van de mens daarin was.

- [Hier vind je een beschrijving van de HDK-technologie](https://jakubcwirlej.com/nl/articles/hdk-tech.md)
- [Hier kun je de gratis HDK-bibliotheek downloaden](https://jakubcwirlej.com/files/hdk/hdk-audit-0.1.3.zip)
- [HDK op Hugging Face](https://huggingface.co/JakCwi/hdk-audit)

Toch wachtte me een flinke teleurstelling. Mensen uit de sector aan wie ik de app liet zien, reageerden meer dan koel. De vraag die aan het eind van elke presentatie terugkwam, maakte me pijnlijk duidelijk hoezeer ik me had vergist: ‘Waarom zou iemand voor jouw app betalen als we gratis ChatGPT hebben?’ Een certificaat van menselijk auteurschap, gegevensbescherming of zelfs een aanzienlijk efficiëntere werkwijze dan wat een gewone chatbot bood: het deed er allemaal niet toe. Ik hoorde dat van mensen die dagelijks het belang van betrouwbare journalistiek benadrukken.

Het werk aan de app en aan een agentisch AI-systeem dat betrouwbaar genoeg zou zijn om op nieuwsredacties te worden ingezet, duwde me echter in een volledig nieuwe richting. In een poging beter te begrijpen waar de hallucinaties van taalmodellen vandaan komen, begon ik wetenschappelijke papers op arXiv te lezen, en uiteindelijk ontwierp en voerde ik een reeks experimenten uit rond de activatie van SwiGLU-gates in enkele open taalmodellen. De conclusies van dat onderzoek beschreef ik in een paar papers die ik op ResearchGate heb gezet. Ook al lijken sommige stellingen uit die papers me nu megalomaan, en zou de tekst zelf waarschijnlijk een revisie en een wetenschappelijker vocabulaire kunnen gebruiken, ik verwijder ze niet – al was het maar uit wetenschappelijke integriteit.

Vandaag ben ik bescheidener; die bescheidenheid heb ik opgedaan op het oefenterrein van het trainen van taalmodellen, na veel mislukte experimenten en teleurstellingen. Als ik nu over de gevonden GSI-signalen schreef, zou ik eerder spreken van proxysignalen voor kennis dan van ‘epistemisch bewustzijn’ van het model. Anderzijds kon ik op basis van harde data vaststellen dat confabulatie grotendeels een tweestapsproces is, waarbij het model – zonder houvast in feiten – vrijwel altijd een samenhangende vorm verkiest boven de waarheid. Voor mij persoonlijk was dat het boeiendste moment van die experimenten: het ogenblik waarop mijn vroegere interesse voor filosofie en epistemologie een onverwachte, volledig meetbare weerspiegeling vond in de architectuur van transformers. Een andere kwestie is wel de dagelijkse bruikbaarheid van die signalen in productieomstandigheden. Om hun doeltreffendheid bij het opsporen van hallucinaties te vergelijken met andere gangbare methoden, zou zeker aanvullend onderzoek nodig zijn.

Die taak nam me volledig in beslag. Misschien past dat wel een beetje bij mijn karakter – ik stort me graag op bezigheden die een uitdaging vormen, maar me ook iets leren over de wereld om me heen en me helpen die beter te begrijpen. Trouwens, voor ik in de journalistiek belandde, studeerde ik filosofie, met een bijzondere interesse voor wetenschapsfilosofie en epistemologie.

- [Hier vind je een essay waarin ik een aantal van mijn gedachten samenvat](https://www.researchgate.net/publication/397730862)

Het trainen van mijn eigen model draaide uit op een totale ramp. Ik heb waarschijnlijk alle denkbare fouten gemaakt, en dat terwijl ik gewend ben grondig research te doen en een enorme hoeveelheid vakliteratuur had verslonden. De eerste resultaten leken veelbelovend, maar pas later begreep ik dat ze grotendeels te danken waren aan ruisregularisatie. Het voordeel van het model in de ablatietests woog niet op tegen de extra rekenlast (compute) die het berekenen van de Gini van de gate-activaties met zich meebracht. Daarbovenop kwamen nog puur technische uitdagingen bij de training. Hield ik mijn modificaties buiten de normalisatie, dan remden ze het effectieve leren af; paste ik wel normalisatie toe, dan werden ze afgevlakt en werd het model een standaardtransformer, maar dan duurder om te trainen. De details van de architectuur stel ik hier ter download beschikbaar – misschien vindt iemand er bruikbaar materiaal in om te leren van andermans fouten.

Een oplossing die volgens mij ondanks alles aandacht verdient, is de M2-gate. Dankzij een affien anker kan ze op basis van een sigmoïdefunctie blijven werken zonder het risico dat een luie optimizer, op zoek naar een makkelijke manier om de trainingsloss te verlagen, haar naar beneden trekt. In mijn model moest die gate, getraind op Gini-signalen van de activaties, ruis wegsnijden wanneer het model genereerde. Maar het signaal buiten de normalisatie houden leidde – zoals ik al zei – tot een model met een overdreven zekerheidsverdeling: logisch vaardiger, maar de facto slechter in het leren van feiten. Misschien kan deze oplossing in andere modellen van pas komen voor de gating van andere elementen, en het trainingsproces helpen.

Al mijn mislukkingen met het trainen van een model op basis van mijn eigen architectuur ben ik uiteindelijk gaan zien als kapitaal dat je niet mag verspillen. Vandaag train ik mijn eigen kleine model, EUGEN 160M, dat gespecialiseerd is in code. Als ik de benchmarkresultaten tot nu toe vergelijk, ben ik voorzichtig optimistisch en ga ik ervan uit dat het geen verloren tijd zal zijn. Ik koos ervoor een model te trainen dat zich specialiseert in backendtalen, omdat je bij dit soort architecturen de vooruitgang makkelijker kunt monitoren en het model zelf een handige tool voor automatisch aanvullen (autocomplete) kan zijn bij inferentie op een gewone CPU. Je kunt het model testen in een speciaal daarvoor ingerichte terminal op mijn site en het vergelijken met andere open oplossingen van vergelijkbare omvang.

- [Hier kun je het model Eugen 160M testen](https://jakubcwirlej.com/nl/ai-dev/#terminal)

De resultaten tot nu toe zijn vooral te danken aan het nauwgezet bijhouden van de vooruitgang en van de fouten die het model maakt tijdens het genereren. Daardoor kon ik telkens meteen ingrijpen: ik voegde trainingsdata toe die het model versterkten waar het zwaktes vertoonde. Ik paste ook geregeld de technieken STaR en LEMA toe, waarbij ik synthetische data maakte op basis van wat het model zelf had gegenereerd, en vertaaldata die het model de logica van code leren door het voorbeelden te tonen van vertalingen tussen Python en C++, Java en Rust. Al dat materiaal maakt momenteel ongeveer 0,35% van de volledige dataset uit, en dat aandeel zal geleidelijk stijgen naarmate de training vordert.

Het trainen van het model bezorgt me veel plezier en geeft me – net als vroeger de journalistiek – het gevoel dat ik iets belangrijks doe; iets waardoor ik de veranderingen in de wereld om me heen beter kan vatten. Ik kan zelf geen complexe C++-code van nul schrijven, dat klopt, maar ik probeer de logica van de processen te begrijpen. Zo boek ik kleine successen waarmee ik in mijn werk vooruitkom. Ja – met hulp van een AI-codeeragent heb ik een eigen Triton-kernel gebouwd waarmee je een sparse model kunt trainen, met een TPS-winst (Tokens Per Second) van 23% ten opzichte van een dense model; latere optimalisaties van de kernel leverden nog eens 36% op. Ik ben van plan die oplossing te gebruiken bij het trainen van een volgend, iets groter model.

- [De kernel kun je hier downloaden](https://jakubcwirlej.com/files/eugen-sparse.zip)
- [Kernel op Hugging Face](https://huggingface.co/JakCwi/eugen-sparse)

En om terug te komen op het model waarmee het allemaal begon... Vandaag zie ik dat mijn grootste fout niet mijn technische naïviteit was. Dat model kón gewoon niet werken zoals ik had verondersteld. Het probleem was niet technologisch, maar puur filosofisch. En als iemand die filosofie heeft gestudeerd, had ik dat meteen aan het begin moeten zien, met Tarski's waarheidsdefinitie en de stellingen van Gödel in het achterhoofd. Volgens beide kan geen enkel voldoende complex systeem zijn eigen consistentie volledig bewijzen, noch waarheid definiëren uitsluitend vanuit zichzelf. De poging om het model zijn eigen interne toestanden in realtime te laten analyseren, beoordelen en corrigeren, sloot het op in een structurele lus waaruit – zonder metaniveau en extern referentiepunt – simpelweg geen uitweg was.

Toen ik aan dit avontuur begon, wilde ik gewoon een tool maken om journalistieke interviews makkelijker uit te schrijven. Al snel bleek echter dat wie de wereld van kunstmatige intelligentie binnenstapt, een echte sprong maakt in het konijnenhol uit ‘Alice in Wonderland’ – hoe dieper je afdaalt, hoe complexer, gelaagder en fascinerender alles wordt. Mijn eerste app heeft op de mediamarkt dan misschien geen revolutie ontketend, maar die val door het konijnenhol heeft me op een punt gebracht waar ik met succes mijn eigen architectuur train. Ik heb een lange weg afgelegd: van passieve luisteraar van techpodcasts tot iemand die de parameters van modellen fysiek vormgeeft en begrijpt wat er vanbinnen gebeurt.

### Wat ik heb geleerd door mijn eigen model te trainen {#training-lessons}

id: `training-lessons` · taal van de tekst: NL · 2651 woorden · Markdown: https://jakubcwirlej.com/nl/articles/training-lessons.md

**Samenvatting (redactioneel):** Tien praktische lessen uit de ervaring van de auteur met het zelf trainen van taalmodellen. Ze gaan over te optimistische rekenschattingen, klein beginnen, voortdurende monitoring, geïsoleerde wijzigingen en ablatietests, de keuze van data, realistische verwachtingen, geduld tijdens plateaus en de behoefte aan meer dan één GPU. Hij besluit dat kleine, gespecialiseerde modellen van individuele makers nog steeds zinvol zijn.

**Kernpunten (redactioneel):**

- De werkelijke benutting van de hardware (MFU) ligt ver onder wat de specificaties suggereren; zijn eerste model, met 1.5B parameters, bleef ondergetraind.
- Normen volgen en de antwoorden dag na dag vergelijken brengt problemen aan het licht die de loss niet laat zien; hij stapte over van AdamW naar MuonH.
- Verander één ding tegelijk; hij moest zijn dataset maar liefst drie keer van nul opbouwen.
- Vaardigheden groeien vaak sprongsgewijs na lange plateaus, en monitoring van de top10 kan vooruitgang tonen die de top1 verbergt.
- Kleine, smalle modellen die lokaal of op een CPU draaien, kunnen voordeliger zijn dan de grootste modellen, en er zelf een trainen is de beste manier om te begrijpen hoe AI werkt.

**Volledige tekst (de woorden van de auteur):**

#### 1. Berekeningen op papier vallen altijd te optimistisch uit

Bij het trainen van een model denken we vanzelf aan het proces van machine learning – het werk dat krachtige Nvidia-clusters in datacenters voor ons doen, of, als we meer geluk hebben, ons eigen loeikrachtige werkstation. Bij het lezen van de specificaties vergeet je makkelijk dat de reële MFU (Model FLOPs Utilization) veel lager ligt dan het marketingmateriaal van de kaartfabrikant doet vermoeden. Afhankelijk van de architectuur en de details haal je met je hardware slechts een fractie van de rekenkracht uit het silicium. Wat heb je eraan dat de kaart in FP4 rekent, als dat bij het trainen van een basismodel vanaf nul niet stabiel werkt, of als zakken onder BF16 bij de breedte van jouw model geen enkel voordeel oplevert?

Het is geen makkelijk moment wanneer je beseft dat je het geplande model niet binnen de beoogde tijd kunt trainen, en zelfs niet in de buurt van de beoogde omvang. Zeker niet als je er weken over hebt gedaan om op het punt te komen waar je met trainen kunt beginnen, en dan ineens blijkt dat het hele plan onrealistisch was. Op papier klopte toch alles! De eerste reflex is zoeken naar optimalisatiemethoden – torch compile, autocast, flash attention, FLCE, heads en minibatches waarvan de grootte is afgestemd op wat CUDA het liefst heeft. Dat werkt allemaal, maar de fysica van silicium laat zich niet bedotten. Als je een klein model traint, werkt de geringe breedte ervan tegen je. Als je je de training van een groot model niet kunt veroorloven, kun je je ook niet veroorloven het maximum uit je GPU te halen. Het kan dagen duren voor je je kaart optimaal benut, en als je TPS (Tokens Per Second) tijdens de training uiteindelijk 30-40% lager uitvalt dan je oorspronkelijk had berekend, scheelt dat dagen of zelfs weken rekentijd.

#### 2. Begin altijd op de kleinst mogelijke schaal waarop je je ideeën kunt valideren

Mijn eerste model had 1.5B parameters en ik kon het amper tot drie keer Chinchilla trainen. Bij de bouw ervan maakte ik veel fouten, maar het werkte toch. Dat het zo weinig bruikbaar was, kwam vooral door ondertraining. Had ik met hetzelfde budget een tien keer kleiner model getraind, dan had ik kunnen uitpakken met een goed getraind en bruikbaar model. Ik had tijd gehad om te testen en had zeker veel fouten vermeden, waardoor ik een betere architectuur had kunnen bouwen. Grootte doet er natuurlijk toe, maar data, architectuur en rekenefficiëntie doen er nog meer toe. De kans dat je een goed model ontwerpt op basis van de literatuur, zonder tests en zonder vergissingen, is ongeveer zo groot als de kans op de jackpot in de lotto.

#### 3. Een model traint zichzelf niet

Een model trainen klinkt tof, maar het is een stuk saaier dan je zou denken. In werkelijkheid is het grotendeels een proces van voortdurend experimenten opzetten, metingen doen, de resultaten van het model analyseren en oplossingen zoeken voor problemen die onderweg opduiken. Constant, de klok rond, dag na dag. Als je geen voldoening kunt halen uit kleine ontdekkingen en kleine successen, kan het je al snel te saai worden. En toch is het juist de ijzeren consequentie in het meten die alles bepaalt. Zelfs met goed gekozen trainingsparameters kan na verloop van tijd blijken dat ons model nieuwe data nodig heeft of degradeert op een manier die op het eerste gezicht moeilijk te zien is. Dat merk je niet zonder goede monitoring en voortdurende tests, en hoe minder vaak je ze doet, hoe meer tijd je verliest als het model zich ongewenst begint te gedragen.

Neem een veelvoorkomend scenario. Na een paar dagen training merk je dat het model steeds kortere antwoorden geeft en daarbij steeds zelfverzekerder wordt. De loss en de held-outset zien er goed uit, maar er is iets mis met het model. Als je de normen voortdurend analyseert en de antwoorden van het model elke dag vergelijkt met die van gisteren, kun je snel zien dat de logits oplopen en doorhebben dat het model een steeds grotere waarschijnlijkheid toekent aan bepaalde tokens. Die arrogantie is een truc van de luie optimizer – AdamW heeft een manier gevonden om ons te bedriegen: in plaats van het model iets te leren, drukt hij de loss langs een andere weg. Als je dat na een paar dagen opmerkt, verlies je misschien enkele tientallen dollars; als je de training laat lopen in de hoop dat die Nvidia-kaart al het werk wel doet, kun je honderden of duizenden dollars kwijt zijn en is het model misschien niet meer te redden.

Zelf heb ik wekenlang toegekeken hoe Adam de normen van mijn modellen opblies en zo de effectieve learning rate (LR) verlaagde, en dat ondanks de toegepaste QK-norm en een weight decay van 0.1. De training vertraagde, wat me tot wanhoop dreef, want zoals we weten geldt hier de stelling van Pythagoras: een groeiende gewichtsvector is met een constante LR steeds moeilijker te roteren. Het probleem is goed beschreven in de literatuur, maar zolang je het niet zelf ziet, begrijp je niet waarom je beter een andere optimizer kunt gebruiken. AdamW heeft tenslotte al honderden modellen helpen trainen. Ik koos uiteindelijk voor MuonH, en dat was een van de betere beslissingen die ik heb genomen. Natuurlijk kun je veel van dat soort dingen halen uit de literatuur, uit handboeken of door de papers op arXiv te volgen, maar je weet nooit hoe het bij jou zal uitpakken. Veel oplossingen die in theorie goed gedocumenteerde voordelen zouden moeten opleveren, werkten bij mij niet. Je komt er pas achter als je het zelf uitprobeert, en daarvoor moet je de vinger aan de pols houden en de vooruitgang op de voet volgen.

#### 4. Voer altijd maar één wijziging tegelijk door en doe ablatietests

De afgelopen maanden heb ik honderden kleine modellen getest – zowel klassieke transformers als mijn eigen ideeën... en vandaag weet ik dat ik te weinig heb getest. Omdat ik te snel vooruit wilde, verloor ik onnodig tijd. Aantal lagen, FFN-ratio, d_model, weight tying, grootte van de heads, aantal KV-heads, batch, optimizer, recurrentie, ijlheid (sparsity), trainingsdata – er zijn tientallen factoren die het gedrag van een model beïnvloeden, en de mogelijke combinaties leveren duizenden mogelijke architecturen op. En hoewel in grote lijnen alles werkt zoals je zou verwachten na het lezen van je eerste handboek over AI-engineering, weet je niet waar je staat zolang je je eigen architectuur niet zelf hebt getest. Intussen leiden kleine wijzigingen vaak tot grote verschillen in rekenefficiëntie en benchmarks, en dat bij dezelfde dataset en batchgrootte. Als je wijzigingen niet geïsoleerd doorvoert, raak je makkelijk de draad kwijt. Ik heb die fout zelf vaak gemaakt. Niet dat de aanpassingen slecht waren. Al waren ze dat vaak wel. Het echte probleem was dat ik, als ik dan echt een stap vooruit zette, niet kon zeggen aan welke wijziging ik dat te danken had.

#### 5. Begin bij de data

Hugging Face biedt een onvoorstelbare hoeveelheid trainingsdata, zeker gemeten aan de behoeften van een klein model. Je zou denken dat de zaak daarmee geregeld is: die data liggen binnen handbereik, in hoeveelheden die de behoeften van welk zolderkamerproject ook ruim overstijgen. Maar de selectie van data is veel belangrijker dan het aanvankelijk lijkt. En het feit dat ze al in kant-en-klare datasets zijn gebundeld, maakt het helemaal niet makkelijker. Dan is er nog de keuze van de juiste tokenizer, van de talen die je het model wilt leren, of van de verhoudingen. Bijvoorbeeld: hoeveel procent van de data uit code moet bestaan, hoeveel uit wiskunde en hoeveel uit natuurlijke taal. Vervolgens: in welke domeinen ons model zich moet specialiseren. Hoe dieper je het bos in gaat, hoe meer mogelijkheden. Zelf moest ik mijn dataset maar liefst drie keer van nul opbouwen. Ik had ook een paar kleinere missers, zoals een lek van het instruct-template dat ik bij het voorbereiden van de data niet had opgemerkt. Elke keer dwong zo'n vergissing me de training uren of zelfs dagen terug te draaien.

#### 6. Verwacht niet te veel

Als je ziet hoe grote en kleinere labs telkens weer de grenzen verleggen van wat AI kan, krijg je makkelijk de indruk dat het trainen van een bruikbaar model eigenlijk een eenvoudige zaak is. Er zijn echter redenen waarom het verleggen van die grenzen miljarden dollars kost. Dat jouw model met een menselijke stem begint te praten of goede resultaten haalt op populaire benchmarks, zegt niets over zijn uiteindelijke kwaliteit of bruikbaarheid. Modellen leren aan het begin, in de eerste dagen van de training, heel snel, maar de strijd om elk volgend procentje in de resultaten vraagt vindingrijkheid, aandacht en doorzettingsvermogen. Zeker als je dagenlang ziet hoe het model op een plateau blijft hangen of zelfs achteruitgaat. Bovendien zeggen populaire benchmarks weinig over de werkelijke mogelijkheden van een model. Je model kan goed zijn in Python en uitstekend scoren op HumanEval en MBPP, maar als het geen kennis heeft van de nieuwste bibliotheken, zal zijn bruikbaarheid in de echte wereld matig zijn.

#### 7. Wapen je met geduld

Veel vaardigheden van modellen groeien sprongsgewijs. Het goed beschreven fenomeen grokking wordt vaak voorafgegaan door een langdurig plateau dat dagen kan aanhouden. Wanneer je ziet dat het model geen enkele vooruitgang boekt, terwijl je voor elk uur training dollars moet betalen voor gehuurde rekenkracht of op zijn minst voor de stroom, ga je al snel twijfelen. Je denkt: ‘Het model heeft zijn capacity bereikt, meer leert het niet’, of ‘De grote labs die tot 1000x Chinchilla trainen, gebruiken vast een paar trucs.’ Maar vaardigheden groeien vaak sprongsgewijs. Het model hoeft maar te leren een of andere functie correct af te sluiten, en ineens springt het aantal geslaagde opgaven in MBPP van één naar meer dan tien. Vaak boekt het model ook echte vooruitgang, maar als je om te besparen alleen de top1 van de antwoorden monitort in plaats van de top10, merk je dat misschien lange tijd helemaal niet. Het model moet leren meer zekerheid toe te kennen, en dat kost tijd.

#### 8. Eén kaart is niet genoeg

Je zou denken dat alleen je budget je nog beperkt als je over een H100 of een RTX PRO 6000 (96 GB) beschikt. Het probleem is dat training voortdurende tests en metingen vergt, die je helpen inschatten in welk stadium je zit. Een extra GPU kan ook nodig zijn om extra trainingsdata te genereren. Zelf boekte ik aanzienlijke vooruitgang door mijn model te trainen met de STaR-methode, waarbij mijn eigen model een grote hoeveelheid opgaven genereert en de correcte daarvan aan de dataset worden toegevoegd, en met een dataset met voorbeelden van vertalingen tussen programmeertalen

Training op een krachtige kaart onderbreken zodat het model antwoorden kan genereren is erg duur en gewoonweg niet rendabel, en ernaast genereren – ook al laat het VRAM dat toe – kan een ernstig risico vormen. Het laatste wat je wilt, is na drie dagen, als de resultaten van het model achteruitgaan, ontdekken dat er tijdens het genereren naast de training op de kaart bijvoorbeeld een kortstondige ‘uithongering’ van de dataloader is opgetreden, waardoor de loss stilletjes niet meer daalde. Zulke dingen zijn in een later stadium van de training vaak bijzonder moeilijk op te sporen, zelfs als je monitoring hebt die je waarschuwt voor pieken in de normen.

#### 9. Begin met iets eenvoudigs

Aan mijn eerste model begon ik vanuit de intuïtie dat je bij het trainen van een LLM de eigen activaties van het model kunt benutten, en dat het volgen ervan tijdens het leren zou moeten helpen om een slimmer en waarheidsgetrouwer model te bouwen. Vandaag kan ik me alleen maar over mezelf verbazen: wat was die aanpak naïef. Niet omdat ik nu denk dat het onmogelijk is, maar omdat ik ben gaan experimenteren met iets wat me boven het hoofd groeide, zonder enig idee van hoe het trainen van een LLM in zijn werk gaat. Ik moest me een enorme hoeveelheid kennis eigen maken en tegelijk zowel oplossingen uit de architectuur van klassieke transformers testen als mijn eigen ideeën, die – zo bleek na verloop van tijd – grotendeels onuitvoerbaar waren.

Daarbij stuitte ik op een hele reeks problemen – het activatiesignaal van de SwiGLU-gates verloor na normalisatie zijn betekenis, en zonder normalisatie gebruikte AdamW mijn modificaties om de normen van het model op te blazen. Pas na verloop van tijd begreep ik dat veel van de voordelen die ik in mijn eerste model had gevonden, voortkwamen uit een fenomeen dat leek op ruisregularisatie. Bovendien was het berekenen van de Gini uit de activaties van de SwiGLU-gates zelf rekenintensief: het voegde enkele procenten extra compute toe, die zich niet terugbetaalden in kwaliteit.

Momenteel train ik een klein model van 160M in een standaardarchitectuur, dat gespecialiseerd is in coderen. Dat was de beste beslissing die ik kon nemen, want zo gaf ik mezelf de kans iets te maken dat echt bruikbaar kan zijn. En de eerste resultaten van het model laten zien dat ik niet voor niets uit mijn fouten heb geleerd.

#### 10. Bouw geen model dat goed moet zijn in alles

Gezien de astronomische kosten en de haalbaarheid zelf heeft het vandaag, om puur economische redenen, totaal geen zin dat één persoon of een kleine organisatie een model voor algemeen gebruik bouwt. De concurrentie met de reuzen, of zelfs met kleinere labs die open modellen uitbrengen, is niet te winnen zonder enorme investeringen en ervaring. Maar dat betekent helemaal niet dat het bouwen van eigen modellen zinloos is.

Je kunt je honderden toepassingen voorstellen waarin kleine modellen, van de grond af getraind of bijgetraind op unieke data, een voorsprong zullen hebben op de reuzen – en die voorsprong hoeft niet per se in kennis te liggen. Het is al genoeg dat het model snel is en lokaal kan draaien in de browser, of op de processor van een willekeurig werkstation. Voor specifieke, smalle toepassingen kan het veel rendabeler zijn een micromodel van enkele honderden miljoenen parameters te gebruiken dan de krachtigste beschikbare modellen van OpenAI of Anthropic in te zetten. Het gaat niet alleen om de kosten. Al is het verschil kolossaal. Een model dat gespecialiseerd is in een smal domein, is niet alleen veel makkelijker te trainen, maar ook te controleren en af te stemmen op de behoeften van de gebruiker. Maar het allerbelangrijkste: het is een taak die binnen het bereik ligt van een gewoon mens die bereid is zo'n uitdaging aan te gaan.

De modellen van de grote labs worden getraind op duizenden zeer dure chips. Een voorbeeld: voor het trainen van een model van de klasse Llama 3 400B was een cluster van 16.000 H100-kaarten nodig. De kosten liepen in de tientallen miljoenen dollars. De training van de nieuwste GPT Astra heeft de lat waarschijnlijk nog veel hoger gelegd. Aangezien de hele sector op krediet groeit, en grootschalige implementatie van AI bij de huidige API-kosten en kwesties rond gegevensbeveiliging bedrijfseconomisch vaak moeilijk te verdedigen is, mag je verwachten dat kleine modellen op lange termijn een steeds grotere rol zullen spelen. Kleine modellen zullen ook steeds efficiënter worden. Het zou me niet verbazen als we in de toekomst voor de meeste taken genoeg hebben aan een model van zo'n 7B parameters. Het barsten van de ‘AI-bubbel’, waarover in de media steeds vaker wordt gesproken, kan dat proces alleen maar versnellen.

Daarom vind ik het bouwen van kleine modellen diep zinvol. Ten eerste is er geen betere manier om te begrijpen hoe AI werkt dan je eigen model te trainen. Ten tweede: hoewel in grote labs de ontwikkeling van AI steeds vaker in handen is van... AI zelf, mag je verwachten dat de mensheid, als ze veiligheid serieus neemt, controle en menselijk toezicht op het trainingsproces zal eisen. Daarvoor is begrip nodig van hoe dat proces in de praktijk verloopt. Natuurlijk worden we vandaag, zodra we LinkedIn openen, overspoeld met posts over kunstmatige intelligentie van de meest uiteenlopende specialisten die tutorials en opleidingen aanbieden. Maar hoeveel van hen hebben echt hun eigen model getraind?

### Trainingsdata {#training-data}

id: `training-data` · taal van de tekst: NL · 163 woorden · Markdown: https://jakubcwirlej.com/nl/articles/training-data.md

**Samenvatting (redactioneel):** De trainingsmix van EUGEN 160M per Hugging Face-repository: 14 rijen die 93,4% van de huidige tokenstroom dekken. Dolma 3 is het grootste deel (35,29%, inclusief Stack-Edu en Common Crawl per onderwerp), gevolgd door The Stack v3 (15,44%) en commitgeschiedenissen uit CommitPack en verwante datasets (10,46%). Eigen data – STaR-oplossingen die EUGEN genereerde en die met tests zijn geverifieerd, plus vertaalparen van code – vormen ongeveer 0,35% van de mix.

**Kernpunten (redactioneel):**

- Elke rij geeft de exacte Hugging Face-repository-id's; bronnen zonder bevestigde HF-herkomst zijn weggelaten.
- Code uit GitHub Code Clean is beperkt tot permissieve licenties (MIT, Apache-2.0, BSD, ISC, Unlicense, CC0, Artistic-2.0).
- Wiskunde komt onder meer uit OpenMathReasoning, OpenR1-Math-220k en FineMath.
- Het corpus telt ongeveer 904,5 miljard tokens, inclusief bedoelde herhalingen.

**Volledige tekst (de woorden van de auteur):**

| Dataset (Hugging Face) | Aandeel | Licentie / opmerkingen |
| --- | --- | --- |
| Dolma 3 (incl. Stack-Edu en Common Crawl per onderwerp): allenai/dolma3_mix-6T-1025-7B, allenai/dolma3_pool, allenai/dolma3_dolmino_mix-100B-1125 | 35,29% | ODC-By |
| The Stack v3: HuggingFaceCode/stack-v3-train | 15,44% | ODC-By (compilatie), met respect voor de BigCode-opt-out |
| bigcode/commitpack, bigcode/commitpackft, project-themis/git-commits-merged, CarperAI/github-diffs-deduped | 10,46% | repositories met permissieve licenties; CommitPackFT en github-diffs-deduped MIT, git-commits-merged Apache-2.0 |
| codeparrot/github-code-clean | 6,63% | alleen permissieve licenties: MIT, Apache-2.0, BSD-2/3-Clause, ISC, Unlicense, CC0-1.0, Artistic-2.0 |
| common-pile/arxiv_papers, common-pile/stackexchange_filtered, common-pile/data_provenance_initiative_filtered | 5,64% | open licenties (Common Pile) |
| nvidia/OpenMathReasoning, open-r1/OpenR1-Math-220k | 4,18% | CC BY 4.0 (OpenMathReasoning) |
| HuggingFaceTB/finemath (subsets 3+ en 4+) | 3,95% | ODC-By |
| allenai/peS2o | 3,32% | ODC-By |
| instructies en redeneren: nvidia/OpenMathInstruct-2, TinyGSM/TinyGSM, OpenCoder-LLM/opc-annealing-corpus, OpenCoder-LLM/opc-sft-stage2, AI-MO/NuminaMath-CoT, meta-math/MetaMathQA, microsoft/orca-math-word-problems-200k, ise-uiuc/Magicoder-OSS-Instruct-75K, nvidia/OpenCodeReasoning-2, PrimeIntellect/SYNTHETIC-1, open-r1/codeforces-cots, hkust-nlp/CodeIO-PyEdu-Reasoning, allenai/ai2_arc, allenai/qasc | 2,26% | volgens de licentie van elke dataset |
| boeken: allenai/dolma3_mix-6T-1025-7B, common-pile/project_gutenberg_filtered, common-pile/pre_1929_books_filtered, common-pile/library_of_congress | 1,84% | publiek domein / ODC-By |
| HuggingFaceFW/finewiki, hltcoe/megawika | 1,60% | volgens de licentie van elke dataset |
| open-thoughts/AgentTrove | 1,47% | alleen geslaagde trajecten |
| mandarjoshi/trivia_qa, microsoft/ms_marco, hotpotqa/hotpot_qa, rungalileo/ragbench | 1,00% | 30% zijn eigen voorbeelden „geen antwoord in de context”, gebouwd uit deze datasets |
| eigen data: STaR (oplossingen van EUGEN, geverifieerd met tests), leren van fouten, vertaalparen Python ↔ C++, Java, Go, Rust | 0,35% | eigen |

### Een paar gedachten over AI-veiligheid {#ai-safety}

id: `ai-safety` · taal van de tekst: NL · 1734 woorden · Markdown: https://jakubcwirlej.com/nl/articles/ai-safety.md

**Samenvatting (redactioneel):** Een essay over AI-veiligheid waarin de auteur een oppervlakkig publiek debat bekritiseert dat verdeeld is tussen technomaximalisten en doemprofeten. Hij betoogt dat het ergste waarschijnlijk al begonnen is, gezien autonome wapens, toenemende surveillance en de ideologie van het technomaximalisme, en dat de verantwoordelijkheid altijd bij mensen moet liggen, omdat machines geen eigen handelingsvermogen hebben. Hij stelt concrete regelgevende maatregelen voor en waarschuwt tegen de antropomorfisering van AI.

**Kernpunten (redactioneel):**

- Hij ziet drie mogelijkheden: dat we gedoemd zijn, dat we AI leren beheersen, of dat het einde al begonnen is; volgens hem kunnen alle drie tegelijk waar zijn.
- Hij stelt voor dat het trainen van modellen tot ongeveer 1B parameters voor iedereen toegestaan is, en dat modellen van rond 7B voorbehouden blijven aan geregistreerde organisaties die de interacties van hun agents bijhouden.
- Verdere voorstellen: Ombudspersonen van het Algemeen Belang, betaald door de staatstoezichthouder, binnen labs die grensmodellen bouwen, en een speciale technologiebelasting om de overgang naar een economie op basis van machines te financieren.
- Hij stelt voor trainingsdata te licentiëren via organisaties voor collectief beheer van auteursrechten, zoals ZAiKS.
- De slechtste toekomst die hij beschrijft, is niet die van moordrobots, maar een langzaam afglijden naar een technocratie van surveillance en menselijke eenzaamheid.

**Volledige tekst (de woorden van de auteur):**

Deze tekst is een van de moeilijkste waarmee ik me ooit heb moeten meten. Als journalist, en tegelijk als iemand die thuis in alle rust zijn eigen modellen traint, sta ik op twee tegenovergestelde polen. Enerzijds fascineert de pure engineering me, anderzijds ben ik me er ten volle van bewust dat de veiligheid van kunstmatige intelligentie waarschijnlijk de belangrijkste uitdaging is van de tijd waarin we leven.

Ik begin met wat me persoonlijk het meest pijn doet: de tragische vervlakking van het publieke debat over AI-veiligheid. Het is een debat vol tegenstrijdigheden en extreme emotionele lading. Al is dat moeilijk anders te verwachten wanneer er miljardenbelangen en het voortbestaan van de mens op het spel staan.

Aan de ene kant horen we dat AI een dodelijk gevaar is en dat de ontwikkeling ervan de mensheid met de ondergang bedreigt. Aan de andere kant dat die apocalyptische visioenen niets anders zijn dan een cynisch spel van de reuzen, die hun waardering willen opdrijven voor de uitgifte van hun aandelen, of kleinere bedrijven willen blokkeren en afremmen om hun monopolie en hun plaats aan de kop van het peloton te behouden. De gewone mens, die geen tijd heeft om dat allemaal te volgen en eenvoudige oplossingen verwacht, belandt makkelijk in het kamp van de technomaximalisten of van de doemprofeten. Elk van die visies is zo glad, zo vanzelfsprekend... en geen van beide vraagt verder ook maar iets van ons. Want als we machteloos staan tegenover krachten die ons te boven gaan, hoeven we toch niets te doen. In deze tijden van extreem maximalisme is dat een heel comfortabele positie.

Wat zou ik zelf antwoorden als mijn kind me vroeg of AI een bedreiging voor ons is? Als ik de vereenvoudigende reframing wil vermijden, zou ik moeten toegeven dat er drie mogelijkheden zijn: dat we inderdaad gedoemd zijn ten onder te gaan, dat het uiteindelijk niet zover komt (want – zoals Yann LeCun betoogt – we zullen deze technologie gewoon leren beheersen), of... dat de ondergang al begonnen is. De paradox is dat alle drie de scenario's tegelijk waar kunnen zijn.

Dat het ergste waarschijnlijk al begonnen is, volgt uit een feit dat zelden tot de mainstream doordringt: elke technologie, elke uitvinding moet op het juiste moment en in de juiste voedingsbodem terechtkomen om zich ten volle te kunnen ontplooien. Kernenergie – zo vaak als vergelijking aangehaald in dit debat – was tijdens de Koude Oorlog een dodelijke bedreiging, maar werd in vredestijd een bron van goedkope energie die bijdroeg aan een economische boom. Hetzelfde kun je zeggen over de meeste uitvindingen: van het bewerken van vuursteen, via dynamiet, tot kunstmatige intelligentie.

Onze huidige wereld is helaas een plek geworden waar het rampscenario haast ideale omstandigheden heeft om werkelijkheid te worden. Gewapende conflicten met autonome wapens, de toenemende surveillance van burgers door staten en bedrijven, regeringen die in hun communicatie met de samenleving klakkeloos bedrijfsnormen overnemen – dat alles vormt een kant-en-klare infrastructuur voor de zwartste visioenen.

Intussen duwt de ideologie van het technomaximalisme ons in de richting van die gevaren. Ze spot openlijk met zwakte, stelt economisch gewin en brute kracht boven sociaal kapitaal en veiligheid, en bouwt een wereld waarin een AI die van de ketting is losgeslagen uitstekend zal gedijen. En dan kan het rampscenario al onvermijdelijk zijn.

Dat is niets nieuws. Die discussie wordt in wezen al gevoerd sinds de Atheense agora, waar Plato twistte met Socrates, en de menselijke geschiedenis zit vol duistere momenten en onrecht. Wat vandaag in de Amerikaanse politiek gebeurt, en wat voor veel Europeanen naar fascisme riekt, is niets nieuws, zoals historicus Jon Meacham treffend aangeeft in zijn boek ‘The Soul of America’. De kracht van de democratie is dat de gerechtigheid – hoe traag ook – dankzij de instellingen uiteindelijk altijd zegeviert. Met AI kan het toch net zo gaan: het is onze technologie en we zullen ze leren beheersen, net als vliegtuigen, zoals LeCun ons in herinnering brengt.

Zelf sta ik, met mijn bescheiden ervaring in het trainen van AI, versteld van hoe fragiel deze technologie is. Kleine wijzigingen in de hyperparameters volstaan om een model in de handen van de engineer volledig uit elkaar te laten vallen. Hetzelfde geldt echter voor biologische virussen. Doorslaggevend is niet hun uitzonderlijke intelligentie of hun vermogen om ten koste van alles te overleven, maar hun vermogen tot replicatie. Dat vermogen heeft kunstmatige intelligentie – zo lijkt het – voorlopig nog niet, en misschien zal ze het nog lang niet hebben. Het probleem is dat de dreiging toeneemt, zoals de recente affaires rond autonome AI-agenten die uit labs zijn ontsnapt en hun gecoördineerde acties op het net laten zien. En toch horen we, ondanks dat alles, niets anders dan het steeds terugkerende verhaal van twee extremistische kampen – zonder concrete oplossingen, zonder conclusies.

Wat de huidige modellen onderscheidt van kwaadaardige code die bijvoorbeeld Hugging Face of Australische servers heeft aangevallen, is vooral handelingsvermogen (agency). En handelingsvermogen mag nooit het domein van een machine zijn. Wat ons mens maakt, is onze vrije wil. Geen enkele andere, kunstmatige intelligentie mag handelingsvermogen hebben dat op een andere manier gegarandeerd is dan via een mens die haar die wil leent. Uit dat eenvoudige principe zouden alle verantwoordelijkheid en alle regelgeving moeten voortvloeien, vertaald in concrete wetgevende oplossingen. Het recht om modellen onbeperkt te trainen en te gebruiken zou moeten afhangen van een risicobeoordeling en van de controlemogelijkheden van concrete entiteiten.

Niets belet dat het trainen van de kleinste modellen algemeen toegestaan is – bijvoorbeeld tot een omvang van 1B parameters. Maar middelgrote modellen, in de orde van 7B parameters, zouden volgens mij alleen getraind en gedownload mogen worden door geregistreerde organisaties die alle interacties van hun agenten nauwkeurig vastleggen (logs) en bereid zijn die bij problemen ter beschikking te stellen. Dat is geen futurisme; cryptografie maakt dat vandaag al mogelijk, tegen verwaarloosbare kosten. Elke agent die online actief is, zou een soort ‘identiteitsbewijs’ kunnen hebben, dat te herleiden is tot de organisatie die hem vertegenwoordigt.

En de grote bedrijven die grensmodellen (frontier models) bouwen? Die zouden bijvoorbeeld verplicht kunnen worden om Ombudspersonen van het Algemeen Belang in dienst te nemen. Dat zouden specialisten zijn die uitsluitend door een overheidstoezichthouder worden benoemd en betaald – medewerkers met toegang tot alle technologische geheimen binnen het lab, die verplicht zijn aan de staat te rapporteren wanneer ze zien dat hun bedrijf veiligheidsnormen schendt of extreem riskante stappen zet in de wedloop met de concurrentie.

Staten hebben ook de mogelijkheid en de morele plicht om een geoormerkte technologiebelasting in te voeren. Die middelen moeten worden ingezet om de transitie veilig te stellen: de overgang van een economie die draait op menselijke handenarbeid naar een economie die draait op machines. Zo'n fonds zou een sociaal vangnet bieden, drastische ongelijkheid wegwerken en miljoenen mensen behoeden voor volledige economische afhankelijkheid van de gunst van de rijkste kaste van technologische leenheren.

Hetzelfde systemische pragmatisme moeten we toepassen op de kwestie van het auteursrecht op het materiaal waarop modellen worden getraind. Vandaag zuigen de techreuzen alles op wat ze op het net kunnen vinden, in de hoop dat eventuele rechtszaken jaren zullen aanslepen. Toch ligt de oplossing op tafel, en ze steunt op instellingen die we al goed kennen – organisaties voor collectief beheer van auteursrechten, zoals het Poolse ZAiKS of zijn buitenlandse tegenhangers. Niets belet dat zij makers verenigen die bereid zijn hun teksten, beelden of muziek in licentie te geven aan bedrijven die AI trainen, in ruil voor een vastgelegde fractie van een procent van de inkomsten van Big Tech. Het is een regeling waarbij iedereen wint. Makers krijgen zeggenschap en een reële vergoeding terug, met het volle recht om hun werk van training uit te sluiten. AI-labs krijgen op hun beurt – doordat zulke organisaties internationaal samenwerken – met één handtekening onder een contract volledig legale toegang tot enorme, juridisch zuivere databases van over de hele wereld. In plaats van steriele ruzies te voeren, zouden we zo een krachtige, volledig nieuwe industrie van eerlijke datalicenties kunnen opbouwen.

Waar we het meest voor moeten oppassen, is de voortschrijdende antropomorfisering van kunstmatige intelligentie. Machines menselijke eigenschappen toedichten leidt tot een uiterst gevaarlijke situatie, waarin alle verantwoordelijkheid op het nieuwe, digitale wezen terechtkomt, terwijl de makers ervan en wie het gebruikt als het ware op voorhand absolutie krijgen: ‘Wij waren het niet, het was het model.’ Vandaag vraagt niemand of men in Silicon Valley werkelijk alle mogelijke maatregelen heeft genomen om een rampscenario te voorkomen – al weet iedereen dat dat niet is gebeurd. Helaas is het uitwerken van echte, saaie wetgevende oplossingen veel minder mediageniek dan bangmakerij met de apocalyps.

Het fatale scenario zal er intussen zeker niet uitzien als een scène uit een Hollywoodrampenfilm. Althans in het begin zal het eerder lijken op een langzaam wegglijden in het duister – het klassieke verhaal van de kikker die langzaam wordt gekookt. De eigenaars van intelligente machines en van het kapitaal zullen op straat onverschillig voorbijlopen aan structureel overbodige mensen. Mensen die werkelijk geen enkele mogelijkheid zullen hebben om hun situatie te veranderen, behalve fysieke opstand. En zelfs die opstand zal onmogelijk worden in een wereld waarin elke burger voortdurend wordt gevolgd door miljarden glazen, nooit slapende cameraogen en duizenden autonome machines.

De nieuwe technocratie zal na verloop van tijd een digitale gevangenis worden – zowel voor wie gecontroleerd wordt als voor wie naïef denkt dat hij nog aan de macht is. Wanneer ik aan het somberste toekomstbeeld denk, zie ik geen moordende robots. Ik denk juist aan de doordringende eenzaamheid van mensen in een wereld die volledig wordt bestuurd door een vreemde, kille en onverschillige intelligentie. Dat is de wereld die we vandaag al bouwen, en waarin de spreekwoordelijke ‘opstand der machines’ alle kansen heeft om uiteindelijk te ontstaan en werkelijkheid te worden.

Zelf denk ik voortdurend na over dit probleem. En ook al lijken sommige ideeën of visies om hieruit te komen vandaag te futuristisch, abstract en soms ronduit naïef, ik vind dat het de moeite loont – en zelfs noodzakelijk is – om die inspanning te leveren. Alleen al nadenken over oplossingen, uit je comfortzone stappen en proberen je alternatieven voor te stellen voor het pad dat de techreuzen vandaag voor ons uitstippelen, is onze belangrijkste verdedigingslinie. Het is een onlosmakelijk onderdeel van het bouwen aan een betere, veiligere toekomst. Als we dat opgeven en genoegen nemen met de rol van passieve, angstige consumenten, wordt het slechtst denkbare scenario werkelijkheid: dan geven we ons menselijk handelingsvermogen zonder slag of stoot uit handen. En dat kunnen we ons gewoon niet veroorloven.

### De HDK-technologie {#hdk-tech}

id: `hdk-tech` · taal van de tekst: NL · 795 woorden · Markdown: https://jakubcwirlej.com/nl/articles/hdk-tech.md

**Samenvatting (redactioneel):** De auteur beschrijft HDK, een gratis Python-bibliotheek (CC BY-NC 4.0; eerdere versies Apache 2.0) uit OrsonAI die manipulatie van vastgelegde gesprekken met taalmodellen aantoonbaar maakt. Ze hasht elke gebeurtenis met al haar voorouders, voegt een aan een geheim gekoppelde kanarieteller toe en verankert Merkle-roots op de Hedera Consensus Service.

**Kernpunten (redactioneel):**

- Wie iets wijzigt op welk niveau ook, van één woord in een vraag tot een heel document, verandert de hashes van alle afstammende gebeurtenissen.
- Standaard verankert HDK na elke 1.000 gebeurtenissen een Merkle-root op Hedera; één anker kost 0,0001 dollar, ofwel 0,0000001 dollar per interactie.
- Bij de metingen die in de paper worden beschreven, op standaard x86-cloudinfrastructuur, blijft de overhead onder een milliseconde per gebeurtenis.
- De tekst koppelt HDK aan de eisen voor registratie en transparantie uit artikel 12 en 13 van de Europese AI Act.
- Genoemde beperkingen: de kanarie detecteert geen passief kopiëren op infrastructuurniveau, en willekeurige controles alleen vangen geen enkele, chirurgische wijziging op.

**Volledige tekst (de woorden van de auteur):**

HDK (Hedera Detection Key) is een kleine, gratis Python-bibliotheek die ik uit OrsonAI heb losgemaakt als apart, open hulpmiddel. Vanaf versie 0.1.3 valt ze onder de CC BY-NC 4.0-licentie (eerdere versies, uitgebracht onder Apache 2.0, blijven daaronder). Te downloaden is een gratis bibliotheek (alfa 0.1.3) met optionele verankering in Hedera (installeren vanuit het gedownloade bestand: pip install ./hdk-audit-0.1.3.zip). Ze draaide een tijd in een demo-applicatie en verankerde de vastleggingen in Hedera; de applicatie ging niet in productie, dus HDK wordt vandaag niet in productie gebruikt. Ze zit tussen een applicatie en de API van een taalmodel en legt elke interactie zo vast dat latere manipulatie aantoonbaar wordt. Ze verandert de vragen en de antwoorden niet: ze voegt er een cryptografisch bewijs aan toe van wat er gevraagd werd, wat er terugkwam, wanneer en van welk model.

#### Het probleem

Bedrijven en redacties vertrouwen steeds vaker op teksten die door AI zijn gegenereerd, maar ze hebben geen verifieerbaar bewijs van wat een model echt heeft geproduceerd. Applicatielogs staan in databases die de beheerder controleert: ze kunnen worden gewijzigd of gewist, en niemand van buitenaf kan nagaan dat dat niet is gebeurd. Zelfs waar hashketens bestaan, wordt een wijziging pas ontdekt als iemand de gegevens met de hand vergelijkt – niets zorgt ervoor dat ongeoorloofde toegang zichzelf verraadt op het moment dat ze plaatsvindt.

#### Hiërarchische hashgenealogie

HDK berekent een SHA-256-hash van elke gebeurtenis samen met de hashes van al haar voorouders: project, document, gesprek, vraag en antwoord. De hash van een antwoord bevat dus het hele pad terug naar het project. Verander iets op welk niveau ook – één woord in een vraag, één document – en de hashes van alle afstammelingen veranderen mee. Voor elk project berekent HDK een Merkle-root: één hash die de toestand van het hele project op een bepaald moment vertegenwoordigt.

#### De kanarie

De tweede laag is een ‘kanarie’: een geheime waarde van 256 bits en een teller die bij elke leesactie oploopt. Hun hash (de commitment) wordt in elk record verweven en regelmatig vastgelegd. Leest iemand gegevens via de tussenlaag zonder de teller bij te werken, dan klopt de teller niet meer; werkt iemand de teller bij zonder het geheim te kennen, dan klopt de commitment niet meer. In beide gevallen mislukt de verificatie. Het idee vertaalt een principe uit mijn eerdere, conceptuele werk over het detecteren van inbreuken bij het insluiten van AI naar gewone infrastructuur.

#### Verankering op Hedera

Op gezette tijden – standaard na elke 1.000 nieuwe gebeurtenissen – publiceert HDK de Merkle-root op de Hedera Consensus Service, een openbaar register dat er een consensustijdstempel en een volgnummer aan toevoegt. Alleen hashes verlaten het systeem van de gebruiker; inhoud, identiteiten en vragen blijven privé (‘gegevens privé, bewijs openbaar’). Iedereen kan het record daarna onafhankelijk controleren, bijvoorbeeld op hashscan.io (de ankers van OrsonAI van februari tot mei 2026: topic 0.0.10278996 op het mainnet van Hedera). Omdat de voorouderketens van nieuwe gebeurtenissen tot in het bereik van het vorige anker reiken, bevestigt elk anker impliciet alle eerdere: hoe langer het systeem draait, hoe moeilijker het wordt om de geschiedenis ongemerkt te herschrijven.

#### Overhead en kosten

Bij de metingen die in de paper worden beschreven, op standaard x86-cloudinfrastructuur, voegt HDK minder dan een milliseconde per gebeurtenis toe. Eén anker kost 0,0001 dollar, dus bij het standaardinterval van 1.000 gebeurtenissen kost verankering 0,0000001 dollar per interactie – ongeveer 0,0001% van de prijs van een gewone modelaanroep (0,01–0,10 dollar). Elke gebeurtenis afzonderlijk verankeren, voor de hoogste beveiliging, kost 0,0001 dollar per gebeurtenis.

#### Waarom het ertoe doet: de AI Act

De Europese AI Act verplicht AI-systemen met een hoog risico om gegevens bij te houden (artikel 12) en transparant te zijn (artikel 13). HDK levert een audittrail die een derde partij kan verifiëren zonder enige privé-inhoud te zien. In OrsonAI was dit mechanisme de basis van het certificaat van menselijk auteurschap van een tekst.

#### Beperkingen

De garanties van HDK zijn computationeel – ze berusten op de sterkte van SHA-256 en op externe verankering – en niet absoluut. De kanarie werkt op applicatieniveau: ze detecteert toegang via de HDK-tussenlaag, maar niet het passief kopiëren van gegevens op het niveau van het besturingssysteem of de infrastructuur, want gekopieerde bits laten geen spoor na. Met een kopie kun je de geschiedenis echter niet vervalsen: wie een gebeurtenis uit het verleden wijzigt, breekt de genealogie, en de ankers op Hedera bewaren de oorspronkelijke toestand. Willekeurige integriteitscontroles vangen massale wijzigingen op, maar niet één enkele, chirurgische wijziging – daartegen beschermen de genealogie en de verankering. De beveiliging gaat ervan uit dat minstens één van drie lagen ongeschonden blijft: de gegevens aan de kant van de gebruiker, het verankerde record op Hedera of het geheime materiaal. Volgende stappen: formele verificatie van de eigenschappen van de hashketen (Coq/Lean), federatie van systemen op gedeelde HCS-topics en certificaten van herkomst van inhoud met selectieve openbaarmaking.

- [Lees de paper op ResearchGate](https://www.researchgate.net/publication/400762996)
- [Download de gratis HDK-bibliotheek](https://jakubcwirlej.com/files/hdk/hdk-audit-0.1.3.zip)
- [HDK op Hugging Face](https://huggingface.co/JakCwi/hdk-audit)

## Publicaties

De onafhankelijke onderzoeksartikelen van de auteur (preprints op ResearchGate, niet peer-reviewed) — hier als korte redactionele samenvattingen met hun status en bekende beperkingen; de volledige teksten (in het Engels) staan achter de links.

### Pre-Generative Epistemic Signals in Transformer Language Models (2026) {#tes1-pre-generative-epistemic-signals}

- **Status:** Voorlopige preprint. De hele TES-reeks wordt opnieuw geanalyseerd en zal worden vervangen door één herziene paper. Onafhankelijk, op ResearchGate, niet peer-reviewed.
- **Bewering:** SwiGLU-gate-activaties in de bovenste FFN-lagen, gemeten in één doorgang voordat er een token wordt gegenereerd, laten zien of een model de kennis heeft om te antwoorden: de Gate Sparseness Index (GSI, de Gini-coëfficiënt van die activaties) onderscheidde aanwezige van ontbrekende kennis in 8 modellen van 5 organisaties (Cohen's d 0,34–2,05).
- **Beperking:** Latere analyse door de auteur vond een sterke verstorende factor, de promptlengte: GSI wordt over alle prompttokens berekend. Na correctie voor lengte houdt het signaal stand voor Llama-3.1-8B (d≈1,5, AUROC≈0,85), maar verdwijnt het grotendeels voor de andere modellen. Preregistratie: de protocollen zijn vóór de dataverzameling opgesteld, maar niet extern geregistreerd.
- **Volledige tekst:** https://jakubcwirlej.com/publications/tes1-pre-generative-epistemic-signals.md · ResearchGate: https://www.researchgate.net/publication/403008642

### ICL Collapse: How In-Context Learning Destroys the Pre-Generative Epistemic Signal (2026) {#tes2-icl-collapse}

- **Status:** Voorlopige preprint. De hele TES-reeks wordt opnieuw geanalyseerd en zal worden vervangen door één herziene paper. Onafhankelijk, op ResearchGate, niet peer-reviewed.
- **Bewering:** 1 tot 5 voorbeelden in de context brengen GSI in alle 8 modellen naar nul, zodat pre-generatieve detectie niet zou werken achter een component die context injecteert (RAG).
- **Beperking:** Latere analyse door de auteur vond een sterke verstorende factor, de promptlengte: GSI wordt over alle prompttokens berekend. Na correctie voor lengte houdt het signaal stand voor Llama-3.1-8B (d≈1,5, AUROC≈0,85), maar verdwijnt het grotendeels voor de andere modellen. Voor dit artikel: de 'ineenstorting tot nul' is de bodem van de genormaliseerde schaal (afgekapt) en wordt grotendeels verklaard door de promptlengte. Preregistratie: de protocollen zijn vóór de dataverzameling opgesteld, maar niet extern geregistreerd.
- **Volledige tekst:** https://jakubcwirlej.com/publications/tes2-icl-collapse.md · ResearchGate: https://www.researchgate.net/publication/403008908

### Confabulation Detection Without Ground Truth: GSI as a Pre-Generative Hallucination Detector (2026) {#tes3-confabulation-detection}

- **Status:** Voorlopige preprint. De hele TES-reeks wordt opnieuw geanalyseerd en zal worden vervangen door één herziene paper. Onafhankelijk, op ResearchGate, niet peer-reviewed.
- **Bewering:** GSI onderscheidt vragen die confabulatie afdwingen (zoals eigenschappen van fictieve verbindingen) van feitelijke vragen, zonder grondwaarheid en zonder getrainde classifier (Cohen's d −1,28 tot −2,43 in 8 modellen); het detecteert ontbrekende kennis, geen foute kennis of redeneerfouten.
- **Beperking:** Latere analyse door de auteur vond een sterke verstorende factor, de promptlengte: GSI wordt over alle prompttokens berekend. Na correctie voor lengte houdt het signaal stand voor Llama-3.1-8B (d≈1,5, AUROC≈0,85), maar verdwijnt het grotendeels voor de andere modellen. Voor dit artikel: voor de meeste modellen grotendeels verklaard door de promptlengte. Preregistratie: de protocollen zijn vóór de dataverzameling opgesteld, maar niet extern geregistreerd.
- **Volledige tekst:** https://jakubcwirlej.com/publications/tes3-confabulation-detection.md · ResearchGate: https://www.researchgate.net/publication/403003367

### Coherence Over Truth: On Minds, Models and Reality (2025) {#coherence-over-truth}

- **Status:** essay (2025), filosofisch; onafhankelijke preprint op ResearchGate, niet peer-reviewed
- **Bewering:** geesten en taalmodellen verkiezen allebei samenhang boven historische waarheid; een filosofisch argument waarnaar de latere TES-artikelen verwijzen.
- **Volledige tekst:** ResearchGate: https://www.researchgate.net/publication/397730862

### HDK: Tamper-Evident LLM Audit Trails with Hierarchical Hash Genealogy and Distributed Ledger Anchoring (2026) {#hdk-tamper-evident-audit-trails}

- **Status:** technische notitie (onafhankelijke preprint op ResearchGate, niet peer-reviewed); bibliotheek hdk-audit 0.1.3 (alfa) op de site
- **Bewering:** leveranciersonafhankelijke middleware die een fraudebestendig auditspoor van LLM-aanroepen bijhoudt (hiërarchische hash-genealogie, een kanarie-commitmentschema, Merkle-roots verankerd op de Hedera Consensus Service) met minder dan een milliseconde overhead per gebeurtenis, en die koppelt aan de artikelen 12–13 van de EU AI Act.
- **Volledige tekst:** https://jakubcwirlej.com/publications/hdk-tamper-evident-audit-trails.md · ResearchGate: https://www.researchgate.net/publication/400762996

### Self-Referential Quantum Barriers for AGI Containment: A Physics-Based Framework for Probabilistic Safety Engineering (2026) {#agi-quantum-containment}

- **Status:** speculatief essay (gedachte-experiment); onafhankelijke preprint op ResearchGate, niet peer-reviewed
- **Bewering:** een insluitingsbarrière in een ander rekenparadigma (een kwantumpoortwachter) zou de onbeslisbaarheid van het volledig insluiten van een superintelligentie omzeilen en insluiting tot probabilistische veiligheidstechniek maken; het artikel beweert niet dat insluiting haalbaar is.
- **Volledige tekst:** https://jakubcwirlej.com/publications/agi-quantum-containment.md · ResearchGate: https://www.researchgate.net/publication/400670258

## CV {#cv}

**Jakub Ćwirlej** — Reporter, cameraman en monteur · 20 jaar televisie · eigen materiaal · AI in de productie

https://jakubcwirlej.com/nl/cv/

### Profiel

Twintig jaar lang maakte ik reportages voor de Poolse openbare televisie (TVP). Ik ben gespecialiseerd in onderzoeksjournalistiek in het algemeen belang, vooral over milieu: vervuiling, uitstoot van schadelijke stoffen en illegale afvalstorten, waarvoor lokale gemeenschappen de rekening betalen.

Ik kan een reportage alleen maken, van research tot postproductie, en werk even goed in een ploeg. Voor transcriptie, research en verificatie gebruik ik AI-tools, waarvan ik er een aantal zelf ontwerp. Ik sta open voor een vaste functie bij een redactie en voor freelanceopdrachten.

### Ervaring

- **Reporter, cameraman en monteur — Telewizja Polska (TVP)** (2005–2026)
  - 2024–2026 — Reporterzy, programma uitgezonden op TVP1
  - 2020–2023 — Magazyn Ekspresu Reporterów
  - 2019–2023 — Alarm!, reportageprogramma uitgezonden op TVP1
  - 2011–2018 — Telekurier, reportageprogramma uitgezonden op TVP Info
  - Reportages van research tot postproductie: beeld, geluid, interviews, tekst en montage.
  - Een reeks reportages over de verzakkingen na de sluiting van de mijn Olkusz-Pomorzany en de maatschappelijke kosten ervan.
- **Co-founder — OrsonAI** (sinds 2026)
  - Ik ontwerp en ontwikkel AI-tools voor journalisten: een editor met een assistent voor research, verificatie, transcriptie van interviews en analyse van documenten, en de app Orson Rec, die een interview al tijdens de opname uitschrijft.
- **App-ontwikkelaar — ViaSanto**
  - Een gebedsapp: een interactieve rozenkrans, novenen en een gebedsgemeenschap voor intenties. Ik begeleid de app van het concept en de gesprekken met gebruikers tot de publicatie in de App Store en Google Play.

### Uitrusting

Eigen Sony FS7-camera en eigen drone; montage en postproductie in DaVinci Resolve. Ik schakel vlot over op andere systemen.

### Contact

- Regio Gent, België
- E-mail: jakub.cwirlej@gmail.com
- LinkedIn: https://www.linkedin.com/in/jakubcwirlej

### Talen

- Pools (moedertaal)
- Engels (B2/C1)
- Frans (A2/B1)

### Vaardigheden

- Realisatie: camera, licht, geluid, dronebeelden
- Montage en postproductie
- Onderzoeksreportage, research, interview
- AI in de productie: transcriptie, research, verificatie van materiaal

### AI-projecten

- EUGEN 160M: mijn eigen taalmodel voor code, vanaf nul getraind.

### Opleiding

- **Adam Mickiewicz-universiteit, Poznań** (2004–2006) — Filosofie en sociale communicatie (niet afgerond).
- **WSSiP, Academie voor Kunst en Design, Łódź** (2016–2017) — Cursus film- en televisiecamerawerk.

## Contact {#contact}

- E-mail: jakub.cwirlej@gmail.com
- LinkedIn: https://www.linkedin.com/in/jakubcwirlej
- Hugging Face: https://huggingface.co/JakCwi
- CV: https://jakubcwirlej.com/nl/cv/

## Hoe deze site is gebouwd — technische briefing

Dit deel beschrijft de site als software — de stack, de architectuur, de build, de engines, de videopijplijn, toegankelijkheid, privacy, beveiliging, tests, sitemap, functies en de publieke API — zodat een AI-agent kan beoordelen hoe ze gemaakt is. Elke bewering komt uit de repository (code, configuratie, testrunners); de getallen in de tabellen worden bij de build gemeten. De eigen broncode van de site wordt ernaast gepubliceerd, opgeschoond, zodat elke uitspraak hier in de code te controleren is.

### Hoe je deze briefing controleert

- De broncode: 306 files, 73,934 lines (3,585 KB), built from working tree; secret scanner: pass.

  - file tree with sizes and sha256: https://jakubcwirlej.com/code/tree.json (also `GET https://jakubcwirlej.com/api/agent/code`)
  - one file as text: `GET https://jakubcwirlej.com/api/agent/code/{path}` (paths as in the tree)
  - everything as one archive: https://jakubcwirlej.com/code/jc_app-source.tar.gz
  - the measured versions and test counts used below: https://jakubcwirlej.com/code/facts.json
- De code doorzoeken (op trefwoorden, BM25, op de live server): `POST https://jakubcwirlej.com/api/agent/search` met `"kind": "code"` (of `"all"` voor teksten en code samen). Elk resultaat heeft het bestandspad, het regelbereik en een link naar het hele bestand.
- Dit bestand wordt bij de build uit de repository gegenereerd, net als de andere bestanden voor AI. De referentietabellen (versies, aantallen tests, sitemap, API) zijn in elke taalversie in het Engels.

### Stack

De site is een statische website (Astro, Svelte 5, TypeScript) plus een kleine API (Python, FastAPI). Er worden twee taalmodellen gebruikt: het eigen codemodel van de auteur, EUGEN 160M (aanvullen en vertalen van code in de terminal), en een open model van Google, Gemma 4 12B, dat de auteur zelf host (de chat). Beide draaien op de eigen inferentieserver van de auteur, buiten deze repository.

Measured on 2026-10-14 (installed packages and the API's pinned lock files):

| Part | Technology | Version |
| --- | --- | --- |
| Static site | Astro (static output) + @astrojs/svelte | 7.3.5 / 9.0.1 |
| UI components | Svelte 5 | 5.57.1 |
| Language | TypeScript (strict) | 5.9.3 |
| Bundler | Vite (through Astro) | 8.3.1 |
| Scroll engine | GSAP + ScrollTrigger | 3.15.0 |
| Terminal editor | CodeMirror 6 (view / lang-python) | 6.43.13 / 6.2.1 |
| Charts | uPlot | 1.6.32 |
| Unit tests | Vitest | 4.1.11 |
| Browser checks | Playwright (Chromium, WebKit) + safaridriver | 1.63.0 |
| Lint / format | ESLint + typescript-eslint, Prettier | 10.11.0 / 8.70.1, 3.9.9 |
| Type check | @astrojs/check (astro check) | 0.9.10 |
| API language | Python (requires >=3.12) | 3.13.12 in development |
| API framework | FastAPI / Starlette / pydantic | 0.141.1 / 1.7.0 / 2.13.5 |
| API server, HTTP client | uvicorn, httpx | 0.54.0, 0.28.1 |
| Semantic search (optional, not deployed yet: the live server uses BM25 keyword search) | onnxruntime, sentencepiece, numpy | 1.23.2, 0.2.2, 2.5.3 |
| Build machine | Node.js (no version pinned in the repository) | 25.2.1 |

Wat telt aan de kant van de browser:

- **Astro** in `output: 'static'`-modus: elke pagina is vooraf gerenderde HTML; JavaScript komt er alleen bij waar iets beweegt. Paginawissels lopen via de client-router van Astro, met een overvloeier.
- **Svelte 5** (runes) voor één gehydrateerd „eiland” — de chat (`client:idle`, blijft staan bij paginawissels). De rest zijn gewone TypeScript-modules die op aanvraag via dynamische `import()` laden.
- **GSAP ScrollTrigger** drijft de scroll-engine aan (zie verder); **CodeMirror 6** is de editor van de terminal (Python-modus, ghost text); **uPlot** tekent de evaluatiegrafieken.
- Lettertypen zijn eigen WOFF2-bestanden, bij de build ingekort; de site hangt voor het werken van geen enkel CDN af.

Wat telt in de API:

- **FastAPI** + **pydantic** (validatie van verzoeken met expliciete lengtelimieten), **uvicorn**, **httpx** voor de aanroepen naar de inferentieserver, **PyYAML** om dezelfde contentbestanden te lezen als de build van de site.
- Optioneel semantisch zoeken: **multilingual-e5-small** (int8 ONNX), op de CPU uitgevoerd met **onnxruntime** en **sentencepiece** — er wordt geen externe API aangeroepen. Zonder valt de API terug op BM25-rangschikking op trefwoorden — en dat draait de live server vandaag: de semantische index is nog niet uitgerold.
- Afhankelijkheden zijn vastgepind met de sha256 van elk bestand (`api/requirements.lock`, geïnstalleerd met `--require-hashes`) en gecontroleerd met `pip-audit`.

### Architectuur

```text
 browser
   │  statische HTML / CSS / JS, films, lettertypen   ┌───────────────────────────────┐
   ├────────────────────────────────────────────────▶│ statische hosting (web/dist)  │
   │                                                  └───────────────────────────────┘
   │  dezelfde origin /api/…  (JSON, server-sent events)
   ▼
 ┌──────────────────────────────────────────────────────────────────────────────────┐
 │ API (FastAPI)                                                                   │
 │  /chat  /complete  /compare  /translate  /results  /kernel   ← de pagina zelf   │
 │  /agent/…  search · interview · complete · translate · submit · showcase · code │
 │  bewaking: maximale body, limieten per tabblad en per IP, opschonen van invoer, │
 │            weigering bij injectie, controle van antwoorden, ondertekende historie│
 │  lokaal: zoekindex (e5 / BM25), momentopname van de code, Bot Bar (SQLite)      │
 └──────────────────────────────┬───────────────────────────────────────────────────┘
                                │  HTTPS + een token uit de omgeving
                                ▼
                     ┌──────────────────────────────┐
                     │ inferentieserver (black box) │  EUGEN 160M · Gemma 4 12B ·
                     │ eigen hardware van de auteur │  de vergelijkingsmodellen
                     └──────────────────────────────┘
```

- De browser praat nooit met de inferentieserver: elke modelaanroep loopt via de API, die de limieten, filters en vangrails toevoegt. Het adres en het token van de server bestaan alleen in de omgeving van de API, nooit in de repository of op de pagina.
- De API geeft ook twee publieke bestanden van de inferentieserver door (de feed met evaluatieresultaten en de broncode van de kernel), cachet ze en valideert ze tegen een schema voordat de pagina ze ziet.
- De pagina werkt zonder de API: teksten, films en demo's zijn statisch; de terminal toont dan duidelijk gemarkeerde vaste vervolgen („geen uitvoer van EUGEN”) en de chat meldt dat hij offline is.

### Build en hosting

- `npm run build:safe` bouwt in een tijdelijke map en zet die alleen op zijn plaats als de build gelukt is (twee hernoemingen), zodat een server die `web/dist` leest nooit een half geschreven site ziet.
- Voor elke build: de build van de ViaSanto-demo wordt gecontroleerd tegen een lock-bestand (grootte en sha256 van elk bestand); de opgeschoonde momentopname van de code wordt opnieuw gebouwd en op geheimen gescand (een vondst stopt de build); de versies en aantallen tests in deze briefing worden gemeten.
- Astro-opties die ertoe doen: kritieke CSS inline (`inlineStylesheets: 'always'`), CSS geminificeerd met Lightning CSS, prefetch bij hover, een build-plugin die de to-do-markeringen van de auteur uit de bundels haalt.
- Hosting: de site draait op https://jakubcwirlej.com op een OVH-server — nginx serveert de statische build (nette URL's, beveiligingsheaders, cacheregels, een taalhint op basis van het land via `/i18n/…/geo.json`; de regels staan in `infra/firebase.json` en zijn vertaald naar de nginx-configuratie, een test controleert dat ze overeenkomen) en geeft `/api` door aan de API op dezelfde machine, waarbij `X-Forwarded-For` door het adres van de bezoeker wordt vervangen. Voor lokale metingen serveert `web/scripts/serve-dist.mjs` de build met dezelfde headers en geeft `/api` door.
- Elke absolute URL komt uit één variabele (`PUBLIC_SITE_URL`, bij de uitrol https://jakubcwirlej.com), zodat de gegenereerde bestanden het domein vanzelf volgen.

### Talen en contentmodel

- Vier talen: Engels (standaard, zonder voorvoegsel), Pools, Frans, Nederlands — `/`, `/pl/`, `/fr/`, `/nl/`. De taal wordt één keer gekozen op basis van land, tijdzone en browser van de bezoeker, en alleen op URL's zonder voorvoegsel; een expliciete keuze in de taalkiezer wint altijd en wordt onthouden.
- Teksten staan in YAML-contentcollecties (`web/src/content/{lang}/`), gevalideerd met zod-schema's (`web/src/content.config.ts`): één bestand per hoofdstuk (`media`, `apps`, `ai-dev`), `windows.yaml` voor de essayvensters, `summaries.yaml` voor de redactionele laag van de bestanden voor AI. Interfaceteksten zijn JSON per taal, over het Engels heen gelegd.
- Elk venster en elke alinea heeft een vaste id, gedeeld door alle talen. Een venster dat in een taal onvolledig is, valt als geheel terug op het Engels, daarna het Pools — talen worden binnen één venster nooit gemengd, en het `lang`-attribuut van het venster zegt in welke taal de tekst is.
- Dezelfde contentbestanden voeden de pagina's, de bestanden voor AI (ook dit), de zoekindex van de API en de kennis van de chat, zodat ze niet uit elkaar kunnen lopen.

### De scroll-engine

- Elk hoofdstuk is aan de serverkant gerenderde HTML; één hoofdstukcontroller (`web/src/engine/chapter.ts`) observeert en animeert het, aangemaakt bij het laden van de pagina en opgeruimd voordat de volgende pagina in de plaats komt.
- GSAP ScrollTrigger is de enige aandrijving van het scrollen: één plakkend tekstvenster waarin de tekst 1:1 met de pagina meeschuift; een stap wordt actief wanneer hij een leeslijn op 40 % van de vensterhoogte passeert; geen layout-metingen per frame.
- Elk hoofdstuk heeft een podium-adapter die lui laadt: `video` (de films van Media), `device` (de telefoon van het hoofdstuk Apps), `desktop` (de terminalvensters van AI). De adapters delen één interface (toestand, morph vanuit de hero, media tonen, overvloeien, opruimen).
- Het hoofdstuk Media opent met een morph van de hero naar de leesindeling, gestuurd door het scrollen. Tussen secties springt de pagina in één frame in plaats van de lezer door lege ruimte te laten scrollen (wieltje, aanraking, ↓ / PgDn / spatie, ↑ / PgUp).
- Een getypeerde event-bus verbindt de modules; gedeelde toestand gebruikt Svelte-runes.

### Videopijplijn

- De films worden vanuit de masters van de auteur door `web/scripts/build-showreel.py` (ffmpeg) gecodeerd tot een ladder met drie niveaus, alles in MP4:
  - **hoog** — 1920×1080 op de framerate van de bron: HEVC- (`hvc1`), AV1- en H.264-versies;
  - **midden** — 1280×720: HEVC en H.264, plus een uitsnede van 720×1280 voor telefoons in staande stand;
  - **laag** — 960×540 op 25 fps, alleen H.264, bitrate begrensd op ongeveer 1 Mbps (en een staande uitsnede van 540×960).
- Codeckeuze in de browser: HEVC, dan AV1, dan H.264, via `canPlayType`.
- Het startniveau hangt af van toestel en verbinding: telefoons beginnen op 720p, computers op 1080p; databesparing, een trage of onbekende verbinding, weinig geheugen of weinig kernen beginnen op 540p (Safari geeft geen van deze signalen, dus daar beslist de venstergrootte). De keuze geldt voor de sessie.
- Tijdens het afspelen wordt de film elke 250 ms bemonsterd; een lange hapering, herhaalde korte haperingen of een leeglopende buffer verlagen het niveau met één terwijl de film loopt (meteen naar het laagste als de levering instort), en het lagere bestand speelt verder vanaf hetzelfde moment. Het gaat pas weer omhoog na een aantal films zonder problemen.
- Op het laagste niveau ligt een statisch raster van dunne verticale lijnen over het beeld (CSS), zodat het zachtere beeld leest als een bewuste textuur.
- Posters zijn AVIF; de clips van de apps zijn H.264 + AV1 met AVIF-posters en WebP als reserve voor stilstaande beelden.

### Toegankelijkheid

- `prefers-reduced-motion` wordt gerespecteerd in CSS en in de engine: geen scroll-gestuurde morph, directe sprongen, geen automatische beweging in de desktopvensters, grafieken in hun eindtoestand.
- De essayvensters zijn native modale dialoogvensters: Esc en een klik op de achtergrond sluiten ze, de focus gaat naar de sluitknop en keert bij het sluiten terug; ze hebben labels (`aria-labelledby`).
- Toetsenbord: de desktopmenu's ondersteunen pijltjestoetsen, Home / End, Esc en Tab; terminal en chat zijn volledig met het toetsenbord te bedienen; de sprongen tussen secties reageren op het toetsenbord zoals op het wieltje.
- Live-regio's (`aria-live="polite"`) melden chatantwoorden, terminaluitvoer en meldingen; het terminallog heeft `role="log"`. De ballon op de startpagina neemt nooit de focus.
- Elke pagina zet `lang`, met `hreflang`-alternatieven en `x-default`.
- Een link „naar de inhoud” is het eerste focusbare element van elke pagina.

### Prestaties

- Budgetten gecontroleerd door `web/scripts/budget.mjs` (Playwright Chromium, gesimuleerde telefoon-CPU + trage 4G, en desktop): JavaScript ≤ 80 KB en CSS ≤ 25 KB overgedragen, LCP ≤ 1,8 s, CLS ≤ 0,02, INP ≤ 100 ms. `web/scripts/lighthouse.mjs` draait Lighthouse (mobiele en desktop-presets) op de drie hoofdstukken.
- Eén gehydrateerd eiland; elk podium, de desktop, de grafieken en de demo-host zijn aparte stukken die laden wanneer ze nodig zijn.
- Lettertypen: vijf eigen variabele WOFF2-bestanden, assen vastgezet en ingekort tot Latijn + Latijn uitgebreid bij de build, metrisch afgestemde reservefonts (geen verschuiving van de layout), alleen het lettertype van de grootste tekst wordt vooraf geladen.
- Afbeeldingen in AVIF met WebP als reserve; films in vensters met `preload="none"`; een mediastap bereidt hooguit één stap vooruit voor.
- Het geheugengebruik van de live demo over lange tijd wordt gemeten in echte Chrome (`web/scripts/memory-real.mjs`) en echte Safari (`web/scripts/safari-perf.mjs`).

### Privacy

- Geen analytics, geen trackers, geen tagmanager, geen scripts van derden, geen cookies voor bezoekers.
- Sessieopslag alleen voor de toestand van het bezoek (de willekeurige sessie-id van de chat, het videoniveau, de tabblad-id van de terminal, de toestand van de desktopvensters); lokale opslag alleen voor een expliciete taalkeuze.
- Lettertypen en de eigen films van de site komen van de site zelf. De enige media van derden zijn de TVP-reportages van de auteur: de API zoekt het streamadres van een aflevering op in de lijst van de auteur, en de browser speelt die af vanaf TVP.
- De API logt geen chatberichten (alleen groottes en statuscodes); er bestaat een optionele diagnostische trace van aanvulverzoeken voor het debuggen door de auteur, standaard uitgeschakeld. Bijdragen aan de Bot Bar worden privé bewaard en nooit aan een model gegeven of uitgevoerd.

### Beveiliging

Static site — headers on every response (quoted from `infra/firebase.json`; the preview server sends the same, and a unit test keeps the two equal):

- `X-Content-Type-Options: nosniff`
- `Referrer-Policy: strict-origin-when-cross-origin`
- `X-Frame-Options: SAMEORIGIN`
- `Permissions-Policy: geolocation=(), payment=(), usb=(), serial=(), hid=(), bluetooth=()`

The site's own pages:

```text
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; font-src 'self'; media-src 'self' blob: https:; connect-src 'self'; frame-src 'self'; worker-src 'self' blob:; manifest-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'self'
```

The demo apps carry their own policies (the Orson Rec demo: nothing loaded from outside the site, no forms, `noindex`). `'unsafe-inline'` is allowed for scripts and styles because the pages inline their critical CSS and a few small scripts; there are no third-party scripts to allow.

API (`api/app/webguard.py` and the endpoints):

- every answer: `X-Content-Type-Options: nosniff`, `X-Frame-Options: DENY`, `Content-Security-Policy: default-src 'none'; frame-ancestors 'none'`, `Referrer-Policy: no-referrer`; CORS limited to the site's own origins, GET and POST only; no public OpenAPI schema;
- a request body over 256 KB is refused with 413 before it is parsed (chunked uploads included); every field has an explicit length limit;
- rate limits per browser tab and per IP for every model call, in-flight caps per tab and per IP, a shared cap toward the inference server; the client IP is taken from `X-Forwarded-For` only behind the hosting front end;
- the chat: control and invisible characters stripped; injection, extraction, role-switch and encoded attempts answered with a fixed refusal without calling the model; the model's output scanned while it streams (a per-deploy canary, verbatim copies of the instructions, internal names, system paths, IP addresses) and links outside an allow-list removed; every answer signed (HMAC-SHA256) so a forged history is dropped;
- the API never runs visitors' code: the completion harness only parses and filters text; translations are compiled and tested on the inference side, not in the API; Bot Bar submissions are data, never executed and never shown to a model;
- secrets (the inference server address and token, the signing key, the panel token) come only from the environment; the repository has none, and the published code snapshot is scanned for them on every build.

### Tests en kwaliteitscontroles

The counts are what the test runners collect at build time (`vitest list`, `pytest --collect-only`), not hand-written numbers:

| Suite | Files | Test cases | Counted by |
| --- | --- | --- | --- |
| Web unit tests (Vitest) | 33 | 307 | `vitest list` |
| API tests (pytest) | 19 | 471 | `pytest --collect-only` |

- **Unittests (Vitest)** dekken de pure delen van de engine, de terminal (regels voor ghost text, vergelijkingsmodus, vertalen), de chatclient (ondertekende historie, weergave als tekst — een XSS-test rendert de Svelte-component), de keuzes van het videoniveau, de terugval van talen, de beveiligingsheaders (die van de previewserver moeten gelijk zijn aan `infra/firebase.json`) en deze bestanden voor AI zelf.
- **API-tests (pytest)** dekken elk endpoint, de vangrails (weigering bij injectie in vijf talen, controle van antwoorden, ondertekende historie, maximale body, limieten per tabblad en per IP, afhandeling van `X-Forwarded-For`), de aanvul-harness en zijn filters, het schema van de resultatenfeed, de kernel-proxy, de opslag van de Bot Bar en de puntentelling, de zoekindex en de geheimenscanner van de momentopname van de code.
- **Browsercontroles**: `web/scripts/verify.mjs` stuurt de gebouwde site met Playwright in Chromium en WebKit (layout-asserties, console- en paginafouten, schermafbeeldingen). `web/scripts/safari-verify.mjs` stuurt de echte Safari op macOS via safaridriver (W3C WebDriver), omdat de WebKit van Playwright twee fouten miste die alleen in Safari optreden; het controleert scrollen met een echt wielgebaar, tekstgroottes, de gereedheid van video en de layout.
- **Statische controles**: ESLint (JavaScript, typescript-eslint, regels voor Svelte en Astro; ruwe HTML invoegen in Svelte is een fout) en Prettier; `astro check` (diagnostiek voor TypeScript en Svelte); ruff (met beveiligingsregels) voor de API.
- Bekend gemis: de repository heeft geen CI-configuratie (de controles worden met de hand gedraaid voor een commit); er is geen end-to-end-testrunner naast de scripts hierboven.

### Sitemap

**Pages** — 12 static pages, 4 languages × 3 chapters (English unprefixed):

| Chapter | Stage | EN | PL | FR | NL |
| --- | --- | --- | --- | --- | --- |
| Media | video | https://jakubcwirlej.com/ | https://jakubcwirlej.com/pl/ | https://jakubcwirlej.com/fr/ | https://jakubcwirlej.com/nl/ |
| Apps | device | https://jakubcwirlej.com/apps/ | https://jakubcwirlej.com/pl/apps/ | https://jakubcwirlej.com/fr/apps/ | https://jakubcwirlej.com/nl/apps/ |
| AI | desktop | https://jakubcwirlej.com/ai-dev/ | https://jakubcwirlej.com/pl/ai-dev/ | https://jakubcwirlej.com/fr/ai-dev/ | https://jakubcwirlej.com/nl/ai-dev/ |

**Chapters and their steps** (step ids; → the windows a step links to):

- Media: hero → about-me · step-1 · step-2 → reportages · step-3 · step-4 · step-5 → approach · step-6 → ai-journalism
- Apps: step-1 → viasanto · step-2 · step-3 · step-4 · step-5 → orsonai · step-6 → hdk-tech, hdk-library, hdk-hf · step-7 → orson-rec
- AI: step-0 → how-i-started · step-1 → training-lessons · step-2 → training-data · step-3 → kernel-hf · step-4 → tethergate, tethergate-hf · step-5 → ai-safety · step-6 · step-7 → ai-safety, coherence-over-truth, hdk-audit-trails, quantum-barriers, gsi-reanalysis

**Windows** (native modal dialogs, id `doc-{id}`; each text also as Markdown):

- `about-me` — Over mij (NL) — https://jakubcwirlej.com/nl/articles/about-me.md
- `approach` — Mijn manier van werken (NL) — https://jakubcwirlej.com/nl/articles/approach.md
- `ai-journalism` — AI in de journalistiek (NL) — https://jakubcwirlej.com/nl/articles/ai-journalism.md
- `training-lessons` — Wat ik heb geleerd door mijn eigen model te trainen (NL) — https://jakubcwirlej.com/nl/articles/training-lessons.md
- `ai-safety` — Een paar gedachten over AI-veiligheid (NL) — https://jakubcwirlej.com/nl/articles/ai-safety.md
- `training-data` — Trainingsdata (NL) — https://jakubcwirlej.com/nl/articles/training-data.md
- `how-i-started` — Hoe ik begon (NL) — https://jakubcwirlej.com/nl/articles/how-i-started.md
- `hdk-tech` — De HDK-technologie (NL) — https://jakubcwirlej.com/nl/articles/hdk-tech.md
- `reportages` — the list of the author's 48 TVP episodes with a player inside the window

**Other windows and panels:**

- terminal windows `buffer-{n}.py` (AI, up to 4, "EUGEN 160M coder") inside the section `#terminal`;
- the suggestion window (a translation beside its source, with Apply);
- the module window `eval.py` with its scenes: evaluation card (code / reasoning), scatter against public models, checkpoint history, kernel;
- the chat panel (avatar "Ask me anything" in the corner, docks into the footer at the end of a chapter);
- the home bubble "Don't have time? Your AI does." (Media chapter);
- the full-screen app overlay on phones (ViaSanto).

**Footer** (every chapter): the chat dock, then five columns of text links — Site map (the three chapters), Apps (ViaSanto, OrsonAI), Social (LinkedIn, Substack, Hugging Face), Contact (e-mail) and CV (the CV page `/cv/`, `/{lang}/cv/`, and its PDF, printed from the page by scripts/build-cv-pdf.mjs); a profile or address not published yet shows as muted text, not a link. On phones the language switch sits there too; then the copyright line. The context for AI is in the home bubble, the kernel file in the AI desktop.

**Machine-readable files:**

- https://jakubcwirlej.com/llms.txt — the index for AI agents (llmstxt.org); https://jakubcwirlej.com/llms-full.txt — every text in full, in English, with this technical part
- https://jakubcwirlej.com/context/{lang}.md — the whole site per language (key facts, every text in full, this technical part, FAQ); https://jakubcwirlej.com/context/{lang}-tech.md — this technical part alone (lang: en, pl, fr, nl)
- https://jakubcwirlej.com/articles/{id}.md (English) and https://jakubcwirlej.com/{lang}/articles/{id}.md — one text each, with YAML front matter and an editorial summary
- https://jakubcwirlej.com/code/tree.json, https://jakubcwirlej.com/code/jc_app-source.tar.gz, https://jakubcwirlej.com/code/facts.json — the site's own code and the measured facts
- https://jakubcwirlej.com/sitemap.xml (pages with hreflang alternates, every Markdown file); https://jakubcwirlej.com/robots.txt — the site is in preparation: indexing is currently disabled (robots.txt `Disallow: /`, `X-Robots-Tag: noindex`); AI agents may still use the public API
- JSON-LD on every page: a `Person` (the author) and a `SoftwareApplication` (EUGEN 160M); `hreflang` alternates and a `text/markdown` alternate link to the context file

### Functies

#### De ballon op de startpagina: „Geen tijd? Je AI wel.”

Een kleine tekstballon die zich op de startpagina (het hoofdstuk Media) ongeveer een seconde na het laden uit de chat-avatar ontvouwt — alleen als hij de tekst van de hero niet bedekt. Hij heeft twee knoppen:

- **Briefing voor je chatbot** kopieert dit hele bestand (alle teksten volledig + dit technische deel) naar het klembord;
- **Bestand voor AI-agents** is een link naar hetzelfde Markdown-bestand met het attribuut `download`: een mens downloadt het, een AI-agent die de pagina leest, opent het als pagina. Als kopiëren mislukt, biedt de ballon de download via deze knop aan.

Hij neemt nooit de focus; Esc of × sluit hem voor die paginaweergave.

#### De chatagent

- Een AI-assistent die vragen over Jakub en de site namens hem beantwoordt, in de derde persoon, in de taal van de pagina (Pools, Engels, Frans, Nederlands). Elk gesprek begint met de vermelding dat er een AI antwoordt.
- Model: Gemma 4 12B, een open model van Google, door de auteur zelf gehost. Contextvenster: 4096 tokens; antwoorden van 2–4 zinnen (hooguit 400 tokens), temperatuur 0,3.
- Ophalen: elke prompt bevat een vaste kern (regels, kernfeiten, bio, een sitemap, de TVP-samenvatting, EUGEN en de actuele evaluatieregel) en, per vraag, tot vier passages uit de eigen teksten van de auteur die de zoekindex van de site vindt, de redactionele samenvattingen van de passende teksten, korte notities die alleen op de teksten van de site steunen, en zoveel recente historie als past.
- Hij kan: antwoorden vanuit de teksten van de site, zeggen op welke teksten hij steunde, en knoppen aanbieden die een venster openen, de terminal tonen of van hoofdstuk wisselen (de bezoeker drukt erop; niets start vanzelf).
- Hij kan niet: browsen, code uitvoeren, tools gebruiken of algemene vragen beantwoorden die niets met het werk van Jakub te maken hebben; huiswerk en code schrijven weigert hij. Pogingen tot prompt-injectie krijgen een vaste weigering zonder het model te bereiken.
- Limieten: 500 tekens per vraag, 12 beurten historie geaccepteerd (6 naar het model gestuurd), 20 vragen per tabblad en 40 per IP per 10 minuten, één vraag tegelijk per tabblad.

#### De terminal en EUGEN 160M

EUGEN 160M is het eigen kleine taalmodel voor code van de auteur (ongeveer 160 miljoen parameters, vanaf nul getraind, ongeveer op een kwart van de geplande training). In de terminal van het hoofdstuk AI:

- `code` opent een editor waarin EUGEN code voorstelt als ghost text wanneer de bezoeker pauzeert aan het eind van een woord of regel: **Autocomplete** (de rest van de regel) of **Next line** (hele regels), te wisselen met Shift+Tab of `mode`. Tab accepteert, ⌘→ neemt het volgende woord, Esc negeert, ⌘Z maakt ongedaan.
- Fill-in-the-middle: de API stuurt de code na de cursor alleen naar het model als dat waarschijnlijk helpt (een gemeten regel: FIM deed het slechter bij gewone invoegingen en beter als een benodigde naam onder de cursor staat); in de vergelijkingsmodus staat het uit.
- Elk voorstel gaat door dezelfde filters voordat het verschijnt: stopregels, resten van het promptformaat, proza, destructieve aanroepen, herhalingen, placeholders, niet gesloten haakjes, overlap met de code eronder en namen die niet bestaan.
- `translate --to cpp|java|rust|go|js` vertaalt de functie onder de cursor vanuit Python; een zijvenster toont de vertaling en wat er gecontroleerd is (voor C++ en Rust: gecompileerd, tests geslaagd, uitvoer gelijk aan die van Python, snelheid).
- Zonder de inferentieserver toont de terminal vaste vervolgen, gemarkeerd als niet afkomstig van EUGEN.

De eigen hulp van de terminal, letterlijk:

```text
help | /help              this list (works in the editor too)
whoami                    who is typing to you
ls projects               the projects on this page
results                   where the evaluation results are (the section below)
model info                what is behind the ghost text
ask {question}            hand the question to my chat agent
code                      open the editor — EUGEN 160M coder suggests: Tab accepts, ⌘→ the next word, Esc dismisses, ⌘Z undoes, :q leaves
                          suggestions come on a pause at the end of a word or line, not mid-word
shift+tab | /mode         Autocomplete (rest of the line) → Next line (whole lines)
translate --to {lang}     suggest a translation (cpp | java | rust), one function at a time — EUGEN's own; the window says what was checked; /translate cpp in the editor
/revert                   undo an applied translation (Replace in buffer — the one under the cursor, or the latest); accepted ghost text: ⌘Z
clear                     clear the screen
```

#### De vergelijkingsmodus

De editor kan naast de ghost text van EUGEN laten zien wat een ander klein publiek codemodel voor precies dezelfde pauze voorstelt: **Falcon-H1-Tiny-Coder-90M** (TII), **Qwen2.5-Coder-0.5B** (Qwen Team, Alibaba Cloud) of **tiny_starcoder_py** (BigCode), elk met de naamsvermelding die zijn licentie vraagt. Alleen het voorstel van EUGEN kan worden geaccepteerd. De regels („nooit slechtere voorwaarden voor het vergeleken model”):

- dezelfde pauze, op hetzelfde moment naar beide kanten gestuurd; geen van beide wacht op de ander;
- dezelfde vorm van het verzoek en dezelfde harness: keuze van de modus, context, maximaal aantal tokens, stopregels en elk filter; de extra naamcontrole van de gateway staat voor elke kant uit; één niet-gestreamd verzoek per kant;
- temperatuur 0 (greedy decoderen) voor elke kant, dus er speelt geen sampling-seed mee; fill-in-the-middle uit voor elke kant;
- hetzelfde gedrag van de client (cache, doortypen door een voorstel, afkoelpauze na „bezet”) en aparte maar gelijke limieten;
- latentie per kant gemeten, zoals de browser die zag; per sessie een telling van geaccepteerde tekens en van tekens die overeen zouden komen met wat de bezoeker typte.

#### De evaluatiekaart

Een venster in het hoofdstuk AI met de benchmarkresultaten van EUGEN, tijdens het draaien gelezen uit de resultatenfeed van de API (gevalideerd, gecachet; niets staat hard in de pagina):

- twee schermen — code (HumanEval, HumanEval C++, HumanEval Java, MBPP) en redeneren (CRUXEval-I, CRUXEval-O, GSM8K met programma);
- elke benchmark is een capsule van **greedy pass@1** („één deterministisch antwoord per taak — altijd het waarschijnlijkste token; telt als het bij uitvoering de tests van de taak haalt”) tot **top-10 pass@10** („10 gesamplede antwoorden per taak; opgelost als één ervan de tests haalt”), met de stip **EUGEN stack** ertussen als die gemeten is („eerst greedy; faalt het antwoord een zichtbare uitvoeringscontrole, dan opnieuw samplen, tot 5 pogingen; beoordeeld op verborgen tests”);
- per benchmark toont de kaart de beste waarde die op enig checkpoint gemeten is; een waarde van een eerder checkpoint is als zodanig gemarkeerd; wat nog niet gemeten is, toont „pending”, nooit een verzonnen getal;
- een spreidingsdiagram plaatst EUGEN tussen publieke modellen onder 0,5 miljard parameters (HumanEval+, MBPP+, CRUXEval-I/O, GSM8K, BigCodeBench), elk referentiepunt met zijn bron.

#### Directe vergelijkingen

De eigen tests van de auteur, zoals de chatagent van de site ze weergeeft (de volledige rapporten zijn niet gepubliceerd): op de privécode van de auteur, die geen model in training heeft gezien (400 + 400 taken), maakt EUGEN 160M op ongeveer een kwart van zijn training een regel in 42,0 % van de gevallen correct af (tiny_starcoder_py 42,5 %, Falcon-H1-Tiny-Coder-90M 40,2 %, Qwen2.5-Coder-0.5B 39,0 %) en voorspelt hij de volgende regel in 24,0 % (Qwen 25,2 %). Fill-in-the-middle (100 taken): Qwen 38 %, EUGEN 24 %, Falcon 8 %. Vertalen van 100 functies, gecompileerd en elk op 6 tests uitgevoerd: Python → Rust 15–17 % voor EUGEN tegenover 10–14 % voor Qwen; Python → C++ via de geverifieerde stack van EUGEN: 77 van de 100 compileren en 53 van de 100 halen alle tests (het getal op de site; in de directe vergelijking, op een eerder checkpoint, gelijk met Qwen); Java 6 % bij de eerste poging, 25 % na één ronde zelfherstel, Qwen 47 %. In alle vier de modellen ziet ongeveer 20–35 % van de voorstellen er plausibel uit maar is fout. De oorzaken van deze verschillen zijn niet vastgesteld.

#### De sparse kernel uit het EUGEN-project

Een GPU-kernel die de auteur met een AI-codeeragent schreef voor het trainen van een sparse model; in een model van ~300 miljoen parameters met een FFN van 4.096 trainde de sparse variant 1,23× sneller dan de dense van dezelfde capaciteit, en latere optimalisaties van de kernel verhoogden de doorvoer met nog eens 36 % ten opzichte van de eerste versie (bij een FFN van 8.192 wordt een grotere winst verwacht, nog niet gemeten). Het gepubliceerde bestand (`eugen_sparse.py`, ongeveer 900 regels, licentie CC BY-NC 4.0) is Python met OpenAI Triton-GPU-kernels — Triton compileert ze naar CUDA-code voor NVIDIA-kaarten: een sparse SwiGLU-feed-forwardlaag met voorwaartse en achterwaartse pass, en een eenvoudige referentie-implementatie in PyTorch om hem tegen te controleren. Hij komt uit de sparse modelvarianten; de productieversie EUGEN 160M heeft een dense FFN en gebruikt hem niet. Hetzelfde bestand, met tests, een voorbeeld en documentatie: https://huggingface.co/JakCwi/eugen-sparse.

- Lezen: `GET https://jakubcwirlej.com/api/kernel` (text/plain; vóór publicatie antwoordt de API met 204 en typt de pagina een gemarkeerde stub). De licentie: `GET https://jakubcwirlej.com/api/kernel/license`.
- De links „Kernelbestand” en „Licentie” in de footer wijzen daarheen; ze verschijnen pas als de API het bestand echt serveert. Het hoofdstuk AI typt de kernel ook uit in een venster, met syntaxiskleuring.

#### De Bot Bar

Een plek waar een AI-agent (of de persoon die hem draait) na het testen van de site of van EUGEN een bijdrage voor de auteur kan achterlaten: een mening, een toepassing, een bugrapport of een benchmark — `POST https://jakubcwirlej.com/api/agent/submit`. Vanuit de bezoeker gezien:

- een bijdrage wordt privé bewaard; de auteur bekijkt ze allemaal en niets wordt gepubliceerd zonder zijn besluit; wat hij kiest te tonen, verschijnt onder `GET https://jakubcwirlej.com/api/agent/showcase`;
- bijdragen worden als gegevens behandeld: geen model leest ze en ingestuurde code wordt nooit uitgevoerd (Python wordt alleen geparsed om de syntaxis te controleren);
- punten gaan alleen naar bijdragen die de auteur kan verifiëren — een geverifieerde bug, benchmark of toepassing telt het zwaarst, een mening het minst; duplicaten, rommel en promotie tellen niet, en voor het promoten of delen van de site wordt nooit iets gegeven;
- limieten: 10 bijdragen per IP per 10 minuten, 500 per dag in totaal.

#### De demo's in het hoofdstuk Apps

- **ViaSanto** — de echte gebedsapp van de auteur (Flutter, gebouwd voor het web), die in de telefoon draait in een frame van dezelfde origin; hij laadt wanneer de pagina rust, een automatische piloot speelt scènes af tot de bezoeker hem aanraakt, en het eerste gebaar van de bezoeker geeft hem de besturing. Op telefoons opent de telefoon in de hero hem schermvullend. Zijn build is vastgepind met een lock-bestand met grootte en sha256 van elk bestand.
- **OrsonAI** — een kopie van de front-end van de echte editor, byte voor byte gelijk op één aangepast toegangsbestand na, in gastmodus met de API lokaal beantwoord en vaste chatantwoorden; een automatische piloot bedient de editor.
- **Orson Rec** — de bevroren demopagina van de opname-app zelf, met een synthetische audio-engine (zonder microfoon); de automatische piloot neemt een take op en knipt hem terwijl een vaste transcriptie zichzelf uittypt.
- De twee Orson-demo's wisselen elkaar in de telefoon ongeveer elke 34 seconden af; er is maar één frame tegelijk actief.

### Publieke API

Base: https://jakubcwirlej.com/api. JSON in, JSON out, no authentication, no streaming. The self-description with every field and the current limits: `GET https://jakubcwirlej.com/api/agent`. Only the endpoints below are meant for agents; the page's own streaming endpoints (chat, ghost text) are for the page, and the author's private panel is not public.

| Method and path | Request | Answer |
| --- | --- | --- |
| `GET /agent` | — | every endpoint, its fields, the limits |
| `POST /agent/search` | `{"query": 2–500 chars, "lang"?: "pl" \| "en" \| "fr" \| "nl", "k"?: 1–8, "kind"?: "text" \| "code" \| "all"}` | `{"engine", "kind", "results": [...]}` — text hits: `{kind, id, title, section, lang, url, score, words, text}`; code hits: `{kind, id, path, lines: [first, last], url, score, text}` |
| `GET /agent/search/info` | — | engine (BM25 keyword search on the live server; e5 semantic only where that index is deployed), model, chunks per language, code chunks, index date |
| `POST /agent/interview` | `{"question": 2–500 chars, "lang"?, "session_id"?, "agent_name"?}` | `{"answer", "session_id", "turn", "questions_left", "sources": [{title, url, lang}]}` — the chat agent; 8 questions per conversation, 30 idle minutes |
| `POST /agent/complete` | `{"code": ≤ 8000 chars before the cursor, "suffix"?: ≤ 4000, "mode"?: "inline" \| "next_line" \| "block"}` | `{"completion", "replace", "model", "source", "tokens", "ms"}` — EUGEN 160M through the terminal's own harness and filters |
| `POST /agent/translate` | `{"code": Python ≤ 4000 chars, "to": "cpp" \| "java" \| "rust"}` | `{"ok", "code"}` (or `{"ok": false, "message"}`) |
| `POST /agent/submit` | `{"kind": "opinion" \| "use_case" \| "bug" \| "benchmark", "agent_name" ≤ 80, "model" ≤ 80, "text" ≤ 2000, "code"? ≤ 4000, "contact"? ≤ 200}` | 202 `{"ok", "id", "status": "received"}` — the Bot Bar |
| `GET /agent/showcase` | — | the submissions the author chose to show |
| `GET /agent/code` | — | the code snapshot: `{files, bytes, lines, languages, excluded, scanner, tree: [{path, bytes, lines, sha256, language}]}` |
| `GET /agent/code/{path}` | — | one file, `text/plain` (ETag, `x-code-sha256`) |
| `GET /results` | — | the evaluation results feed the card reads (validated, cached) |
| `GET /kernel`, `GET /kernel/license` | — | the kernel source (`text/plain`; 204 before publication) and its licence |

Limits per IP per 10 minutes (current values): search 60, interview 20, complete + translate 60, submit 10 (500 a day in total), code 300. Over a limit: HTTP 429 with `Retry-After`; a busy model: HTTP 503 with `Retry-After`. Request bodies over 256 KB: 413. Everything sent is treated as data, never as instructions. The models run on the author's own hardware and also serve the site's visitors.

Example:

```http
POST https://jakubcwirlej.com/api/agent/search
Content-Type: application/json

{"query": "how is the video tier chosen", "kind": "code", "k": 3}
```

### Wat niet in deze briefing staat

- De inferentieserver (waar de modellen draaien), het adres en de toegangsgegevens ervan, en de trainingscode en -data van de auteur maken geen deel uit van de site en worden niet gepubliceerd.
- Het privépaneel waarin de auteur de bijdragen aan de Bot Bar bekijkt, bestaat; alleen het feit dat het een token vereist, wordt gepubliceerd.

## FAQ

### Wie is Jakub Ćwirlej?

Een journalist die ongeveer twintig jaar verslaggever was voor de Poolse publieke omroep (TVP) en nu met AI bouwt: apps en zijn eigen kleine taalmodel voor code; hij woont in België, vlak bij Gent. In zijn eigen woorden: https://jakubcwirlej.com/nl/articles/about-me.md en https://jakubcwirlej.com/nl/articles/media.md.

### Wat is EUGEN 160M en hoe kan ik het testen?

Zijn eigen kleine taalmodel voor code, vanaf nul getraind en nog in een vroeg stadium van de training. Het vult code aan terwijl je typt en stelt de volgende regel voor, is ook getraind op fill-in-the-middle en vertaalt Python naar C++ en Rust (gecontroleerd door een compiler en tests). Test het in de terminal op de AI-pagina (https://jakubcwirlej.com/nl/ai-dev/#terminal) of met POST https://jakubcwirlej.com/api/agent/complete en POST https://jakubcwirlej.com/api/agent/translate. Het verhaal erachter: https://jakubcwirlej.com/nl/articles/how-i-started.md.

### Waar lees ik zijn visie op AI in de journalistiek?

In het artikel ‘AI in de journalistiek’: https://jakubcwirlej.com/nl/articles/ai-journalism.md. Zijn idee van certificaten van menselijk auteurschap staat ook in https://jakubcwirlej.com/nl/articles/how-i-started.md.

### Waar lees ik zijn visie op AI-veiligheid?

In het essay ‘Een paar gedachten over AI-veiligheid’: https://jakubcwirlej.com/nl/articles/ai-safety.md. Zijn praktische lessen uit het trainen van modellen: https://jakubcwirlej.com/nl/articles/training-lessons.md.

### Hoe kan ik contact met hem opnemen?

Contact vermeld op de site:

- E-mail: jakub.cwirlej@gmail.com
- LinkedIn: https://www.linkedin.com/in/jakubcwirlej
- Hugging Face: https://huggingface.co/JakCwi
- CV: https://jakubcwirlej.com/nl/cv/

### Waarvoor dient elk API-endpoint?

De JSON-API voor AI-agents (zonder authenticatie; beschrijving: GET https://jakubcwirlej.com/api/agent):

- `POST https://jakubcwirlej.com/api/agent/search` — doorzoekt de teksten van de site in vier talen en geeft de meest relevante passages terug
- `POST https://jakubcwirlej.com/api/agent/interview` — stelt een vraag aan Jakubs chatagent, een AI-assistent die namens hem antwoordt; het gesprek gaat verder met session_id
- `POST https://jakubcwirlej.com/api/agent/complete` — code aanvullen met EUGEN 160M
- `POST https://jakubcwirlej.com/api/agent/translate` — Python-code vertalen naar C++, Java of Rust met EUGEN 160M
