Know-how

Onze Lambda denkt dat 'ie een telefoon is

Versie 1.0 · Gepubliceerd 2026-08-26

Op de plek waar eerst de netwerkcall zat, staat nu een on-device PII-model

We mogen niet wachten

Wij zijn technische types die een AI-product bouwen. En we houden van regels. Dus legden we onszelf dit jaar een nieuwe regel op: niets op het kritieke pad mag wachten op een andere computer.

Eerlijk gezegd slaat dat nergens op in 2026. Elke interessante functie komt als API-call binnen, en het advies luidt overal: roep er meer aan, niet minder. Wij schreven de regel toch op.

Zoiets doen we ongeveer eens per tien jaar. Tien jaar geleden mochten we geen servers gebruiken, en daar draait UNLESS nog altijd op. Een harde regel neemt ontwerpbeslissingen voor je. Dat lukt geen enkele vergadering.

Maar deze nieuwe regel ging meteen mis. En wel op de belangrijkste stap die we hebben.

Waar de regel meteen stukliep

We bedienen gereguleerde sectoren in de Europese Unie, financiële dienstverlening bijvoorbeeld. Elke vraag die een klant aan onze Customer Agent stelt, gaat daarom eerst door een PII-filter. Namen, e-mailadressen, de rest: eruit, voordat een model de tekst ziet. Persoonsgegevens weghouden bij de modelleveranciers is bij Unless een harde eis, geen voorkeur.

Dat filter draaide op AWS Bedrock Guardrails. Managed, betrouwbaar, saai in de goede zin. Maar die dienst draait ergens anders, en dus wachten we.

Bij elke aanroep staat de functie stil. 200 tot 400 ms. Daarna pas verder met het antwoord.

“Het netwerk is traag”, denk je dan, en je kijkt er niet meer naar. Alleen stond dit vóór elke vraag, en bij een gesprek van meerdere beurten tikt dat aan. Daar namen we geen genoegen mee, dus gingen we nadenken. Sneller wachten bestaat helaas niet. Om onze eigen regel te volgen, moest het model dus naar ons toe komen.

Een on-device model tegenover een managed dienst

Gelukkig was er aan de modelkant iets veranderd terwijl wij de andere kant op keken. Telefoons en browsers vroegen om modellen die het helemaal zonder netwerk redden. Klein, quantized zodat de gewichten in lagere precisie worden opgeslagen, native, gebouwd voor andermans hardware.

Dat werk is bedoeld voor een apparaat met een batterij, een trage chip en geen geduld. Niet voor een cloudfunctie. Al zijn de verschillen klein, bedachten we. Een AWS Lambda-functie lijkt op zo’n apparaat, op het scherm na. Kleine computer, alleen, kort van leven, niemand in de buurt om te bellen. Dat klinkt als een prima plek voor een on-device model.

Leuk bedacht, bewijst niets. Dus zetten we zo’n telefoonmodel tegenover de managed dienst waar we al voor betaalden. En raad eens? Het vond er meer. Het kostte minder. En het reist als één layer mee naar elke functie.

Wat we geïnstalleerd hebben

Het model heet @desert-ant-labs/redact, versie 3.0.0. Redact herkent 17 labels die er voor de AVG toe doen. Verder helemaal niets.

Eronder zit een voorgebouwde native kern op LiteRT, de on-device runtime van Google. Node praat ermee via koffi FFI. De modelgewichten zitten niet in het npm-pakket, dus we zetten bij de build een versie vast.

Die bestanden en de native kern gaan samen in één Lambda layer, gebouwd met CDK, 47 MB gepubliceerd. Elke functie die filtert, hangt diezelfde layer eronder. Eén artefact om te onderhouden, geen kopie per functie.

Het geheel gedraagt zich als een geïnstalleerde app. Vaste versie, staat op schijf, start mee met de functie. Verder geen verkeer naar buiten.

We rekenden op verlies

Een zelfopgelegde regel kost meestal iets. We gingen er dus van uit dat een model dat in een layer van 47 MB past het zou afleggen tegen een managed dienst van AWS. We wilden weten hoe groot dat verlies was voordat we ons eraan bonden. Of misschien konden we het model als extra controle gebruiken.

Dus schreven we 102 vragen, geformuleerd zoals mensen ze echt aan de agent stellen, met Europa als context. Alle persoonsgegevens in de set zijn verzonnen. Er is niets van echte mensen gebruikt.

Daarna probeerden we allebei de detectoren te laten struikelen. Naast de vragen met echte PII zetten we valstrikken: ordernummers, SKU’s, datums, prijzen, namen van beursgenoteerde bedrijven. Dat lijkt op persoonsgegevens, daar grijpt een gretige detector naar, en daar gaat je resultaat. Haal een ordernummer uit een vraag en de agent beantwoordt een verminkte versie. De klant krijgt een slechter antwoord en niemand ziet ooit waarom.

Nog één ding over de telling, want dat bepaalt wat de cijfers betekenen. We scoorden per vraag: kwam die er goed geclassificeerd uit, PII of schoon? In productie ligt de lat hoger, want daar wordt elk gegeven in een vraag apart gemaskeerd. Lees deze cijfers dus als detectiecijfers.

De prijs viel de andere kant op

Over de 102 vragen maakte het lokale model nul fouten. Nul. Guardrails maakte er acht. 92% tegen 100% zegt weinig. Die acht zijn twee verschillende fouten, en ze gaan de andere kant op.

De PII die erdoorheen glipte

57 van de 102 vragen bevatten PII. Hier telt een misser het zwaarst, want dan liggen persoonsgegevens bij de modelleverancier, meestal een externe cloudpartij in Europa. Precies dat moet het filter voorkomen. Wij houden niet van losse eindjes. Onze klanten ook niet.

Guardrails vond er 53 en miste er 4. Vangstpercentage 93,0%. Redact vond ze alle 57. Op onze set: vier lekken tegen nul.

De schone vragen die sneuvelden

De andere 45 vragen waren schoon, valstrikken incluis. Een valse treffer kost geen compliance maar kwaliteit. De agent beantwoordt dan een doorgestreepte versie van een prima vraag.

Guardrails markeerde er 4 van de 45. Fout-positief: 8,9%. Redact markeerde er nul, en wint dus op allebei de fouten tegelijk.

Resultaat op 102 vragenAWS Bedrock GuardrailsRedact 3.0.0 (lokaal, 17 labels)
Goed94/102 (92,2%)102/102 (100,0%)
PII gevonden5357
PII gemist40
Schoon, terecht niet gemarkeerd4145
Schoon, onterecht gemarkeerd40

Voordat het enthousiasme te groot wordt: we zetten een specialist tegenover een generalist. Guardrails is breed en voorzichtig afgesteld, voor van alles. Redact doet één ding. Dat de specialist wint is geen nieuws. Hoeveel, en tegen welke kosten, wel.

Nog twee dingen, voor de eerlijkheid. De AWS-kolom is onze echte productieconfiguratie, geen stropop. En 100% betekent: nul fouten, 102 verzonnen vragen, één run. Sterk op deze set. Geen voorspelling voor productie.

Vergeet niet: wachten betaal je twee keer

De nauwkeurigheid gaf de doorslag. Snelheid en kosten waren de bonus. De managed call kostte 200 tot 400 ms per vraag. Het lokale model doet er warm 30 tot 50 over.

Die twee meet je niet hetzelfde. In de eerste zit de rit naar Bedrock. De tweede is inference in een functie die al draait, zonder de eenmalige laadtijd bij een koude start.

Dan het tarief. Guardrails kost $ 0,10 per 1.000 tekstunits, en een tekstunit is 1.000 tekens. Onze vragen zijn kort, dus reken op één unit per vraag. Tien dollarcent per duizend.

Zo lees je de wissel verkeerd: een tarief van tien cent deels eraf, 30 tot 50 ms rekenwerk erbij. Dan mis je de helft. Je on-device model is natuurlijk ook niet gratis, maar host je het zelf, dan kost het waarschijnlijk maar een fractie. Daar gaat het ons alleen niet om.

Want de call werd afgewacht. De functie stond geblokkeerd, zonder iets anders te doen. Lambda rekent af op tijd, en stilstaan kost precies zoveel als werken. We betaalden Amazon om in de wacht te staan.

De wissel snijdt dus twee keer. Het API-tarief is weg. En 200 tot 400 ms betaald wachten werd 30 tot 50 ms betaald werk. Scheelt 150 tot 370 ms gefactureerde duur per vraag.

Eén eerlijke tegenpost. Het model en de runtime hadden ruimte nodig, dus ging de functie van 1.024 MB naar 1.536 MB. Meer geheugen maakt elke milliseconde duurder, van de hele aanroep, niet alleen van het filter.

Maak die som dus zelf: (nieuw geheugen × nieuwe duur) − (oud geheugen × oude duur). Bij ons valt die duidelijk uit naar het lokale model. Bij jou misschien niet.

Wat de regel ons kostte

Gratis is het niet. De rekening komt bij koude starts. Een koude container laadt het model één keer voor de eerste inference: 240 tot 330 ms extra.

We maten 2% koude starts. Elke warme aanroep daarna zit op die 30 tot 50 ms. Voor deze workload werd het nooit een probleem.

Bij grillig verkeer klopt die som niet meer. Meet de laadtijd op je eigen configuratie voordat je iemands snelheidscijfers gelooft. Die van ons ook.

Wat de regel niet oplevert

De regel leverde snelheid op, en geld. Onze plek in de verwerkingsketen veranderde er niet door. Dat onderscheid houden we scherp.

Een PII-detector leest ruwe invoer. Anders vindt die geen persoonsgegevens. Daarmee blijft het een vermelde subverwerker. Of een derde partij die stap draait of wij zelf, dat maakt niet uit. Waar de stap staat, verandert niets aan wat die kan zien.

Wat het filter wél doet, is smaller en controleerbaar. Herleidbare identifiers blijven weg bij het model van derden dat het antwoord schrijft. Dat model krijgt velden die in tokens zijn omgezet en die niet terug te rekenen zijn. Daar steunt onze Privacy Vault op, voor en na deze wissel.

Filteren is een inspanningsverplichting op herkenbare identifiers. Anonimiseren is het niet. Die vier missers in de tabel laten precies zien waarom dat verschil telt. We schreven eerder over PII-filtering onder de AVG en over de veiligheidsgrens rond een Customer Agent.

Kies zelf een regel waar je niet omheen kunt

Een harde regel kiezen en kijken hoe ver we kwamen, bracht ons bij deze nieuwe klasse micromodellen. Alles wat in een mobiele app kan draaien, past prima in een Lambda.

En de lijst met klussen die zo’n klein lokaal model kan overnemen wordt langer. De rest hebben we niet getest, dus lees dit als richting en niet als resultaat. Een interactie samenvatten. Er een titel bij verzinnen. Een vraag in een onderwerp indelen. Alle drie zijn ze vandaag een await. En alle drie klein en afgebakend genoeg voor een specialist ter plekke.

Kijk dus eens naar de awaits op je eigen kritieke pad. Meet wat dat wachten je nu al kost. Vraag je dan af of iets wat voor een broekzak gebouwd is, dat werk in jouw functie kan doen.

Ons PII-filter heeft nooit een telefoon gezien. Het had alleen een kleine computer met een kort leven nodig, en dat is precies wat een Lambda is.

EU AI Act: de deadline van 2 aug...